Темболее когда стоит выравнивание по старшей стороне и используется только 8 бит.
Ассемблер (ASM) для AVR в вопросах и ответах
С АЦП такой проблемы нет, произвольно читай регистры. Он не меняется каждый такт и поэтому нет проблемы синхронного чтения двух байт. Пожалуй, с АЦП надо специально расставить и зарядить грабли чтобы прочитать старший байт от одной выборки а младший от другой.
Темболее когда стоит выравнивание по старшей стороне и используется только 8 бит.
Темболее когда стоит выравнивание по старшей стороне и используется только 8 бит.
- Реклама
вот "прямо за стенкой" такие грабли выстрелили 
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Просто оставлю это тут...

- Вложения
-
- ADC_READ.png
- (13 КБ) 624 скачивания
Неправильно собранная из неисправных деталей схема нуждается в отладке и сразу не работает... (С)
т.е. ADCL без ADCH читать нельзя, а наоборот можно, понятно. (я всегда старался читать всё, так, на всякий случай)
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Кстати, если речь идёт об avr-gcc, если нужна вся 10-битная точность, то есть ещё способ - читать сразу ADCW в 16-битную переменную.
Если же 8 бит достаточно, то да, проще всего читать ADCH, с установленным выравниванием результата влево.
Если же 8 бит достаточно, то да, проще всего читать ADCH, с установленным выравниванием результата влево.
Код: Выделить всё
/* ADC */
#define ADCW _SFR_IO16(0x04)
#define ADCL _SFR_IO8(0x04)
#define ADCH _SFR_IO8(0x05)- Реклама
- Сообщения: 516
- Зарегистрирован: Пт янв 18, 2013 15:11:02
Подскажите кому не трудно что не так на схеме в протеусе, так как двигаю ползунок переменного резистора и нечего не происходит.
В начальный момент времени Шим сигнал выставляется по умолчанию его скважность, А потом изменения скважности постоянны и на ползунок не реагируют?
В начальный момент времени Шим сигнал выставляется по умолчанию его скважность, А потом изменения скважности постоянны и на ползунок не реагируют?
Спойлер
Код: Выделить всё
.include "tn13Adef.inc"; Header files
.list; // Отоброжения листинга исполнения команды.
.cseg; работаем с програмной памятью а не озу или eeprom
.org 0; устанавливаем начальную позицию строки
rjmp START; Reset Handler
rjmp START; IRQ0 Handler
rjmp START;; PCINT0Z Handler
rjmp START3; Timer0 Overflow Handler
rjmp START; EEPROM Ready Handler
rjmp START; Analog Comparator Handler
rjmp START; TIM0_COMPA CompareA Handler
rjmp START; Timer0 CompareB Handler
rjmp START; Watchdog Interrupt Handler
rjmp start3; ADC Conversion Handler
start3:
CLV;
//Считываем данные АЦП
in R16, ADCL;
//Записываем считанные данные в регистр.
out OCR0A, R16;
reti;
START:
// команда запрещает глобальные прерывания.
CLI;
//инициализация стэка.(установка максимально размера ОЗУ);
ldi R17, RAMEND;
out SPL, R17;
//Выбираем коэфициент пределителя тактовой частоты АЦП при расчете что частота 9,6/8=1,2 Мгц; 1200/8=150; где 8 выбранный коэфициент
//Запрещаем прерывание от компоратора ADIE
LDI R16,(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(0<<ADIE);
out ADCSRA, R16;
//Включаем аналогово-цифровой преобразователь
SBI ADCSRA, ADEN;
//Режим работы выставляем непрерывное преобразования
SBI ADCSRA, ADATE;
LDI R16,(0<<ADTS2)|(0<<ADTS1)|(0<<ADTS0);
out ADCSRB, R16;
//Выбираем ножку мк которая будет производить измерения ADC1
LDI R16, (0<<MUX1)|(1<<MUX0);
out ADMUX, R16;
//Делаем выравнивания по левому краю для считывания ADCH.
SBI ADMUX, ADLAR;
//Выбираем напряжение питание микроконтролера, ставим питания от ИОН.
SBI ADMUX, REFS0;
//Запуск преобразования
SBI ADCSRA, ADSC;
//Оставляем работу ножки МК как на вход для измерения сигнала
CBI DDRB, DDB0;
CBI PORTB, PB0;
//Подключаем таймер в режиме FAST PWM - шИМ сигнала с установленным верхним значением OCR0A
LDI R16, (1<<WGM01)|(1<<WGM00)|(1<<COM0A1)|(0<<COM0A0);
OUT TCCR0A,R16;
//Определяем состояение выводов OCOA - не инвертирующий шим как на выход.
SBI DDRB, DDB0;
SBI PORTB, PB0;
/*Скорость работы таймера выбираем СК/1024 - где СК - частота работы микроконтролера
в нашем случаи мы выставляем во fuces clkdiv8 что обеспечит нам частоту 9,6Мhz/8=1,2Mhz значит
скорость работы таймера будет 1,2Mhz/1024=1,17Khz что увеличивает счет значения. Чем меньше
частота тем большее время срабатывания прерывания*/
ldi R16, (1<<CS02)|(0<<CS01)|(1<<CS00)|(0<<WGM02);
out TCCR0B, R16;
//Прерывания от переполнения таймера
ldi R16, (1<<TOIE0);
out TIMSK0, R16;
//Скважность шим сигнала.
ldi R16, 0x50;
out OCR0A, R16;
sei;
rjmp START1;
START1:
nop;
rjmp START1;
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3284651#p3284651"]...ну если не взлетит - знаешь куда копать.[/uquote] (подсказка) пятью постами выше ссылка за стенку со стреляющими граблями
это твой случай
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 516
- Зарегистрирован: Пт янв 18, 2013 15:11:02
Спасибо ошибку устранил:
start3:
CLV;
//Считываем данные АЦП
in R17, ADCL;
in R16, ADCH;
//Записываем считанные данные в регистр.
out OCR0A, R16;
reti;
Но нечего не поменялось протеус также выдает не изменяемые по скважности импульсы. В чем может быть еще причина.
start3:
CLV;
//Считываем данные АЦП
in R17, ADCL;
in R16, ADCH;
//Записываем считанные данные в регистр.
out OCR0A, R16;
reti;
Но нечего не поменялось протеус также выдает не изменяемые по скважности импульсы. В чем может быть еще причина.
- Сообщения: 615
- Зарегистрирован: Вс дек 28, 2014 21:54:05
start3 выполняется и при ADC complete и при Timer0 overflow.
В overflow попробуйте снова запустить конверсию. Не углублялся в режимы таймера, нзн.(времени сейчас нет)
В overflow попробуйте снова запустить конверсию. Не углублялся в режимы таймера, нзн.(времени сейчас нет)
Я всё-всё узнAю и стану профессором.
По идее конверсию надо запускать по прерыванию окончания конверсии и всё (ну и один раз при старте, чтоб закрутилось) а в прерывании от таймера я не знаю что нужно делать (в смысле можно ничего не делать и вообще это прерывание запретить).
тогда в прерывании завершения конверсии будет:
1) получение данных преобразования,
2) запись их в регистр сравнения таймера и
3) запуск нового АД преобразования.
(изменение регистра сравнения и вызывает изменение уровня ШИМ)
тогда в прерывании завершения конверсии будет:
1) получение данных преобразования,
2) запись их в регистр сравнения таймера и
3) запуск нового АД преобразования.
(изменение регистра сравнения и вызывает изменение уровня ШИМ)
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
- Сообщения: 615
- Зарегистрирован: Вс дек 28, 2014 21:54:05
Точно, сморозил я, пардон
Я всё-всё узнAю и стану профессором.
- Сообщения: 516
- Зарегистрирован: Пт янв 18, 2013 15:11:02
Добавлено after 1 minute 4 seconds:
Я вот так вот сделал и все заработало
start3:
CLV;
//Считываем данные АЦП
in R17, ADCL; //ADCH - записываем, ADCL - можно не записывать
in R16, ADCH;
//Записываем считанные данные в регистр.
out OCR0A, R16;
SBI ADCSRA, ADSC;//Запуск преобразования
reti;
Получается что запуск преобразования нужно запускать каждый раз когда считываем данные с ADCH?
Я то думал что при выбора режима - непрерывное преобразования, этого делать не надо.
Я вот так вот сделал и все заработало
start3:
CLV;
//Считываем данные АЦП
in R17, ADCL; //ADCH - записываем, ADCL - можно не записывать
in R16, ADCH;
//Записываем считанные данные в регистр.
out OCR0A, R16;
SBI ADCSRA, ADSC;//Запуск преобразования
reti;
Получается что запуск преобразования нужно запускать каждый раз когда считываем данные с ADCH?
Я то думал что при выбора режима - непрерывное преобразования, этого делать не надо.
- Сообщения: 615
- Зарегистрирован: Вс дек 28, 2014 21:54:05
С Мегой8 у меня тоже не получилось, запускаю преобразование каждый раз. Не пробовал, может надо было по человечески прочитать ADC, по ДШ?
Я всё-всё узнAю и стану профессором.
- Сообщения: 516
- Зарегистрирован: Пт янв 18, 2013 15:11:02
Всем спасибо за уделенное время и помощь. Буду пробовать дальше.
strengerst писал(а):Получается что запуск преобразования нужно запускать каждый раз когда считываем данные с ADCH?
Я то думал что при выбора режима - непрерывное преобразования, этого делать не надо.
Сбрасывайте флаг ADIF и все само зажжжжужит. А лучше чтобы сбрасывало прерывание от АЦП автоматом.A conversion will be triggered by the
rising edge of the selected Interrupt Flag... ...Switching to Free Running mode (ADTS[2:0]=0) will not cause a trigger event, even if the ADC
Interrupt Flag is set.
Спойлер

Вроде там не должно быть каких-то нюансов.dgrett писал(а):С Мегой8 у меня тоже не получилось, запускаю преобразование каждый раз.
Здравствуйте!
Недавно начал заниматься программированием AVR, сейчас тренируюсь на tiny2313 на простых задачах (светодиоды, кнопки, энкодер, UART).
Написал простейшую программку, которая по внешним прерываниям опрашивает энкодер, инкрементирует/декрементирует значение в регистре и сразу отправляет по UART. Общий вывод энкодера на земле, каналы энкодера подключены ко входам для внешних прерываний INT0, INT1, включены внутренние подтягивающие резисторы. Использую лишь одно из этих прерываний.
Алгоритм простой:
1) Настраиваю прерывание по срезу импульса на INT0
2) Соответственно, когда возникло прерывание, точно известно, что первый канал энкодера переключился из 1 в 0.
3) Проверяю состояние второго канала, который подключен на PD3.
4) Если энкодер вращается в одну сторону (например, по ч.с.), то там будет 1, делаю инкремент регистра Steps.
5) Если энкодер вращается в другую сторону (против ч.с.), то там будет 0, делаю декремент регистра Steps.
5) Посылка Steps по UART.
6) Выход из прерывания.
В основном цикле ничего нет, только "заглушка" rjmp pc.
Проблема в том, что независимо от направления вращения энкодера получается только инкремент (или только декремент, если переход не по sbis, а по sbic). Как будто второй канал энкодера постоянно находится в 1.
Самые очевидные причины проверил:
1) Энкодер исправен, проверял подключением к нему светодиодов и медленным вращением.
2) Каналы энкодера подключены именно к ножкам PD2 (INT0), PD3 (INT1)
3) Эти ножки порта настроены на ввод, подтяжки включены.
4) Прерывание по INT0 разрешено, по INT1 запрещено.
5) Неисправен вход PD3? Пробовал подключать второй канал энкодера на PA0 - результат такой же.
PUSHF, POPF - макросы для сохранения SREG в стек и извлечения его оттуда. Прописаны в самом начале, до таблицы векторов прерываний.
Код пишу в универсальном редкаторе RJ Editor, компилятор tavrasm, загрузчик AVR Dude, программатор USB tiny (самодельный).
П.С. Сигналы на каналах энкодера выглядят так:

