Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум разработчиков электроники ELECTRONIX.ru _ AVR _ Странное поведение ATtiny26

Автор: SAVC Sep 15 2018, 13:46

Пытаюсь сделать управляемый источник питания, источник тока с регулировкой на МК AVR ATtiny26(L)
В целях ознакомления с периферией, сделал такой вот проект:

CODE
.include "avr000/tn26def.inc"

.cseg
.org 0

start:
ldi r16,RAMEND
out sp,r16
ldi r16,0b00001111
out ddrb,r16
ldi r16,2
out pllcsr,r16
start_01:
in r16,pllcsr
andi r16,1
breq start_01
ldi r16,6
out pllcsr,r16
ldi r16,0
out ocr1a,r16
out ocr1b,r16
ldi r16,255
out ocr1c,r16
ldi r16,0b01010011
out tccr1a,r16
ldi r16,0b10000011
out tccr1b,r16

;CK/8
ldi r16,0b00000010
out tccr0,r16
ldi r16,128
out tcnt0,r16

rcall pause

forever:

;Ждём ADIF=1
;ADLAR = 1 сдвигать результат влево, 8 бит в регистре ADCH
ldi r16,0b00100000
out admux,r16

;ADEN = 1
;ADSC = 1
;ADPS = 001; division by 2
ldi r16,0b11000001
out adcsr,r16

start_02:
in r16,adcsr
andi r16,16
breq start_02

;Сбросим ADIF
ldi r16,0b10010001
out adcsr,r16

in r16,adch

out ocr1a,r16

rcall pause

;ADLAR = 1 сдвигать результат влево, 8 бит в регистре ADCH
ldi r16,0b00100001
out admux,r16

;ADEN = 1
;ADSC = 1
;ADPS = 001; division by 2
ldi r16,0b11000001
out adcsr,r16

;Ждём ADIF=1
start_03:
in r16,adcsr
andi r16,16
breq start_03

;Сбросим ADIF
ldi r16,0b10010001
out adcsr,r16

in r16,adch

mov r17,r16
andi r17,128
out porta,r17

out ocr1b,r16

rcall pause

rjmp forever

pause:

;Ждём TOV0
pause_01:
in r16,tifr
andi r16,2
breq pause_01

;Clear TOV0
ldi r16,2
out tifr,r16

ldi r16,128
out tcnt0,r16

ret

Запускается периферия, затем в цикле измеряется напряжение с нулевого входа АЦП, выводится в первый канал PWM,
после этого измеряется напряжение на первом входе АЦП, выводится во второй канал PWM.
Светодиод на PA7 отображает состояние старшего бита данных с АЦП для второго канала.
Имеем странный результат: вращая ручку переменного резистора, подключенного делителем к первому входу АЦП
длительность импульса выходного сигнала сначала плавно увеличивается, потом доходит до максимума и затем резко обрывается, падая в ноль.
Это происходит где-то после 75% шкалы.
Светодиод при этом светится, то есть это не АЦП.
Далее, проверяем PWM.
С этой целью запускаем след. код на микроконтроллере:
CODE
.include "avr000/tn26def.inc"

.cseg
.org 0

start:
ldi r16,RAMEND
out sp,r16
ldi r16,0b00001111
out ddrb,r16
ldi r16,2
out pllcsr,r16
start_01:
in r16,pllcsr
andi r16,1
breq start_01
ldi r16,6
out pllcsr,r16
ldi r16,254
out ocr1a,r16
out ocr1b,r16
ldi r16,255
out ocr1c,r16
ldi r16,0b01010011
out tccr1a,r16
ldi r16,0b10000011
out tccr1b,r16

forever:
rjmp forever

Код инициализирует периферию и запускает таймер-счётчик с коэффициентом 254 на обоих каналах PWM
Код работает.
Не могу понят, что происходит в системе, если у кого-нибудь есть опыт или идеи, прошу поделиться.

Автор: controller_m30 Sep 15 2018, 14:22

Уточните, какие напряжения:
1. Питания контроллера
2. Переменного резистора, которым регулируете PWM
3. При каком напряжении на выходе резистора PWM сбрасывается в 0? Интересно узнать именно напряжение, а не просто какая часть шкалы.

Автор: SAVC Sep 15 2018, 14:24

Цитата(controller_m30 @ Sep 15 2018, 19:22) *
Уточните, какие напряжения:
1. Питания контроллера
2. Переменного резистора, которым регулируете PWM
3. При каком напряжении на выходе резистора PWM сбрасывается в 0? Интересно узнать именно напряжение, а не просто какая часть шкалы.

Напряжение питания 5.20В
Напряжение, при котором сигнал сбрасывается в ноль 4.33В

Автор: controller_m30 Sep 15 2018, 14:41

Попробуйте значения, считанные из АЦП, сначала поделить на 2 (команда LSR Rx), а потом загружать в PWM. Что получится?

Автор: SAVC Sep 15 2018, 14:46

Цитата(controller_m30 @ Sep 15 2018, 19:41) *
Попробуйте значения, считанные из АЦП, сначала поделить на 2 (команда LSR Rx), а потом загружать в PWM. Что получится?

Импульсы на выходе стали в два раза уже. При достижении напряжения на входе уровня 4.33В рост ширины импульсов останавливается, происходит насыщение.

Автор: controller_m30 Sep 15 2018, 15:30

Два предложения.
1. Проверьте питание на ноге AVCC - равно ли питанию VCC контроллера? Попробуйте добавить конденсатор на эту ногу 0.1uF, и индуктивность 10uH (как в http://electronix.ru/redirect.php?http://www.superrobotica.com/download/S310330/attiny26-complete.pdf на стр.106).

2. Если предыдущее не поможет. И если нет возможности быстро подключить дисплей, чтобы посмотреть регистры ADC и PWM.
Добавьте на выход PWM схемку как на картинке (я пользуюсь номиналами из нижней схемы, но и номиналы верхней схемы тоже рабочие).
Это для того, чтобы значения PWM смотреть в виде напряжения мультиметром напрямую. При VCC=5 вольт, и PWM=255 - на выходе цепочки будет 5 вольт. При PWM=128 - на выходе будет 2.5 вольт (пол питания), а при PWM=0 - на выходе 0 вольт. Т.е. получится такой себе DAC.
Дальше попробуем измерить значение внутреннего источника 1.18v, и вывести на выход PWM - посмотрим сколько покажет.
Потом тоже самое, но с опорным напряжением ADC=2.56v. Сколько покажет?

 

Автор: aiwa Sep 15 2018, 15:34

Чтение измерений АЦП в коде вообще отсутствуют, ибо осуществляются они исключительно командой "in r16,adcl".
Ее надо поставить перед "in r16,adch".

Автор: domowoj Sep 16 2018, 01:00

SAVC
-зачем вы залезли своей программой на адреса векторов прерываний
-какая необходимость использовать PLL
-грамотней было бы использовать в АЦП внутренний ИОН, подключенный на выход МК, и к нему же подключить ваши переменные резисторы
-при работе с АЦП удобней использовать прерывания с настройкой режима сна,
запускаете АЦП и засыпаете и по окончании преобразования процессор просыпается по прерыванию и ADIF не надо сбрасывать. Программа становится короче.

Автор: SAVC Sep 16 2018, 03:01

Цитата(controller_m30 @ Sep 15 2018, 20:30) *
Два предложения.
1. Проверьте питание на ноге AVCC - равно ли питанию VCC контроллера?

Ну вот оно!
Я забыл подключить AVCC!
Эпитеты о тупизне автора...
Благодарю, всё заработало.

Цитата(aiwa @ Sep 15 2018, 20:34) *
Чтение измерений АЦП в коде вообще отсутствуют, ибо осуществляются они исключительно командой "in r16,adcl".
Ее надо поставить перед "in r16,adch".

Я использую режим сдвигания результата преобразования в старший регистр. Бит 5 в регистре ADMUX, ADLAR.

Цитата(domowoj @ Sep 16 2018, 06:00) *
SAVC
-зачем вы залезли своей программой на адреса векторов прерываний

А у меня прерывания отключены, могу залезать, куда душе угодно.

Цитата
-какая необходимость использовать PLL

Режим работы нравится.

Цитата
-грамотней было бы использовать в АЦП внутренний ИОН, подключенный на выход МК, и к нему же подключить ваши переменные резисторы

Спорный вопрос. У меня изменение сигнала в схеме от 0 до 5В.

Цитата
-при работе с АЦП удобней использовать прерывания с настройкой режима сна,
запускаете АЦП и засыпаете и по окончании преобразования процессор просыпается по прерыванию и ADIF не надо сбрасывать. Программа становится короче.

Не удобней. И вообще, о вкусах не спорят.
Мелкие придирки. По существу ничего не сказано.

Остался только вопрос, почему горел светодиод, указывающий старший бит АЦП. Ведь, если АЦП выдавало ноль, светодиод должен был гаснуть...

Автор: aiwa Sep 16 2018, 07:54

Цитата(SAVC @ Sep 16 2018, 06:01) *
Я использую режим сдвигания результата преобразования в старший регистр. Бит 5 в регистре ADMUX, ADLAR.


В даташите при описании ADLAR "Otherwise, ADCL must be read first, then ADCH."


Автор: SAVC Sep 16 2018, 07:57

Цитата(aiwa @ Sep 16 2018, 12:54) *
В даташите при описании ADLAR "Otherwise, ADCL must be read first, then ADCH."

Это написано для случая, когда ADLAR=0.

Автор: controller_m30 Sep 16 2018, 16:20

Цитата(SAVC @ Sep 16 2018, 06:01) *
Остался только вопрос, почему горел светодиод, указывающий старший бит АЦП. Ведь, если АЦП выдавало ноль, светодиод должен был гаснуть...

В тексте программы не видно команды инициализации порта A на вывод (а светодиод подключен к PA7, как я понял). Т.е. PA7 работал как вход.
Поэтому, точно сказать отчего горел светодиод, трудно. Может от Pull-Up резистора входной линии. Или, из-за отсутствия питания на AVCC, что-то "глючило" на портах ввода-вывода.
А если светодиод подключен анодом к VCC а катодом к порту, то при переводе порта на ввод, светодиод тоже может светиться в пол-яркости.

Автор: SAVC Sep 17 2018, 15:16

Цитата(controller_m30 @ Sep 16 2018, 21:20) *
В тексте программы не видно команды инициализации порта A на вывод (а светодиод подключен к PA7, как я понял). Т.е. PA7 работал как вход.
Поэтому, точно сказать отчего горел светодиод, трудно. Может от Pull-Up резистора входной линии. Или, из-за отсутствия питания на AVCC, что-то "глючило" на портах ввода-вывода.
А если светодиод подключен анодом к VCC а катодом к порту, то при переводе порта на ввод, светодиод тоже может светиться в пол-яркости.

Светодиод подключен анодом к порту ввод-вывода, катодом через резистор 2к2 на общий провод.
Светодиод светился очень слабо, я ещё подумал, что, наверное, резистор не на 2к2, а на 22к :-)
Видимо, ток шёл через подтягивающий резистор, который подключается, если в porta будет единица, а в ddra - 0
Действительно, я забыл проинициализировать порт А
Но вот ведь незадача, сигнал сбрасывался в ноль, а светодиод продолжал гореть.
Светодиод чётко делил шкалу на пополам. В нижней части гас, в верхней части - светился.
Объяснить я этого не могу.

