Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Странное поведение ATtiny26
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
SAVC
Пытаюсь сделать управляемый источник питания, источник тока с регулировкой на МК 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
Уточните, какие напряжения:
1. Питания контроллера
2. Переменного резистора, которым регулируете PWM
3. При каком напряжении на выходе резистора PWM сбрасывается в 0? Интересно узнать именно напряжение, а не просто какая часть шкалы.
SAVC
Цитата(controller_m30 @ Sep 15 2018, 19:22) *
Уточните, какие напряжения:
1. Питания контроллера
2. Переменного резистора, которым регулируете PWM
3. При каком напряжении на выходе резистора PWM сбрасывается в 0? Интересно узнать именно напряжение, а не просто какая часть шкалы.

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

Импульсы на выходе стали в два раза уже. При достижении напряжения на входе уровня 4.33В рост ширины импульсов останавливается, происходит насыщение.
controller_m30
Два предложения.
1. Проверьте питание на ноге AVCC - равно ли питанию VCC контроллера? Попробуйте добавить конденсатор на эту ногу 0.1uF, и индуктивность 10uH (как в даташите на стр.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
Чтение измерений АЦП в коде вообще отсутствуют, ибо осуществляются они исключительно командой "in r16,adcl".
Ее надо поставить перед "in r16,adch".
domowoj
SAVC
-зачем вы залезли своей программой на адреса векторов прерываний
-какая необходимость использовать PLL
-грамотней было бы использовать в АЦП внутренний ИОН, подключенный на выход МК, и к нему же подключить ваши переменные резисторы
-при работе с АЦП удобней использовать прерывания с настройкой режима сна,
запускаете АЦП и засыпаете и по окончании преобразования процессор просыпается по прерыванию и ADIF не надо сбрасывать. Программа становится короче.
SAVC
Цитата(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
Цитата(SAVC @ Sep 16 2018, 06:01) *
Я использую режим сдвигания результата преобразования в старший регистр. Бит 5 в регистре ADMUX, ADLAR.


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

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

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

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

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

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

Сейчас восстановил схему, переменный резистор был подключен к первому каналу АЦП, CH1
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2024 Invision Power Services, Inc.