Запрограммировал Atmega8 на регулирование скважности используя два прерывания 1 по старту от PD2 и 2 от таймера Т2 . скважность меняется от 0 до 255 и обратно до 0. И еще меряет напряжение на PC0 и PC1 и отображает на 1602. Проблема в том идут сбои вместо плавного изменения скважности сигнал сжимается или расширяется вдруг сплошная линия потом восстанавливается и так 5 или 6 раз. Думал протеус не справляется запрограммировал Atmega8 в живую тоже самое. Что не так протеусе пробовал Atmega16 тоже самое.
Может я слишком многого от этой серии хочу? Подскажите.
В вопросе практически отсутствует информация, оперившись на которую можно было бы что-то подсказать. Самый лучший вариант - скачайте даташит именно на ваш MCU. И очень-очень внимательно посмотрите что именно вы записываете в регистры конфигурации таймеров. Поймите, что именно означает каждый бит и какие сочетания битов регистра на что влияют.
Добавлено after 45 seconds: Две самые частые ошибки в таймерах - использование кода от другого MCU и банальная невнимательность.
void init_interrupt(char YROVEN) // настройка прерывания { GICR|=(1<<INT0); // включаем прерывания MCUCR|=((YROVEN & 1)<<ISC00)|((YROVEN >>1 & 1)<<ISC01);//устанавливаем тип срабатывания // 1-Любое изменение уровня на выводе INT0, 2-Нисходящий фронт сигнала (смена 1 на 0) на выводе INT0 //3-Восходящий фронт сигнала (смена 0 на 1) на выводе INT0, 0- Нижний уровень на выводе INT0 } void int_StopTimerT2(void) { TCCR2 = 0b00000000; }
{ TCNT2 = 0x00;//обнуляем счетчик таймера Т2 TCCR2 = 0x00; // Сброс регистра конфигурации таймера Т2 TCCR2|=((delitel >>2 & 1)<<CS22)|((delitel >>1 & 1)<<CS21)|((delitel & 1)<<CS20) // Установка делителя: 0-Источника тактирования нет таймер остановлен, // 1-Тактовая частота МК, 2-Тактовая частота МК/8, 3-тактовая частота МК/32, // 4-Тактовая частота МК/64, 5-Тактовая частота МК/128, 6-Тактовая частота МК/256, // 7-Тактовая частота МК/1024. |((rejim_taim >>1 & 1)<<WGM21)|((rejim_taim & 1)<<WGM20)//Режим работы таймера/счётчика // 0-Нормальный режим счётчика, 1-ШИМ с коррекцией фазы, //2- Сброс таймера при совпадении регистров OCR2 и TCNT2 (CTC) и 3-Быстрая ШИМ (Fast PWM). |((rejim_OC2 >>1 & 1)<<COM21)|((rejim_OC2 & 1)<<COM20) // Режим работы вывода OC2: 0-Вывод ОС2 отключён от таймера/счётчика, //1- Состояние вывода меняется на противоположное при совпадении TCNT2 и OCR2 //(только в режимах Normal и CTC) //2-На OC2 устанавливается "0" при совпадении TCNT2 и OCR2 // и устанавливается "1" при сбросе счётчика, //3-На OC2 устанавливается "1" при совпадении TCNT2 и OCR2 //и устанавливается "0" при сбросе счётчика. |((rejim_foc2 & 1)<<FOC2);//устанавливаем тип срабатывания // предназначен для принудительной установки логического уровня на выходе OC2. // Он работает только для режимов Normal и CTC. При установке бита FOC2 в единицу //состояние выхода меняется в соответствии со значениями битов COM21 и COM20. } void int_RazPrerT2(char Kakoe)//разрешения прерываний { TIMSK &=0b00111111;// сброс прерываний таймера Т2 TIMSK|=((Kakoe >>1 & 1)<<OCIE2)|((Kakoe & 1)<<TOIE2); //0-Все прерывания запрещены, 1-Разрешает прерывание по событию переполнение, //2-Разрешает прерывание по событию совпадение, 3-Разрешает прерывания по обоим событиям // sei();// Разрешение работу прерываниям }
void int_pcb(void) { DDRD = 0b11110011;//PD0 PD1 PD4 PD5 PD6 PD7 — настраиваем ножки на выход PD2 PD3 - Вход PORTD = 0b00001100;//РD2 PD3 — подключаем подтягивающие резисторы DDRC = 0b00110000; // Конфигурируем вывод порта PC0-PC3 как вход и PC4 PC5 как выход }
ISR(INT0_vect)// прерывание по ножке PD2 { PORTC &= ~(1 << PC4);// Устанавливаем 0 на его выходе на линии 4 порта C _delay_ms(0.6); int_TimerT2(6,2,0,0);//запукаем таймер Т2 OCR2 -=1;
}
ISR (TIMER2_COMP_vect) // Если произошло прерывание по совпадению таймера Т2 {
if(OCR2 <1) { PORTC &= ~(1 << PC4);// Устанавливаем 0 на его выходе на линии 4 порта C } else { PORTC |=_BV (PC4); //Устанавливаем 1 на выходе PC4 } }
int main(void) { int_pcb(); //Настройка портов sei();// Разрешение работу прерываниям init_interrupt(3); // Включение прерывания по входу PD2 int_RazPrerT2(2);//разрешения прерываний от таймера Т2
Ну ладно, таймерТ2 я как то не досмотрел (старческий невнимательность)... Обычно до него без особой надобности не доходило... Но сама постановка задачи чей то никак не соображаю - автор измерять скважность по прерываниям собирался или чего там вылавливать то?... Или регулировать выходной ШИМ сигнал в соответствии с напряжением, снимаемым с переменного резистора? Или еще какой задачей озаботился, но сформулировать не сумел? Скорее всего от такого подхода и хаос результата... Глянул повнимательнее в исходник... Это "тонкий троллинг" автора или .... ?? как сие компилятор без матюков вообще пропустить смог? или в СИ допускается разрыв строки на несколько автономных кусков через пакеты однострочных комментариев?
Я в СИ начинающий (и то из-под адурино) - может чего таки не понимаю... Да и атмеги 8е несколько не мои базовые (детально не разбирались), могу чего и упустить...
ISR(INT0_vect)// прерывание по ножке PD2 { PORTC &= ~(1 << PC4);// Устанавливаем 0 на его выходе на линии 4 порта C _delay_ms(0.6); int_TimerT2(6,2,0,0);//запукаем таймер Т2 OCR2 -=1;
}
даже если убрать задержку (внутри обработчика прерывания оная!!!)... на кой ... делать в каждом прерывании инициализацию режимов таймера то? При том,что в начале ее вообще нет ( да и с разрешением/запретом прерываний бардак - обычно их сначала запретить надо, а уж после всякоманипуляций разрешать) Спойлер
Код:
int main(void) { int_pcb(); //Настройка портов sei();// Разрешение работу прерываниям init_interrupt(3); // Включение прерывания по входу PD2 int_RazPrerT2(2);//разрешения прерываний от таймера Т2
while(1)
........... Сначала хотя бы схему да грамотное словесное описание задачи надо изложить. Тогда возможно чего реально и самому вопрошающему прояснится.
Схема большая меряет два напряжения на PC0 PC1 высвечивает их на ЛСД 1602 в зависимости от PC0 выставляет значение OCR2 для таймера Т2 и включает PC4 и запуск таймера по входу PD2. Так вот значение OCR2 меняется от 255 до 0 с дискретностью 1. Проблема была в плавности изменения на PC4 хотя значение OCR2 меняется плавно а на PC4 скачки. На другом форуме подсказали задержку _delay_ms(0.6); нельзя ставить проверил точно мешает а она мне нужна. через FOR попробовал задержать скачки возобновились.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения