Таймеры/счётчики в AVR
Таблицу режимов таймера 1 в даташите посмотрите, тогда поймете, почему в вашем случае флаг переполнения не включается, а в моём включается. По совпадению OCR1A кстати тоже можно ловить.
- Реклама
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
Давно хотел проверить, как теперь протеус ардуину симулирует, а тут как раз этот случай. Загнал все в симуляцию и действительно, в FastPWM top=OCR0A вызываются и прерывание по совпадению "А" и прерывание по переполнению. Причем, сначала идет прерывание по совпадению, а потом уже по переполнению.
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
Если можно, выложите листинг программы на Си, которую вы проверяете. Я её пропущу через симулятор VMLab, где будет видно какие и когда прерывания вызываются, типа вот так:a5021 писал(а):Давно хотел проверить, как теперь протеус ардуину симулирует, а тут как раз этот случай. Загнал все в симуляцию и действительно, в FastPWM top=OCR0A вызываются и прерывание по совпадению "А" и прерывание по переполнению. Причем, сначала идет прерывание по совпадению, а потом уже по переполнению.
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
Код ардуиновский, в чистый си переделайте сами, благо не сложно.
Спойлер
Код: Выделить всё
/* Main.ino file generated by New Project wizard
*
* Processor: ATmega328P
* Compiler: Arduino AVR
*/
volatile unsigned char bFlag;
ISR(TIMER2_COMPA_vect){
bFlag = 1;
}
ISR(TIMER2_COMPB_vect){
bFlag = 0;
}
ISR(TIMER2_OVF_vect){
bFlag = 2;
}
void setup() {
// put your setup code here, to run once:
// Timer/Counter 2 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Fast PWM top=OCR2A
// OC2A output: Disconnected
// OC2B output: Disconnected
// Timer Period: 4 ms
ASSR=(0<<EXCLK) | (0<<AS2);
TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20);
TCCR2B=(1<<WGM22) | (1<<CS22) | (1<<CS21) | (0<<CS20);
TCNT2=0x00;
OCR2A=0xF9;
OCR2B=0xA0;
// Timer/Counter 2 Interrupt(s) initialization
TIMSK2=(1<<OCIE2B) | (1<<OCIE2A) | (1<<TOIE2);
}
void loop() { // put your main code here, to run repeatedly:
}
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
А какой язык у Ардуиновского кода? Вы задали три вектора прерывания таймера2. Если вы разрешили общие прерывания, то прерывания будут происходить согласно их приоритетам. В чём проблема?a5021 писал(а):Код ардуиновский, в чистый си переделайте сами, благо не сложно.Спойлер
Код: Выделить всё
/* Main.ino file generated by New Project wizard * * Processor: ATmega328P * Compiler: Arduino AVR */ volatile unsigned char bFlag; ISR(TIMER2_COMPA_vect){ bFlag = 1; } ISR(TIMER2_COMPB_vect){ bFlag = 0; } ISR(TIMER2_OVF_vect){ bFlag = 2; } void setup() { // put your setup code here, to run once: // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: 62,500 kHz // Mode: Fast PWM top=OCR2A // OC2A output: Disconnected // OC2B output: Disconnected // Timer Period: 4 ms ASSR=(0<<EXCLK) | (0<<AS2); TCCR2A=(0<<COM2A1) | (0<<COM2A0) | (0<<COM2B1) | (0<<COM2B0) | (1<<WGM21) | (1<<WGM20); TCCR2B=(1<<WGM22) | (1<<CS22) | (1<<CS21) | (0<<CS20); TCNT2=0x00; OCR2A=0xF9; OCR2B=0xA0; // Timer/Counter 2 Interrupt(s) initialization TIMSK2=(1<<OCIE2B) | (1<<OCIE2A) | (1<<TOIE2); } void loop() { // put your main code here, to run repeatedly: }
- Реклама
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
Я, вроде, ни на какие проблемы не жаловался. COMPA в списке векторов выше, значит у него и приоритет выше, чем у OVF. Сомнения у меня было возникли по поводу вызывается ли OVF вообще, но теперь я выяснил, что в отличие от режима CTC, FastPWM вызывает и этот вектор, фактически по одному и тому же событию, что, на мой взгляд, немного не логично.
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
Вообще он вызывается по-всякому, - Вы же его прописали в программе. Инициализация прошла ,вектор установлен, - только жди общих прерываний, а там OVF возмёт своё.a5021 писал(а):Сомнения у меня было возникли по поводу вызывается ли OVF вообще,
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
Акромя программиста вектор прерывания никто не вызывает и не устанавливает. Априори он устанавливается по программе в самом начеле адресного поля, но программист может изменить адрес вектора по своим убеждениям, как он хочет.a5021 писал(а): FastPWM вызывает и этот вектор
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
Что такое СТС-режим?a5021 писал(а):В CTC-режиме не вызывается, хоть прописывай, хоть жди.
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
In Clear Timer on Compare or CTC mode (WGM13:0 = 4 or 12), the OCR1A or ICR1 Register
are used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when
the counter value (TCNT1) matches either the OCR1A (WGM13:0 = 4) or the ICR1 (WGM13:0 =
12). The OCR1A or ICR1 define the top value for the counter, hence also its resolution. This
mode allows greater control of the Compare Match output frequency. It also simplifies the oper-
ation of counting external events.
are used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when
the counter value (TCNT1) matches either the OCR1A (WGM13:0 = 4) or the ICR1 (WGM13:0 =
12). The OCR1A or ICR1 define the top value for the counter, hence also its resolution. This
mode allows greater control of the Compare Match output frequency. It also simplifies the oper-
ation of counting external events.
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
I" m none the better for it. Пожалуйста, на русском в одном предложении.a5021 писал(а):In Clear Timer on Compare or CTC mode (WGM13:0 = 4 or 12), the OCR1A or ICR1 Register
are used to manipulate the counter resolution. In CTC mode the counter is cleared to zero when
the counter value (TCNT1) matches either the OCR1A (WGM13:0 = 4) or the ICR1 (WGM13:0 =
12). The OCR1A or ICR1 define the top value for the counter, hence also its resolution. This
mode allows greater control of the Compare Match output frequency. It also simplifies the oper-
ation of counting external events.
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
А Вы здесь зачем?a5021 писал(а):Это цитата из манула. Прочтите со словарем.
круто.gavrasio писал(а):Акромя программиста вектор прерывания никто не вызывает и не устанавливает. Априори он устанавливается по программе в самом начеле адресного поля, но программист может изменить адрес вектора по своим убеждениям, как он хочет.
а вот если я установлю флаг разрешения прерываний по переполнению таймера, и не определю обработчик этого прерывания - что будет? я (программист) ничего вызывать и устанавливать не буду - что произойдет?
и еще: очень хотелось бы увидеть код, который разместит адрес вектора прерывания по переполнению нулевого таймера на ячейку с адресом 0xF000 - в качестве примера, конечно.
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
Наконец то тяжёлая артиллерия прибыла. Второй вопрос я изучу и отпишу. Потом.ARV писал(а):gavrasio писал(а): а вот если я установлю флаг разрешения прерываний по переполнению таймера, и не определю обработчик этого прерывания - что будет? я (программист) ничего вызывать и устанавливать не буду - что произойдет?
и еще: очень хотелось бы увидеть код, который разместит адрес вектора прерывания по переполнению нулевого таймера на ячейку с адресом 0xF000 - в качестве примера, конечно.
По первому вопросу. Где Вы устанавливаете любые флаги, можно, при инициализации( ясно чего) или же в ходе исполнения программы( бери обработщик прерываний).
Если Вы не определите "обработщик этого прерывания" - ничего не будет. Что Вы понимаете за термином "определить обработщик"?
- Сообщения: 6452
- Зарегистрирован: Пт сен 13, 2013 13:11:31
Забавное утверждение. Забавное в своей абсурдности.gavrasio писал(а):Акромя программиста вектор прерывания никто не вызывает и не устанавливает.
Прерывание -- это событие и связанные с ним процессы, которые заключаются в следующем. Некоторое внешнее или внутреннее устройство (периферия) посылает ядру микроконтроллера сигнал о том, что должно произойти прерывание (извините за "сепульки"). Если флаг обработки прерываний установлен, то микроконтроллер останавливает обработку текущего кода, сохраняет текущий адрес, на котором он остановился (вернее, адрес следующей команды, которую он будет выполнять) и начинает выполнение команды с адреса где-то в начале ПЗУ. Точное значение адреса зависит от номера прерывания. Обычно по этому адресу располагается либо команда выхода RETI, либо команда перехода RJMP/JMP. Эта последовательность действий происходит вне зависимости от того, что запрограммировал программист, поскольку она (последовательность действий) заложена в МК производителем. Что будет если программист забыл расположить в нужном месте команду перехода к обработчику прерывания? Контроллеру наплевать: он будет интерпретировать всё, чтобы там ни было как команду процессора. Реально, если программист программирует на си, то обычно компилятор вставляет за программиста затычки на все не объявленные программистом обработчики прерываний. Затычка может быть как бесконечным циклом (что позволит отловить вызываемые, но не обрабатываемые прерывания), так и просто командой возврата. Программист на ассемблере обычно копипастит начало своей программы из какого-нибудь шаблона, так как программы для одного и того же МК обычно начинаются почти одинаково: таблица прерываний и инициализация периферии. Так что программист так или иначе, действительно устанавливает вектор прерываний, но никак его не вызывает. Переход к вектору осуществляет ядро МК в соответствующих условиях.
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
Практически во всех микроконтроллерах семейства Mega, заисключением модели ATmega48x, положение таблицы векторов прерываний может быть изменено. Таблица может располагаться не только в начале памяти программ,но также и в начале области загрузчика, причем перемещение таблицы можетбыть осуществлено непосредственно в ходе выполнения программы. Это цитата из книги Евстивеева А.В. Но с Вами согласен.ARV писал(а):gavrasio писал(а):
и еще: очень хотелось бы увидеть код, который разместит адрес вектора прерывания по переполнению нулевого таймера на ячейку с адресом 0xF000 - в качестве примера, конечно.
- Сообщения: 162
- Зарегистрирован: Пн июн 01, 2015 15:23:01
Естественно! Я устанавливаю, а вызывает какая-то движуха в программе.B@R5uk писал(а):Забавное утверждение. Забавное в своей абсурдности.gavrasio писал(а):Акромя программиста вектор прерывания никто не вызывает и не устанавливает.
Так что программист так или иначе, действительно устанавливает вектор прерываний, но никак его не вызывает. Переход к вектору осуществляет ядро МК в соответствующих условиях.
З.Ы. Вам книги надо писать, - получается нормально. Хорошая книга никому не помешает.