Недавно начал заниматься программированием AVR, сейчас тренируюсь на tiny2313 на простых задачах (светодиоды, кнопки, энкодер, UART).
Написал простейшую программку, которая по внешним прерываниям опрашивает энкодер, инкрементирует/декрементирует значение в регистре и сразу отправляет по UART. Общий вывод энкодера на земле, каналы энкодера подключены ко входам для внешних прерываний INT0, INT1, включены внутренние подтягивающие резисторы. Использую лишь одно из этих прерываний.
Алгоритм простой:
1) Настраиваю прерывание по срезу импульса на INT0
2) Соответственно, когда возникло прерывание, точно известно, что первый канал энкодера переключился из 1 в 0.
3) Проверяю состояние второго канала, который подключен на PD3.
4) Если энкодер вращается в одну сторону (например, по ч.с.), то там будет 1, делаю инкремент регистра Steps.
5) Если энкодер вращается в другую сторону (против ч.с.), то там будет 0, делаю декремент регистра Steps.
5) Посылка Steps по UART.
6) Выход из прерывания.
В основном цикле ничего нет, только "заглушка" rjmp pc.
Проблема в том, что независимо от направления вращения энкодера получается только инкремент (или только декремент, если переход не по sbis, а по sbic). Как будто второй канал энкодера постоянно находится в 1.
Самые очевидные причины проверил:
1) Энкодер исправен, проверял подключением к нему светодиодов и медленным вращением.
2) Каналы энкодера подключены именно к ножкам PD2 (INT0), PD3 (INT1)
3) Эти ножки порта настроены на ввод, подтяжки включены.
4) Прерывание по INT0 разрешено, по INT1 запрещено.
5) Неисправен вход PD3? Пробовал подключать второй канал энкодера на PA0 - результат такой же.
Код: Выделить всё
Int_Ext0: PUSHF
cli ; чтобы дребезг контактов не вызвал ещё одно прерывание
sbis portD,3
breq Decr
inc Steps
rjmp uart_snt
Decr: dec Steps
uart_snt: sbis UCSRA,UDRE ; Пропуск, если нет флага готовности
rjmp uart_snt ; ждем готовности - флага UDRE
out UDR,Steps ; отправляем байт
sei
POPF
retiКод пишу в универсальном редкаторе RJ Editor, компилятор tavrasm, загрузчик AVR Dude, программатор USB tiny (самодельный).
П.С. Сигналы на каналах энкодера выглядят так:

Фак, кот грызёт провод! Сейчас его ударит либо током, либо тапком! ))
Если рассматривается только восходящий фронт - энкодер легко обмануть покачиванием около одного фронта (обозначенного красной стрелкой) покачиваемый около одной точки энкодер будет уверенно считать...
Для тех, кто не учил магию мир полон физики 
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Команда( ы) SBIS, SBIC, SBRS, SBRC не работают по флагам. CLI в обработчике бессмысленен
Что значит: [uquote="akl",url="/forum/viewtopic.php?p=3286281#p3286281"]Команда( ы) SBIS, SBIC, SBRS, SBRC не работают по флагам.[/uquote]



