Вот код. Хочу регулировать скважность шим сигнала с помощью переменного резистора, но не могу правильно считать данные с АЦП и записать в соответствующий регистр. Подскажите пожалуйста а лучше подправите как правильно сделать. Микроконтролер Attiny 13A. Спойлер
Код:
.include "tn13Adef.inc"; Header files .list; // Отоброжения листинга исполнения команды. .cseg; работаем с програмной памятью а не озу или eeprom .org 0; устанавливаем начальную позицию строки rjmp START; Reset Handler rjmp START; IRQ0 Handler rjmp START;; PCINT0Z Handler rjmp START; 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 START; ADC Conversion Handler
START: // команда запрещает глобальные прерывания. CLI; //инициализация стэка.(установка максимально размера ОЗУ); ldi R17, RAMEND; out SPL, R17;
//Включаем аналогово-цифровой преобразователь SBI ADCSRA, ADEN; //Режим работы выставляем непрерывное преобразования SBI ADCSRA, ADATE; //И выставляем режим работы на прерывания от переполнения таймер счетчика. LDI R16,(1<<ADTS2)|(0<<ADTS1)|(0<<ADTS0); out ADCSRB, R16; //Выбираем коэфициент пределителя тактовой частоты АЦП при расчете что частота 9,6/8=1,2 Мгц; 1200/8=150; где 8 выбранный коэфициент LDI R16,(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0); out ADCSRA, R16; //Выбираем напряжение питание микроконтролера, ставим питания от мк. CBI ADMUX, REFS0; //Выбираем ножку мк которая будет производить измерения ADC1 LDI R16, (0<<MUX1)|(1<<MUX0); //Оставляем работу ножки МК как на вход для измерения сигнала CBI DDRB, DDB0; CBI PORTB, PB0; //Запуск преобразования SBI ADCSRA, ADSC;
//Подключаем таймер в режиме 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, 0xFE; out OCR0A, R16;
rjmp START1;
START1: //Считываем данные с младшего регистра АЦП, и подставляем их в OCR0A для изменения скважности. ldi R16, ADCL; out OCR0A, R16; rjmp START1;
Заголовок сообщения: Re: Ассемблер (ASM) для AVR в вопросах и ответах
Добавлено: Пт янв 12, 2018 09:38:26
Собутыльник Кота
Карма: 29
Рейтинг сообщений: 645
Зарегистрирован: Сб май 14, 2011 21:16:04 Сообщений: 2694 Откуда: г. Чайковский
Рейтинг сообщения:0 Медали: 1
Цитата:
14.12.4 ADCSRB – ADC Control and Status Register B .... .... • Bits 2:0 – ADTS[2:0]: ADC Auto Trigger Source ... ...Switching to Free Running mode (ADTS[2:0]=0) will not cause a trigger event, even if the ADC Interrupt Flag is set.
В цикле ждите окончание преобразования АЦП (проверка соответствующего флага), считывайте значение АЦП и снова ручками запускайте преобразование.
По скольку вы решили использовать только 8 бит АЦП, то включите выравнивание результата по левому краю и считывайте ADCH.
_________________ Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ очень важен контроль процесса заряда и разряда для избегания воздействия внешнего зарядного напряжения после достижения 100% заряда. Инженеры КОМПЭЛ подготовили список таких решений от разных производителей.
Можно работать по прерыванию готовности данных с АЦП, в прерывании заносите данные в OCR0A. Установите частоту шим с учетом емкости таймера fOCnxPWM=Fclk/(N*256)
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
START1: //Считываем данные с младшего регистра АЦП, и подставляем их в OCR0A для изменения скважности. //Команда проверяет на установку флага в регистре. SBIC ADCSRA, ADIF; rjmp ACPPP; nop; rjmp START1;
ACPPP: //Считываем данные АЦП in R16, ADCH; //Записываем считанные данные в регистр. out OCR0A, R16; //Запускаем преобразования SBI ADCSRA, ADSC; //Очищаем флаг. sbi ADCSRA, ADIF; rjmp START1;
Сделал так но все равно не работает. В AVR симуляторе АЦП не входит в прерывания "ADC Conversion Handler", хотя таймер TCNT0 значение меняет . А в настройках стоит уходить в прерывания по переполнению таймера. Но по флагу то же что то грустно так как переходит в ACPPP: если его выставить в ручную а так не хочет. Такое чувство что АЦП не работает вообще.
Последний раз редактировалось strengerst Пт янв 12, 2018 10:54:18, всего редактировалось 1 раз.
Флаг не устанавливается,. "//И выставляем режим работы на прерывания от переполнения таймер счетчика. LDI R16,(1<<ADTS2)|(0<<ADTS1)|(0<<ADTS0); out ADCSRB, R16; " - В этом смысле.
Да вы правы теперь прерывания от ацп работает, я понял в чем я ошибся, в неправильной последовательности записи. Теперь исправил вот так. Буду проверять дальше. Всем спасибо.
Спойлер
Код:
.include "tn13Adef.inc"; Header files .list; // Отоброжения листинга исполнения команды. .cseg; работаем с програмной памятью а не озу или eeprom .org 0; устанавливаем начальную позицию строки rjmp START; Reset Handler rjmp START; IRQ0 Handler rjmp START;; PCINT0Z Handler rjmp START; 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 ACPPP; ADC Conversion Handler
START: // команда запрещает глобальные прерывания. CLI; //инициализация стэка.(установка максимально размера ОЗУ); ldi R17, RAMEND; out SPL, R17;
//И выставляем режим работы на прерывания от переполнения таймер счетчика. LDI R16,(1<<ADTS2)|(0<<ADTS1)|(0<<ADTS0); out ADCSRB, R16; //Выбираем коэфициент пределителя тактовой частоты АЦП при расчете что частота 9,6/8=1,2 Мгц; 1200/8=150; где 8 выбранный коэфициент LDI R16,(0<<ADPS2)|(1<<ADPS1)|(1<<ADPS0)|(1<<ADIE); out ADCSRA, R16; //Включаем аналогово-цифровой преобразователь SBI ADCSRA, ADEN; //Режим работы выставляем непрерывное преобразования SBI ADCSRA, ADATE; //Делаем выравнивания по левому краю для считывания ADCH. SBI ADMUX, ADLAR; //Выбираем напряжение питание микроконтролера, ставим питания от мк. CBI ADMUX, REFS0; //Выбираем ножку мк которая будет производить измерения ADC1 LDI R16, (0<<MUX1)|(1<<MUX0); //Оставляем работу ножки МК как на вход для измерения сигнала CBI DDRB, DDB0; CBI PORTB, PB0; //Запуск преобразования SBI ADCSRA, ADSC;
//Подключаем таймер в режиме 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, 0x00; out OCR0A, R16; sei; rjmp START1;
START1: //Считываем данные с младшего регистра АЦП, и подставляем их в OCR0A для изменения скважности. //Команда проверяет на установку флага в регистре. //SBIC ADCSRA, ADIF; nop; //nop; rjmp START1;
ACPPP: //Считываем данные АЦП in R16, ADCH; //Записываем считанные данные в регистр. out OCR0A, R16; //Запускаем преобразования SBI ADCSRA, ADSC; //Очищаем флаг. sbi ADCSRA, ADIF; reti;
Добавлено after 1 hour 29 minutes 27 seconds: Теперь протеус не запускается, стопорить постоянно на адресе прерывания. А в AVR симуляции, постоянно входит в прерывания короче полный бардак. Данные с ADCH не считываются.
Вольфганг Трамперт "AVR-RISC микроконтроллеры фирмы ATMEL". Прочитайте эту книгу. Там ответы на элементарные вопросы. Не тратьте напрасно свое и наше время! Ваше время: прочитаете книгу, снимутся вопросы, сами будете знать. Наше время: не надо отвечать на простые вопросы, которые снимаются после прочтения книг. Личное время - это невосполнимый ресурс. Его никто не вернет.
Книга не дает практики, и многое само сабой тоже не снимается. А форумы для того создали что бы общались и помогали, тем более конкретно вас Demiurg не кто не просит тратить свое время, перейдите на другой раздел форума или вообще помогите другим более опытным участникам.
Вы, последние двое задали те вопросы, ответы на которые получите из этой книги. Плюс примеры программ для практики. Не надо рассматривать форумы как отвечалки на простые элементарные вопросы. А вот когда затруднения, тогда уже другой вопрос.
Минутка полезностей! Делюсь кодом на ассемблере для организации точных задержек на AVR. Точность до такта. Надеюсь будет полезно, так как в свое время обыскался! short_delay я откопал на каком-то форуме (скрин), long_delay писал сам по образу и подобию short_delay. Представлено в виде макроса. Пример использования в коде: "long_delay 123456" - дает задержку ровно на 123456 тактов.
nop'ы в конце long_delay обязательны!
Код:
//задержка на 8-65543 тактов .macro short_delay ldi r24, low( @0 - 8 ) ldi r25, high( @0 - 8 ) sbiw r24, 4 brcc pc - 1 cpi r24, 0xFD brcs pc + 4 breq pc + 3 cpi r24, 0xFF breq pc + 1 .endmacro
Код:
//задержка на 13-16777228 тактов .macro long_delay ldi r16, low( @0 - 13 ) ldi r17, high( @0 - 13 ) ldi r18, byte3( @0 - 13 ) subi r16, 5 sbci r17, 0 sbci r18, 0 brcc pc - 3 cpi r16, 0xFB brcs pc + 8 breq pc + 7 cpi r16, 0xFD brcs pc + 6 breq pc + 5 cpi r16, 0xFF brcs pc + 4 breq pc + 3 nop nop .endmacro
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 42
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения