|
|
  |
Таймер работает не корректно |
|
|
|
Oct 3 2013, 15:27
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Процессор: ATmega Частота: 8 МГц. Компилятор: AVR GCC После пробного запуска кода в симуляторе импульс на ножке имеет верхний и нижний участки одинаковой длины, хотя я добиваюсь обратного. Прошу посмотреть код, не могу объяснить ситуацию. Спасибо. CODE #include <avr/io.h> #include <avr/interrupt.h>
int t = 0x90; ISR(TIMER0_COMP_vect) { if(PINA & 0x01) { PORTA &= ~0x01; OCR0 = 0x90; } else { PORTA |= 0x01; OCR0 = 0x0C; } TCNT0=0x00; }
int main(void) { DDRA = 0x01;
// Делитель на 1024 (8МГц / 1024 = 7,8125КГц) // 128 мкс TCCR0=0x05; TCNT0=0x00; //OCR0=0x0C;
TIMSK=0x02;
// Разрешаем прерывания глобально sei();
while(1) ;
return 0; }
Сообщение отредактировал IgorKossak - Oct 3 2013, 18:04
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!!!
|
|
|
|
|
Oct 3 2013, 16:12
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Цитата(Палыч @ Oct 3 2013, 20:05)  Хорошо бы задавая вопрос указывать конкретный тип МК. Простите... Процессор: ATmega16 Я убрал строчку Код TCNT0=0x00; и получил несимметричный импульс, но верх равен 16 мс, а низ 50 мс. Почему? Так же увидел строчку "• Clear Timer on Compare Match (Auto Reload)" в описании. Ситуация для меня не разрешимая.
|
|
|
|
|
Oct 3 2013, 18:28
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Попробовал на втором таймере Код #include <avr/io.h> #include <avr/interrupt.h>
ISR(TIMER2_COMP_vect) { if(PINA & 0x01) { PORTA &= ~0x01; OCR2 = 0x90; } else { PORTA |= 0x01; OCR2 = 0x0C; } //TCNT0=0x00; }
int main(void) { DDRA = 0x01;
// Делитель на 1024 (8МГц / 1024 = 7,8125КГц = 128 мкс) // CTC режим TCCR2=0x0F; TCNT2=0x00; OCR2=0x0C;
TIMSK=0x80;
// Разрешаем прерывания глобально sei();
while(1) ;
return 0; } , верх импульса - 33 мс, низ - 1,65 мс. Вопросов два: 1. Код вроде как правильный? 2. Если нужно сделать генератор с варьируемым коэффициент заполнения и с одинаковым периодом, есть код проще моего? Спасибо. ПС: Цитата(Xenia @ Oct 3 2013, 19:51)  Да и в даташите OCR0 вообще не вижу. Откеда вы его взяли? В моем даташите есть ( Rev. 2466T–AVR–07/10), если интересно могу прислать.
Сообщение отредактировал e-leks - Oct 3 2013, 18:33
|
|
|
|
|
Oct 3 2013, 19:29
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(e-leks @ Oct 3 2013, 22:28)  В моем даташите есть ( Rev. 2466T–AVR–07/10), если интересно могу прислать. У ATmega16 регистр OCR0 у таймера есть, но у ATmega8 его нет. Я же высказала свое сомнение о наличии OCR0 только потому, что вы к тому времени не назвали тип своего МК. Я всегда так поступаю - отвечаю на вопросы по AVR, подразумевая по умолчанию ATmega8. Если не угадала - вопрошающий сам виноват. А то уже обрыдло всякий раз задавать один и тот же встречный вопрос "А что у вас?". Цитата(e-leks @ Oct 3 2013, 22:28)  2. Если нужно сделать генератор с варьируемым коэффициент заполнения и с одинаковым периодом, есть код проще моего? Есть проще  . Тогда частоту меандра задают по переполнению таймера, а скважность задают через OCR. Тогда прерываться в прерывание вообще не нужно, но сигнал надо снимать с ноги OC2 (PD7). Еще вариант - использовать таймер 1, который имеет пару OC1A (PD5) и OC1B (PD4). Тогда одним из них задают периодичность меандра, а вторым задают уровень, на котором возникает переключение уровня на ножке ОС.
|
|
|
|
|
Oct 4 2013, 13:44
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Люди добрые, я использовал "стандартные" подходы: 1. Установил делитель 2. Настроил таймер на сравнение 3. Использовал режим СТС для сброса 4. Включил прерывания глобально Мне не нужно больше ничего придумывать, мне нужно понять: либо я написал что то неправильно, либо ошибка не в моих действиях. Прошу Вас помочь заставить мой код работать или ответить почему он не работает корректно. Неужели у столь большого сообщества специалистов нет ответа на далеко не самый сложный вопрос?
Благодарю!
|
|
|
|
|
Oct 4 2013, 15:21
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Цитата(Палыч @ Oct 4 2013, 19:12)  Поправьте оператор if в процедуре прерывания Не помогло, а может симулятор не корректно работать? Просто осциллографа нет, проверить не где. Попробую подключить к сервомашинке, посмотрю будет ли реагировать.
|
|
|
|
|
Oct 4 2013, 15:51
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(e-leks @ Oct 4 2013, 19:21)  Не помогло, а может симулятор не корректно работать? Просто осциллографа нет, проверить не где. Прошу прощения, не дочитал: "После пробного запуска кода в симуляторе..." Что ж, попробую и я "прогнать" в симуляторе Вашу программу. Имеем: Низкий уровень = 18.56мс. Проверяем (0x90+1)*0.128=(144+1)*0.128=145*0.128= 18.56мс Высокий уровень = 1.664мс. Проверяем (0x0C+1)*0.128=(12+1)*0.128=13*0.128= 1.664мс Где некорректная работа таймера?
|
|
|
|
|
Oct 4 2013, 16:03
|
Участник

Группа: Участник
Сообщений: 22
Регистрация: 12-10-11
Пользователь №: 67 694

|
Цитата(e-leks @ Oct 3 2013, 22:28)  верх импульса - 33 мс, низ - 1,65 мс. У меня получается участок с высоким уровнем 33 мс, а с низким 1,65 мс. Получается что симулятор (Proteus) врет.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|