Автор: controller_m30 Sep 17 2018, 15:55

Ещё вариант такой.
По тексту программы, на светодиод выводится значение старшего бита 1-го канала АЦП. А из пояснений в первом посте следует, что переменный резистор подключен к каналу 0 АЦП, а канал 1, видимо, "висит" в воздухе.
И возможно на этом 1-м канале, в неподключенном состоянии, напряжение больше пол-питания, и потому старший бит (и светодиод) всегда равны 1.

Автор: SAVC Sep 18 2018, 09:27

Цитата(controller_m30 @ Sep 17 2018, 20:55) *
Ещё вариант такой.
По тексту программы, на светодиод выводится значение старшего бита 1-го канала АЦП. А из пояснений в первом посте следует, что переменный резистор подключен к каналу 0 АЦП, а канал 1, видимо, "висит" в воздухе.
И возможно на этом 1-м канале, в неподключенном состоянии, напряжение больше пол-питания, и потому старший бит (и светодиод) всегда равны 1.

Нет, светодиод отображает состояние того канала АЦП, к которому подключен переменный резистор. К сожалению, уже не помню, к какому именно. Светодиод гас в нижней части шкалы и загорался в верхней части.

Сейчас восстановил схему, переменный резистор был подключен к первому каналу АЦП, CH1

Русская версия Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)