|
|
  |
Не получается сконфигурировать таймер ATMega8515 |
|
|
|
May 15 2011, 20:35
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Не могу даже понять, откуда проблема. Необходимо запустить первый таймер в режиме - CTC по сравнению с регистром ICR1. Вот исходник: Код void InitializationTimer1(void){ TCCR1B |= _BV(CS11); // Тактирование таймера clk/8 = 1843200 Гц TCCR1B | _BV(WGM13) | _BV(WGM12); // Режим работы - "Сброс при совпадении ICR1" ICR1 = (F_CPU/8)/100; // Переполнение - через 10 mSec TIMSK |= _BV(TOIE1); // Разрешить прерывание по переполнению }
ISR (TIMER1_OVF_vect) { static u16 q = 0; if(q == 0){ PORTA ^= _BV(PA3); q = 100; }else --q; } Теоретически, прерывание должно возникать 100 раз в секунду, соответственно, дерганье ногой, в моем случае, должно происходить каждую секунду. Но в железе видно, что это происходит раз за почти четыре секунды. Значит, почему-то в регистре ICR1 не мое значение, а 0xFFFF. Решил глянуть в симуляторе студии. Оказывается, проблема в следующем: строка TCCR1B |= _BV(CS11) отрабатывается корректно, а строка TCCR1B | _BV(WGM13) | _BV(WGM12) не выставляет никакие биты, соответственно, таймер работает в режиме normal. Когда я объединил эти строки в одну TCCR1B |= _BV(CS11) | _BV(WGM13) | _BV(WGM12), в симуляторе начали выставляться все положенные биты, но в железе нога больше не дергается. Понимаю, что чего-то я не знаю. Вот собственно и вопрос - ЧЕГО? Компилятор с WinAVR-20100110, makefile - студийный, оптимизация Os
|
|
|
|
|
May 16 2011, 04:23
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Обычно делают так: Код cli(); TCCRxB = 0; // stop TCNTx = QQ; // setup1 ICRx = XX; // setup2 TCCRxA = YY; // configure1 TCCRxB = ZZ; // configure2 + start .... sei(); Т.е. прямо пишут байты в регистры таймера, а не по маске. И при остановленном таймере и запрещённых прерываниях. Что у Вас с cобакой (watchdog'ом)? И есть-ли у этой модели меги предделитель тактирования и выключен-ли он?
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
May 16 2011, 06:14
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Цитата Т.е. прямо пишут байты в регистры таймера В этой меге регистры общие для двух таймеров, так, что придется по маске. Цитата Что у Вас с cобакой (watchdog'ом)? И есть-ли у этой модели меги предделитель В моем случае задействование T1 - это дополнение к существующему проекту. В настоящее время на этом-же камне параллельно функционируют T0, INT0, UART, MODBUS исправно, во всяком случае визуально. Иключение - та самая нога из прерывания TIMER1_OVF_vect. Цитата и запрещённых прерываниях Инициализация производится на старте при выключеных прерываниях. Цитата И при остановленном таймере Попробовал переписать так Код ICR1 = (F_CPU/8)/100; // Переполнение - через 10 mSec TIMSK |= _BV(TOIE1); // Разрешить прерывание по переполнению TCCR1B |= _BV(CS11) // Тактирование таймера clk/8 = 1843200 Гц | _BV(WGM13) | _BV(WGM12); // Режим работы - "Сброс при совпадении ICR1" Визуально - прерывания нет, в симуляторе все нужные биты регистров выставлены, а счетный регистр почему-то стоит в нулях.
|
|
|
|
|
May 16 2011, 06:38
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Sirko @ May 16 2011, 10:14)  В этой меге регистры общие для двух таймеров, так, что придется по маске. Не верю! У неё всего 2 таймера timer0 (8бит) и timer1 (16бит) и у каждого из них собственные TCCRA, TCCRB, ICR, OCR, TCNT иначе быть не может. Из общего у них лишь TIMSK пожалуй. Это общепринятая идеология у всех AVR.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
May 16 2011, 10:23
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Цитата а с чего собственно TCCR1B должен был измениться? Действительно не видел Хотя это, в настоящий момент - не актуально, т.к. TCCR1B |= _BV(CS11) | _BV(WGM13) | _BV(WGM12) отрабатывает корректно. Цитата Не верю! Вероятно, у меня ассоциация с TIMSK. Цитата И при остановленном таймере и... Вернусь домой, попробую, отпишусь. Спасибо.
|
|
|
|
|
May 16 2011, 18:36
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Чет невыходит ниче. Инициализирую вот так: TCCR1B = 0; // stop TCNT1 = 0; // setup1 ICR1 = 0x4800; // setup2 TCCR1A = 0; // configure1 TCCR1B = _BV(CS11) | _BV(WGM13) | _BV(WGM12); // configure2 + start TIMSK |= _BV(TOIE1); TCNT1 в симуляторе - как вкопаный. В железе тоже тишина (касаемо этого таймера, остальной код работает).
Вроде все верно. Че ему нужно?
|
|
|
|
|
May 16 2011, 19:58
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Цитата Очень интересно, ждём прерывание по совпадению... Простите, - не совсем понял. Если Вы имеете в виду прерывание по сравнению, то действительно, мне будут нужны прерывания и сравнения и переполнения. Вот только в этом топике я не вижу, где я использовал сравнение. Цитата и чего в итоге ждём Скорее не ждем, а хотим запустить таймер в режиме "сброс по совпадению". Почему-то счетный регистр не хочет шевелиться. В чем кроется загвоздка - не знаю.
|
|
|
|
|
May 16 2011, 20:35
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(Sirko @ May 16 2011, 23:58)  Простите, - не совсем понял. Если Вы имеете в виду прерывание по сравнению, то действительно, мне будут нужны прерывания и сравнения и переполнения. Вот только в этом топике я не вижу, где я использовал сравнение.
Скорее не ждем, а хотим запустить таймер в режиме "сброс по совпадению". Почему-то счетный регистр не хочет шевелиться. В чем кроется загвоздка - не знаю. Это же Ваше Цитата Необходимо запустить первый таймер в режиме - CTC по сравнению с регистром ICR1. И каким образом Вы собираетесь добирвться до переполнения , если выставлен режим сравнения, что ознaчает - при совпадении немедленный сброс и счёт заново до значения 0х4800 , что значительно меньше чем 0xFFFF 2. Проверьте , что записывается в бит CS11 и какую частоту Вы поставили процессору в симмуляторе
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
May 17 2011, 04:12
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Sirko @ May 16 2011, 22:36)  Че ему нужно? Используйте mode 4. Вот вам рабочий пример, правда не для вашей меги, но поправить его 1 мин: Код //============================================================================= // TIMER1 ATmega(16)(128)(64): // Mode:2 (CTC) clear on compere (TCNTn[0->OCRnA]) // TOP: OCRnA // Div: 256 // FTIMER = F_CPU/(DIV*(OCR+1)) // actual value: 1,000Hz (0,0%) //============================================================================= static void timer1_init(void) { #define F_NEED1 1UL #define F_DIV1 256UL #define OCR1_VALUE (F_CPU/(F_DIV1*F_NEED1)-1)
TCCR1B = 0x00; //stop
OCR1AH = BYTE1(OCR1_VALUE); OCR1AL = BYTE0(OCR1_VALUE);
TCCR1A = 0x00; TCCR1B = (1<<WGM12)|(1<<CS12); // start timer with div=256
TIMSK |= (1<<OCIE1A); //timer interrupt sources }
ISR(TIMER1_COMPA_vect) { sec++; }
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
May 17 2011, 19:20
|
Местный
  
Группа: Участник
Сообщений: 245
Регистрация: 15-08-07
Пользователь №: 29 795

|
Цитата Это же Ваше Мое. Только я считал, что при сравнении с ICR1 отработает прерывание по переполнению.
Цитата Используйте mode 4. Суть в том, что мне потребуются прерывания и от OCR1A и от OCR1B. По поводу прерывания от ICR1 - я обойдусь. Только вот вопрос, не столько жизненно важный, а скорее для общего развития остается. А именно, как запустить таймер, у которого бы при достижении регистра TCNT значения 1000 отработало бы прерывание OCR1A, значения 2000 - OCR1B, значения 3000 - OVERFLOW ? Даже не как, а реально-ли. В голове уже каша.
|
|
|
|
|
May 17 2011, 20:13
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(Sirko @ May 17 2011, 23:20)  Мое. Только я считал, что при сравнении с ICR1 отработает прерывание по переполнению.
Суть в том, что мне потребуются прерывания и от OCR1A и от OCR1B. По поводу прерывания от ICR1 - я обойдусь. Только вот вопрос, не столько жизненно важный, а скорее для общего развития остается. А именно, как запустить таймер, у которого бы при достижении регистра TCNT значения 1000 отработало бы прерывание OCR1A, значения 2000 - OCR1B, значения 3000 - OVERFLOW ? Даже не как, а реально-ли. В голове уже каша. Ну у Вас же на приведённом Вами рисунке написано , при совпадении с ICR установится флаг ICF, соответственно в регистре TIMSK надо разрешить прерывание захвата TICIE1 и соответсвенно изменить обработчик прерывания. Максимальное значение здесь -надо понимать , это значение записаное в регистр ICR или OCR1A,B 2. Надо понимать , что режим называется СБРОС при совпадении, т.е при достижении значения 1000, TCNT сбросится в ноль и счёт начнётся снова. Но программно Вы сможете посчитать сколько было прерываний по 1000 и обработать 2000 или 3000.
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|