Форум РадиоКот https://radiokot.ru/forum/ |
|
Как работать с таймерами ATmega48PA на C/C++ ? https://radiokot.ru/forum/viewtopic.php?f=57&t=156178 |
Страница 2 из 2 |
Автор: | BOB51 [ Чт июл 19, 2018 08:44:10 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
Если делать качественный светодиодный индикатор двух прерываний вряд-ли хватит, тем более при том, что помимо индикации еще и задачи ввода/обработки делать необходимо. И ВСЕ на одном кристалле. Ежли вывести управление светодиодным табло на отдельную мелкосхемку с собственными мозгами - дело несколько упростится (то же касается индикаторов ЖКИ, имеющих свой контроллер). Однако чаще стараются "мелкий" проект в одну корпусину запихерить, а в таком случае без кучки прерываний "с выпендрежом" не обойтись. |
Автор: | Zat [ Чт июл 19, 2018 08:57:41 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
Сейчас нет. Потом, в процессе отладки или доработки понадобится второе, и приплыли. а если и потом не понадобится? я это все к тому, что надо все делать с умом. Делал я как-то ампервольтметр для своего ЛБП. Использовал два прерывания, АЦП и таймер, для индикации. Основной цикл пустой. Теперь вопрос: откуда тут могут взяться еще какие-то прерывания? Ну ты троль. Если, когда, зачем... просто делай сразу так ,чтобы потом не было мучительно больно за потраченное время на быдлокод. 500 мс задержки в прерывании - это вечность. |
Автор: | VladislavS [ Чт июл 19, 2018 10:22:12 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
Цитата: Встречаются два мужика в пустыне. Один тащит телефонную будку, второй рельсу. Тот что с рельсой спрашивает: - Нафига тебе телефонная будка? - Ну а вдруг на меня лев нападет?! Я в будку спрячусь, и он меня не съест! А ты зачем рельсу таскаешь? - А вдруг львы?! - И что? - Ну дак я рельсу брошу и налегке от них убегу! Кого-то мне чувак с рельсой напоминает. |
Автор: | ozonn [ Чт июл 19, 2018 11:33:53 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
есть правильный подход, который ВСЕГДА дает хороший реззультат, а есть подход, который дает результат ЕСЛИ. знать о таком подходе - плюс, а пользоваться им повседневно на регулярной основе - минус. я и не пользуюсь. Я просто не люблю усложнять на ровном месте |
Автор: | DENIS451 [ Пт июл 20, 2018 11:06:17 ] | ||
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? | ||
Теперь непонятные проблемы с таймером1 - ставлю такие настройки (внешний кварц 20мГц): Код: TCCR1B = 0; TCCR1A = 0; TCCR1B |= (1<<WGM12); // устанавливаем режим СТС (сброс по совпадению) для первого таймера // OCR1AH = 0xFF; //записываем в регистр число для сравнения - старшый байт // OCR1AL = 0x7F; //записываем в регистр число для сравнения - младший байт OCR1A = 4000; //записываем в регистр число для сравнения TCCR1B |= ( 1 << CS12 ) | ( 1 << CS10 );//устанавливаем предделитель на 1024 TIMSK1 |= (1<<OCIE1A); // Разрешить прерывание по совпадению OCR1A //TIMSK1 |= (1<<OCIE1B); // Разрешить прерывание по совпадению OCR1B //TIMSK1 |= (1<<TOIE1); // Разрешить прерывание по переполнению Канал B осциллографа в Протеусе подключён к ноге PC2, на которой в ISR (TIMER1_COMPA_vect )меняется высокий уровень на низкий, каждый полупериод меандра должен быть 205 милисек. = 1/(20000000/(4000*1024)) а он, почему то, то в 3 раза больше, то в 2 ! Почему так происходит?
|
Автор: | Ivanoff-iv [ Пт июл 20, 2018 12:55:02 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
может в прерывание входит не сразу (не разрешены по какой то причине, I, например нет), может в прерывании не сразу скидывает (код то не видно)... а поднимает ногу кто? Добавлено after 2 minutes 15 seconds: посмотрел видимую часть сигнала - сбрасывается он вроде регулярно (интервалы между спадающими фронтами равны), а вот поднятие идет както поразному... |
Автор: | DENIS451 [ Пт июл 20, 2018 14:02:27 ] | ||
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? | ||
Я выложил весь тестовый проект (Таймеры.zip) для Atmel studio 6.2, там же внутри проэкт для Proteus 8.7 Кстати, если закомментировать блок настроек относящиеся к таймеру0, то таймер1 перестаёт работать вообще (кажется это происходит после одного срабатывания) ! Почему так происходит? СпойлерКод: ///////////////////////////////////////////////////////////////// #define F_CPU 20000000L #include <avr/io.h> #include <Util/delay.h> #include <avr/interrupt.h> ///////////////////////////////////////////////////////////////// void timers_ini(void) { ///////////////////////////////////////////////////////////////////////// //====/Настройка таймера0/=================== TCCR0A = 0; TCCR0B = 0; TCCR0A |= (1<<WGM01); // Режим CTC (сброс по совпадению) //TCCR0B |= (1<<CS00); // Тактирование от CLK. // Если нужен предделитель : // TCCR0B = (1<<CS01); // CLK/8 // TCCR0B = (1<<CS00)|(1<<CS01); // CLK/64 // TCCR0B = (1<<CS02); // CLK/256 TCCR0B = (1<<CS00)|(1<<CS02); // CLK/1024 // Верхняя граница счета. Диапазон от 0 до 255. OCR0A = 255; // Частота прерываний A будет = Fclk/(N*(1+OCR0A)) OCR0B = 255; // Частота прерываний B будет = Fclk/(N*(1+OCR0B)) // где N - коэф. предделителя (1, 8, 64, 256 или 1024) TIMSK0 |= (1<<OCIE0A); // Разрешить прерывание по совпадению A //TIMSK0 |= (1<<OCIE0B); // Разрешить прерывание по совпадению B //TIMSK0 |= (1<<TOIE0); // Разрешить прерывание по переполнению //====/Настройка таймера1/=================== TCCR1B = 0; TCCR1A = 0; TCCR1B |= (1<<WGM12); // Режим CTC (сброс по совпадению) //TCCR1B |= (1<<CS10); // Тактирование от CLK. // Если нужен предделитель : // TCCR1B |= (1<<CS11); // CLK/8 // TCCR1B |= (1<<CS10)|(1<<CS11); // CLK/64 // TCCR1B |= (1<<CS12); // CLK/256 TCCR1B |= (1<<CS10)|(1<<CS12); // CLK/1024 // Верхняя граница счета. Диапазон от 0 до 65535. OCR1A = 2678; // Частота прерываний A будет = Fclk/(N*(1+OCR1A)) OCR1B = 2678; // Частота прерываний A будет = Fclk/(N*(1+OCR1B)) // где N - коэф. предделителя (1, 8, 64, 256 или 1024) TIMSK1 |= (1<<OCIE1A); // Разрешить прерывание по совпадению A //TIMSK1 |= (1<<OCIE1B); // Разрешить прерывание по совпадению B //TIMSK1 |= (1<<TOIE1); // Разрешить прерывание по переполнению //////////////////////////////////////////////////////////////////////////////////////////////////// } ISR (TIMER0_COMPA_vect) // вектор прерывания по совпадению таймера 0 { ///////////////////////////////////////////////////////////////// if ((PINC&0b00000001)) { PORTC &= ~(1<<0); //записать в PC0 ноль } else { PORTC |= (1<<0); //записать в PC0 единицу } //////////////////////////////////////////////////////////////////// } ISR (TIMER1_COMPA_vect ) { ///////////////////////////////////////////////////////////////////// if ((PINC&0b00000001)) { PORTC &= ~(1<<2); //записать в PC0 ноль } else { PORTC |= (1<<2); //записать в PC0 единицу } /////////////////////////////////////////////////////////////////// } int main(void) { //========================= DDRC |= (1<<0); //записать в PC0 единицу (что бы выставить его на выход) PORTC &= ~(1<<0); //записать в PC0 ноль DDRC &= ~(1<<1); PORTC |= (1<<1); DDRC |= (1<<2); //записать в PC2 единицу (что бы выставить его на выход) PORTC &= ~(1<<2);//записать в PC2 ноль timers_ini(); sei();//разрешить прерывания //========================= while(1) { if (false == (PINB&0b00000010)) { //_delay_ms(500); } } //======== }
|
Автор: | ARV [ Пт июл 20, 2018 14:12:52 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
что за хрень вы наворотили? что вы там пытаетесь сгенерировать? просто меандр генерируется без всяких прерываний чисто аппаратно в двух разных прерываниях от разных таймеров переключать один и тот же вывод и удивляться, что длительность странно меняется?! а вы чего ждали-то? |
Автор: | DENIS451 [ Пт июл 20, 2018 14:24:41 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
О точно, спасибо ARV, глаз замылился и я не вижу, что проверяю PC0 вместо того, что бы проверять PC2, в обработчике ISR (TIMER1_COMPA_vect )! |
Автор: | ARV [ Пт июл 20, 2018 14:34:06 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
DENIS451 писал(а): глаз замылился и я не вижу, что проверяю PC0 вместо того, что бы проверять PC2 чтобы не попадать в подобную ситуацию, крайне настоятельно рекомендую избавиться от магических чисел при помощи соответствующих макросов
|
Автор: | ozonn [ Пт июл 20, 2018 16:18:43 ] |
Заголовок сообщения: | Re: Как работать с таймерами ATmega48PA на C/C++ ? |
Ну ты троль. Если, когда, зачем... просто делай сразу так ,чтобы потом не было мучительно больно за потраченное время на быдлокод. 500 мс задержки в прерывании - это вечность. я сразу сделал "не так" и мне не больно, все работет. А у тебя я спросил, откуда в вольтметре возьмется еще одно прерыване. От сырости? Вы как роботы, сказали вам что в прерывании низзя и все тут. Нет шоп моск включить, хотя бы на мгновение |
Страница 2 из 2 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |