Перейти к содержанию

    

Странное поведение ATtiny26

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

В целях ознакомления с периферией, сделал такой вот проект:

	.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.

С этой целью запускаем след. код на микроконтроллере:

	.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

Код работает.

Не могу понят, что происходит в системе, если у кого-нибудь есть опыт или идеи, прошу поделиться.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уточните, какие напряжения:

1. Питания контроллера

2. Переменного резистора, которым регулируете PWM

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Уточните, какие напряжения:

1. Питания контроллера

2. Переменного резистора, которым регулируете PWM

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

Напряжение питания 5.20В

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Два предложения.

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. Сколько покажет?

post-45309-1537024991_thumb.png

Изменено пользователем controller_m30

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Ее надо поставить перед "in r16,adch".

Изменено пользователем aiwa

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SAVC

-зачем вы залезли своей программой на адреса векторов прерываний

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

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

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

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Два предложения.

1. Проверьте питание на ноге AVCC - равно ли питанию VCC контроллера?

Ну вот оно!

Я забыл подключить AVCC!

Эпитеты о тупизне автора...

Благодарю, всё заработало.

 

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

Ее надо поставить перед "in r16,adch".

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

 

SAVC

-зачем вы залезли своей программой на адреса векторов прерываний

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

 

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

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

 

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

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

 

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

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

Не удобней. И вообще, о вкусах не спорят.

Мелкие придирки. По существу ничего не сказано.

 

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

Изменено пользователем SAVC

Поделиться сообщением


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

 

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

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В даташите при описании ADLAR "Otherwise, ADCL must be read first, then ADCH."

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

Поделиться сообщением


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

В тексте программы не видно команды инициализации порта A на вывод (а светодиод подключен к PA7, как я понял). Т.е. PA7 работал как вход.

Поэтому, точно сказать отчего горел светодиод, трудно. Может от Pull-Up резистора входной линии. Или, из-за отсутствия питания на AVCC, что-то "глючило" на портах ввода-вывода.

А если светодиод подключен анодом к VCC а катодом к порту, то при переводе порта на ввод, светодиод тоже может светиться в пол-яркости.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
В тексте программы не видно команды инициализации порта A на вывод (а светодиод подключен к PA7, как я понял). Т.е. PA7 работал как вход.

Поэтому, точно сказать отчего горел светодиод, трудно. Может от Pull-Up резистора входной линии. Или, из-за отсутствия питания на AVCC, что-то "глючило" на портах ввода-вывода.

А если светодиод подключен анодом к VCC а катодом к порту, то при переводе порта на ввод, светодиод тоже может светиться в пол-яркости.

Светодиод подключен анодом к порту ввод-вывода, катодом через резистор 2к2 на общий провод.

Светодиод светился очень слабо, я ещё подумал, что, наверное, резистор не на 2к2, а на 22к :-)

Видимо, ток шёл через подтягивающий резистор, который подключается, если в porta будет единица, а в ddra - 0

Действительно, я забыл проинициализировать порт А

Но вот ведь незадача, сигнал сбрасывался в ноль, а светодиод продолжал гореть.

Светодиод чётко делил шкалу на пополам. В нижней части гас, в верхней части - светился.

Объяснить я этого не могу.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ещё вариант такой.

По тексту программы, на светодиод выводится значение старшего бита 1-го канала АЦП. А из пояснений в первом посте следует, что переменный резистор подключен к каналу 0 АЦП, а канал 1, видимо, "висит" в воздухе.

И возможно на этом 1-м канале, в неподключенном состоянии, напряжение больше пол-питания, и потому старший бит (и светодиод) всегда равны 1.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты
Ещё вариант такой.

По тексту программы, на светодиод выводится значение старшего бита 1-го канала АЦП. А из пояснений в первом посте следует, что переменный резистор подключен к каналу 0 АЦП, а канал 1, видимо, "висит" в воздухе.

И возможно на этом 1-м канале, в неподключенном состоянии, напряжение больше пол-питания, и потому старший бит (и светодиод) всегда равны 1.

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

 

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

Изменено пользователем SAVC

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти