Не могу настроить таймер1 attiny85
- Войдите на сайт для отправки комментариев
Пт, 27/10/2017 - 16:33
Не получается настроить таймер1 для аттини, хчоу чтоб раз в секунду инвертировался выход, по расчетам вроде не ошибся, но порт инвертируется раз в 16 секунд гдето, судя по протеусу. Ещё меняю значение регистра OCR1A; и тоже ничего не происходит. Где я прокосячил?
#define F_CPU 8000000UL #include <avr/io.h> #include <avr/interrupt.h> #include <util/delay.h> #define TIMER_TICKS_IN_ONE_SECOND 125 //тики таймера в секунду при делителе 512. OCR1A=125. (8000000/512/125 = 125) unsigned char count_to_second; //число тиков TIMER1 //инициализация таймера1 void timer1_ini (void){ TCCR1 |= (1 << CTC1) //режим CTC |(0<<COM1A1)|(0<<COM1A0) //отключаем OC1A |(1 << CS13)|(0 << CS12)|(1 << CS11)|(0 << CS10); //Делитель 512 TCNT1 = 0x00; //сброс счетчика OCR1A = 125; //регистр сравнения TIMSK |=(1<<OCIE1A); //включаем прерывания по сравнению с OCR1A } //------------------------------------------------------------------ void port_ini (void){ DDRB=0b00000001;//PB0 - выход, PB1 - , PB2 - , PB3 - , PB4 - входы, PORTB=0b00000000; } //обработка прерывания таймера1 ISR(TIMER1_COMPA_vect){ count_to_second++; if (count_to_second >= TIMER_TICKS_IN_ONE_SECOND) { // Отсчитываем прерывание 125 раз получаем 1 секунду PORTB ^= _BV(PB0); // инвертируем состояние порта PB0 count_to_second=0; } } int main(void) { port_ini(); timer1_ini(); sei(); while (1) { } }
может поменять 6 строку на #define TIMER_TICKS_IN_ONE_SECOND 8
получется что 8*125*512 = 512000, а должно 8000000
получется что 8*125*512 = 512000, а должно 8000000
да я и не спорю :)
но тут два варианта: или фьюзы криво стоят, или в программе ошибка - меняем 6 строку на 8 и срабатывает аккурат в 16 раз быстрее.
когда над своей attiny тренировался - простейший метод узнать правильно ли скорость фьюзами выставлена,
мигаем светодиодом с задержкой delay(1000) - если ровно секунда - значит скорось выставлена верно
papakaplo, смотрю все наступают на одни и те-же грабли. Как-то раз уже разъяснял, у вас полностью аналогичный случай.
получется что 8*125*512 = 512000, а должно 8000000
да я и не спорю :)
но тут два варианта: или фьюзы криво стоят, или в программе ошибка - меняем 6 строку на 8 и срабатывает аккурат в 16 раз быстрее.
CLKDIV8 выставил в протеусе теперь раз в 2 секунды смена состояния идет.
papakaplo, смотрю все наступают на одни и те-же грабли. Как-то раз уже разъяснял, у вас полностью аналогичный случай.
смотрел и не раз, скажите в чем именно косяк? в режиме CTC (сравнения)? меняю значения регистра OCR1A как считал так и считает без изменений.
papakaplo, йошкин кот! Ответ #1 в той теме. Читайте до прояснения.
papakaplo, йошкин кот! Ответ #1 в той теме. Читайте до прояснения.
Читал, в общем сделал вот так
Я не dimax, но, если не возражаете, помогу ему
надеюсь все правильно понял
Боюсь, что нет.
OCR1A = 5; <---тут может быть любое число лишь бы не 0
Почему? С 0 тоже отлично работает. Здесь может быть число <=125, а вот при любом >125 работать перестаёт (по крайней мере в реальной жизни - насчёт протеуса не знаю).
Дело, конечно Ваше (локальную проблему Вы решили), но вот я бы на Вашем месте, читал бы даташит до дыр и экспериментировал бы с микросхемой до тех пор, пока не понял бы до конца и не убедился бы, что реальная микросхема ведёт себя в точном соответствии с моим пониманием и моей картиной мира.
экспериментировал бы с микросхемой до тех пор, пока не понял бы до конца и не убедился бы, что реальная микросхема ведёт себя в точном соответствии .
Протеус дает не правильные задержки, только реальная микросхема.
Почему? С 0 тоже отлично работает. Здесь может быть число <=125, а вот при любом >125 работать перестаёт (по крайней мере в реальной жизни - насчёт протеуса не знаю).
Дело, конечно Ваше (локальную проблему Вы решили), но вот я бы на Вашем месте, читал бы даташит до дыр и экспериментировал бы с микросхемой до тех пор, пока не понял бы до конца и не убедился бы, что реальная микросхема ведёт себя в точном соответствии с моим пониманием и моей картиной мира.
только что проверил в протеусе, работает только в этом интервале, 0 < OCR1A <=OCR1C .
ДШ открыт постоянно, но вот познания в английском не позволяют полностью понять весь смысл заложенный инженерами АВР. Тем более там технический язык. Но со временем я думаю проще станет. попробую в микросхему загрузить интервал 0 < OCR1A <=125.
только что проверил в протеусе, работает только в этом интервале, 0 < OCR1A <=OCR1C .
Ну, я сразу сказал, что про протеус не знаю. А в микросхеме у меня работает и с 0 тоже.
Всем здравия... Подскажите плиз почему у меня "лыжи не едут". Пытаюсь эмулировать в протеусе таймер1 в Tiny45. Вроде все работает, но задержка получается почему-то слишком длинной. Ожидается в 1 сек, а в протеусе показывает около 4-х сек. Подскажите это я что-то делаю не так или это протеус мне голову морочит.
Код конечно не ардуиновский, использую IAR, но смысл тот же.
А где Вы устанавливаете делитель частоты? Константу вижу TC1_DIV_16384, а где она используется?
А где Вы устанавливаете делитель частоты? Константу вижу TC1_DIV_16384, а где она используется?
В строке, в которой я запускаю таймер. Она вне этой функции.
В строке, в которой я запускаю таймер. Она вне этой функции.
Вот именно поэтому, я терпеть не могу, когда выкладывают код не полностью.
Вот смотрите, я уже (1) скопировал Ваш код, (2) добавил к нему необходимый минимум, чтобы запустить, (3) запустил, посмотрел. Теперь я узнаю, что оказывается, это не полная конфигурация таймера, а есть ещё какая-то строка "вне этой функции". Простите, а что ещё у Вас там есть "вне этой функции"?
Вам не кажется, что многовато усилий для случайного совета незнакомому человеку?
Давайте так, если Вам нужна помощь, сделайте полный пример, демонстрирующий Вашу проблему. Полный, чтобы я мог его просто запустить не дописывая отсебятину и не догадываясь, что там есть ещё "вне этой функции". Тогда, я его посмотрю.
И, кстати, что во фьюзах? Какова частота F_CPU?
Вот именно поэтому, я терпеть не могу, когда выкладывают код не полностью.
Вот смотрите, я уже (1) скопировал Ваш код, (2) добавил к нему необходимый минимум, чтобы запустить, (3) запустил, посмотрел. Теперь я узнаю, что оказывается, это не полная конфигурация таймера, а есть ещё какая-то строка "вне этой функции". Простите, а что ещё у Вас там есть "вне этой функции"?
Да практически больше ничего, что касается таймера. Единственное, что еще есть это инверсия 3-го пина порта в прерывании. Вобщем суть такая... Я в протеусе собрал схемку для управления регистром HC595. При этом задержку сделал на встроенной в компилятор функции __delay_cycles(). Все заработало, как положено. После этого я решил сделать задержку по таймеру, чтоб не тупить в цикле, а заслать контроллер в слип и чтоб по прерыванию он просыпался и слал в HC595 нужный байт. Но прежде чем усыплять проц, я решил проверить работу таймера светодиодами паралельно с работой HC595. Навесил светодиоды на 3-й и 4-й пин порта. Где 3-й пин управляется из прерывания, а 4-й автоматом, таймером, по совпадению. И вот получается, что при симуляции HC595 работает правильно, а светодиоды от таймера работают с задержками порядка 4-х сек, а ожидалось, что они будут моргать с задержкой около 1 сек.
Не нужно нервничать... Я все таки новенький тут у вас...:) Просто я предполагал, что у меня затык именно в функции инициализации таймера.
Не вопрос... Вот весь код.
И, кстати, что во фьюзах? Какова частота F_CPU?
Фьюзы по умолчанию. Такт от внутреннего генератора через CLKDIV8. В итоге имеем 1МГц F_CPU.
Вот только поэтому я всё ещё здесь (а также потому, что я сегодня необычайно размякший (с бодуна, наверное)). Вы ставьте себя на место человека, который решил Вам помочь и никогда не создавайте ему лишних проблем. То, что Вы выложили нечто, что я не могу просто запустить – это проблема. То, что Вы потом вывалили код с нафиг не нужными потрохами от 595 – это проблема. Зачем? Если Вы хотите получить ответ на свой вопрос – сделайте специальный, короткий код, показывающий Ваш затык и именно его и выкладывайте.
Сейчас я приведу Вам код правильной инициализации таймера. Заодно считайте его учебным пособием по подготовке кода для вопроса на форуме – полный, работающий, и ничего лишнего, чтобы не пудрить людям мозги.
Смотрите, вот это нормально работает и в железе и в протеусе (у меня AVR-студия, потому инклюды немного другие)
Что здесь важно? В Errata к даташиту написано, что настройки COM1B1 нормально работают только если COM1A1 настроен точно также. Там же написано, что вроде они это уже исправили с какой-то версии чипа, но в протеусе именно так. В железе - как повезёт. Также важно, чтобы настройки делались, когда CTC1 уже установлен. Я выбросил Ваш сброс делителя, т.к. мы его и так уже сбросили, зачем лишние сущности?
Вот примерно такого размера код Вы и должны были выложить с Вашим вопросом. Проблема проявляется, ничего лишнего и можно запускать без доработок.
Смотрите, вот это нормально работает и в железе и в протеусе (у меня AVR-студия, потому инклюды немного другие)
Спасибо, все очень доходчиво.
Каюсь... В Errata я как-то и не додумался глянуть. Грешил тупо на протеус... А оно вон оно как... Оказывается модель в протеусе писалась с глючного камня со всеми глюками. :) Однако...
Поигрался я с этим CTC1... Скажем так, не совсем критично, чтобы он был сразу установлен. Но желательно. Если инициализацию делать при сброшенном CTC1, то при запуске таймера значение на выводе, контролируемом таймером аппаратно, будет инверсным, что несколько неожиданно, но в моем случае не критично. А если инициализацию делать при установленном CTC1, то все получается правильно и ожидаемо.
Вы наверное ошиблись. :) Сбросили мы только содержимое самого таймера, а вот предделитель - это отдельная песня. Потому для него даже отдельный бит организовали, чтоб его по нужде можно было дергать независимо.
Вобщем вариант с той же настройкой в COM1A0 меня не устроил, т.к. при этом жестко перекрывается еще один из выводов, аккурат задействованный для моей HC595. Тут либо надеятся, что железный камень окажется без глюков, либо дергать нужные ноги чисто в прерывании, либо менять камень. Я поменял модельку в протеусе на Tiny25 и все заработало даже с моим кодом(с оговоркой про CTC1). В конечном итоге остановился на таком варианте функции...
Вобщем вариант с той же настройкой в COM1A0 меня не устроил, т.к. при этом жестко перекрывается еще один из выводов, аккурат задействованный для моей HC595.
А может их можно просто поменять местами? Это "B" нельзя настроить на СТС/PWM без "А", а "А" без "В" отлично настраивается. Будет у Вас меандр на ноге PB1, а освободившийся PB4 используйте для 595
А может их можно просто поменять местами? Это "B" нельзя настроить на СТС/PWM без "А", а "А" без "В" отлично настраивается. Будет у Вас меандр на ноге PB1, а освободившийся PB4 используйте для 595
В принципе это тоже вариант. Однако я планировал использовать оба канала почти независимо, с отличающимися настройками. В этом случае все равно то на то и получится. Пока покумекаю над работой в прерываниях, чтоб не зависеть от аппаратных причуд, а там видно будет. Еще раз спасибо.