|
старанности в работе timer0, mega16 |
|
|
|
Jul 1 2008, 16:08
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 7-04-05
Пользователь №: 3 947

|
здравствуйте. столкнулся со следующим непонятным поведением timer0 на atmega16. первоначально была программа, в которой, помимо всего прочего, таймер отсчитывал 5 мс по кругу. однако после добавления куска инициализации uart, а точнее только разрешения работы передатчика, приводит к тому что таймер срабатывает раз в 10 мс. все это я прекрасно вижу на осциллографе. стоит только убрать бит TXEN, как все становиться нормально. я с МК работаю недавно, и на ум ничего не приходит самому. в чем может быть дело??? далее предлагаю исходник. компилятор IAR 5.11 (все оптимизации выключены) Код #define ENABLE_BIT_DEFINITIONS
#include <stdio.h> #include <inavr.h> #include <iom16.h>
#define USART_PC
volatile int intFront; //содержит значения фронта сигнала по которому происходит прерывание (0 - спадающий, 1 - возрастающий)
//================================================================ //На вход подается сигнал с частотой 100 Гц, длительность импульса 160 мкс // // //================================================================
#pragma vector=INT0_vect __interrupt void int0_gen(void) { if (intFront==0) { //============================================================ //спадающий фронт сигнала TIMSK |= (1<<OCIE0); //разрешения прерывания таймера по совпадению TCCR0 = 0x0D; //start timer } else { //установка генерации прерывания по спадающему фронту фронту intFront = 0; GICR &= ~(1<<INT0); //запрещение прерывания на INT0 MCUCR |= (1<<ISC01); //генерация прерывания по спадающему фронту сигнала на ножже 11 (INT0) MCUCR &= ~(1<<ISC00); GICR |= (1<<INT0); //разрешение прерывания на INT0 } }
//================================================================ //Обработка прерывания по совпадению таймера // // //================================================================ #pragma vector=TIMER0_COMP_vect __interrupt void timer0_5ms(void) { PORTA ^= 0x01; TIMSK &= ~(1<<OCIE0); //запрещение прерывания таймера по совпадению TCCR0 = 0x08; //останавливаем таймер //============================================================ //установка генерации прерывания по возрастающему фронту intFront = 1; GICR &= ~(1<<INT0); //запрещение прерывания на INT0 MCUCR |= (1<<ISC01) | (1<<ISC00); //генерация прерывания по нарастающему фронту сигнала на ножке 11 (INT0) GICR |= (1<<INT0); //разрешение прерывания на INT0 }
void timer0_init(void) //таймер на 5 мс { TCCR0 = 0x00; //stop TCNT0 = 0x00; //set count OCR0 = 0x24; //set compare TCCR0 = 0x08; //пока остановлен //TCCR0 = 0x0D; //start timer }
void uart_pc_init(void) { UCSRB = 0x00; //disable while setting baud rate UCSRA = 0x00; UCSRC = (1<<URSEL) | 0x06; UBRRL = 0x03; //set baud rate lo UBRRH = 0x00; //set baud rate hi UCSRB = 0x18; // !!!! после включения передатчика и начинаются все казусы }
int main( void ) { __disable_interrupt(); //disable all interrupts DDRA |= (1<<PA0); //PortA0 as output timer0_init(); void uart_pc_init(void)
intFront = 0; //сигнал того что первоначально прерывание по спадающему фронту MCUCR |= (1<<ISC01); //генерация прерывания по спадающему фронту на ножке 11 (INT0) GICR |= (1<<INT0); //разрешение внешнего прерывания __enable_interrupt(); //разрешения всех прерываний while(1) { }
}
|
|
|
|
|
 |
Ответов
|
Jul 1 2008, 21:37
|
Местный
  
Группа: Свой
Сообщений: 256
Регистрация: 6-03-06
Из: Украина, г. Винница
Пользователь №: 15 017

|
Цитата может и дурацкий вопрос, но все же:что такое полярность импульсов в данном случае и какая она в моем примере? Так как Вы пишете, что "длительность импульса 160 мкс", то по рисунку, приведенному выше, полярность - положительная Приведенный Вами листинг полный? Если это так, то по поводу 20 мс уж и не знаю, что сказать. Если нет, то пока единственное, что приходит на ум - это то, что программа не успевает переключиться на фронт/спад сигнала ДО его прихода. Опровергнуть/подтвердить это помогут 2хлучевой осциллограф и инверсия какого-либо пина при каждом фронте INT0. Кстати, а что за void uart_pc_init(void) в теле main?
|
|
|
|
|
Jul 2 2008, 09:53
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 7-04-05
Пользователь №: 3 947

|
Цитата(Александр Куличок @ Jul 2 2008, 01:37)  Так как Вы пишете, что "длительность импульса 160 мкс", то по рисунку, приведенному выше, полярность - положительная
Приведенный Вами листинг полный? Если это так, то по поводу 20 мс уж и не знаю, что сказать. Если нет, то пока единственное, что приходит на ум - это то, что программа не успевает переключиться на фронт/спад сигнала ДО его прихода. Опровергнуть/подтвердить это помогут 2хлучевой осциллограф и инверсия какого-либо пина при каждом фронте INT0. да, приведенный текст программыполный. спасибо за советы, проблема решилась добавлением строчки при перенастройки прерываний Код GIFR |= (1<<INTF0); // сброс флага, который мог установиться при смене активного фронта по двухлучевому осциллографу видно что прерывание по спадающему фронту без этой строки и включенном USART срабатывало через раз. теперь же все нормально. однако в чем причины я не совсем понимаю. Цитата Кстати, а что за void uart_pc_init(void) в теле main? это случайно попала когда постил текст программы  вообщем большое спасибо!
|
|
|
|
|
Jul 2 2008, 10:35
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(covsh @ Jul 2 2008, 12:53)  да, приведенный текст программыполный. спасибо за советы, проблема решилась добавлением строчки при перенастройки прерываний Код GIFR |= (1<<INTF0); // сброс флага, который мог установиться при смене активного фронта Неправильно! Эдак Вы все выпавшие флаги прерывания очистите при перенастройке. И будут очередные поиски глюков. Код GIFR = (1<<INTF0); // сброс флага, который мог установиться при смене активного фронта Так что мне тоже спасибо
|
|
|
|
Сообщений в этой теме
covsh старанности в работе timer0, mega16 Jul 1 2008, 16:08 Александр Куличок А что размещено по вектору передатчика UART?
IMHO... Jul 1 2008, 16:54 covsh Цитата(Александр Куличок @ Jul 1 2008, 20... Jul 1 2008, 17:39 Александр Куличок Цитатано все таки, разве это могло служить причино... Jul 1 2008, 17:53 covsh Цитата(Александр Куличок @ Jul 1 2008, 21... Jul 1 2008, 19:32 Александр Куличок Цитатачто-то я не могу понять, в моей задумке тайм... Jul 1 2008, 19:43 covsh Цитата(Александр Куличок @ Jul 1 2008, 23... Jul 1 2008, 20:34 SasaVitebsk На мой взгляд.
1) TCNT тоже надо обнулять, раз ты ... Jul 1 2008, 20:01   covsh Цитата(_Pasha @ Jul 2 2008, 14:35) Неправ... Jul 3 2008, 17:08    _Pasha Цитата(covsh @ Jul 3 2008, 21:08) или я ч... Jul 3 2008, 17:36    Александр Куличок Цитата(covsh @ Jul 3 2008, 20:08) а объяс... Jul 3 2008, 17:39     covsh большое спасибо все, разобрался Jul 3 2008, 19:13 defunct Что-то я не понял зачем намудрено с переключением ... Jul 2 2008, 15:45 Александр Куличок ЦитатаЭдак Вы все выпавшие флаги прерывания очисти... Jul 2 2008, 22:41
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|