ISR(TIMER1_COMPB_vect) { PORTB &= ~(1<<2); // инвертировать состояние пин 2 port B *** TCCR1B=(0<<ICNC1) | (0<<ICES1) | (0<<WGM13) | (0<<WGM12) | (0<<CS12) | (0<<CS11) | (0<<CS10); // TIMSK1=(0<<ICIE1) | (0<<OCIE1B) | (0<<OCIE1A) | (0<<TOIE1); nterrupt_off(); triger = 0; }
Парни объясните в чем проблема, прерывание ISR(TIMER1_COMPA_vect) примерно раз в 0.4 сек обслуживает lcd. ISR(TIMER1_COMPB_vect) включает порт PORTB2 и выключает его через промежуток времени. Проблема в том что если OCR1A содержит число меньшее чем OCR1B то происходит обнуление TCNT1 и промежуток времени отсчитывается нормально, но если в момент вызова timer_COMPB_ON(); в OCR1A содержит число большее чем OCR1B то на PORTB2 возникает импульс примерно 3 миллисекунды, как я понимаю при вызове сразу происходит вызов прерывания как так получается вить флаг прерывания еще не установлен
в "угадайку" будем играть? 1. какой МК? 2. какая тактовая частота? 3. что такое "if(.....)" и когда оно срабатывает? 4. у тебя ISR(TIMER1_COMPB_vect) останавливает таймер. сколько времени проходит до "срабатывания" if(.....) ? 5. у тебя 27000 / 4500 = ровно 6. поэтому флаги обоих прерываний выставляются одновременно. но первым всегда выполняется прерывание по OCR1A. попробуй OCR1B сделать чуточку побольше, чтобы это прерывание гарантированно произошло позже, чем прерывание по OCR1A.
_________________ Мудрость приходит вместе с импотенцией... Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Качественное и безопасное устройство, работающее от аккумулятора, должно учитывать его физические и химические свойства, профили заряда и разряда, их изменение во времени и под влиянием различных условий, таких как температура и ток нагрузки. Мы расскажем о литий-ионных аккумуляторных батареях EVE и нескольких решениях от различных китайских компаний, рекомендуемых для разработок приложений с использованием этих АКБ. Представленные в статье китайские аналоги помогут заменить продукцию западных брендов с оптимизацией цены без потери качества.
Компания EVE выпустила новый аккумулятор серии PLM, сочетающий в себе высокую безопасность, длительный срок службы, широкий температурный диапазон и высокую токоотдачу даже при отрицательной температуре.
Эти аккумуляторы поддерживают заряд при температуре от -40/-20°С (сниженным значением тока), безопасны (не воспламеняются и не взрываются) при механическом повреждении (протыкание и сдавливание), устойчивы к вибрации. Они могут применяться как для автотранспорта (трекеры, маячки, сигнализация), так и для промышленных устройств мониторинга, IoT-устройств.
Я не понял вы спрашиваете или отвечаете? Так в том то и дело, что при заходе в timer_COMPB_ON(); происходит обнуление счетного регистра, инициализация регистров сравнения обоих и только после этого происходит разрешение прерывания регистра сравнения OCR1B.
МНДЯаа... Я-то привык САМ режимы задавать, какие захочу - ассемблер однако штука удобная... Си - потребует или библиотеку досконально изучить или свое написать. В этом плане (СИшные прожки) я пока не советчик...
Написал я значит код и честно сказать я в шоке, не могу понять как такое получается. В AVR Studio 4 код получился 400 bytes и он вообще работает не правильно, Arduino код занял 686 байт код работает но прежняя проблема осталась, при переполнении OCR1A более чем OCR1B прерывание по OCR1B не отрабатывает. ======= AVR Studio ====
//==================== int main(void) { DDRD = 0b00000000; // ddr D. PORTD = 0b11110111; // port D. DDRB = 0b00000110; // ddr B. PORTB = 0b11111001; // port B.
void setup() { DDRD = 0b00000000; //настраиваем выводы порта D. PORTD = 0b11110111; //записывае значение в порт D. DDRB = 0b00000110; //настраиваем выводы порта B. PORTB = 0b11111001; //записывае значение в порт B. }
Выкинуть из кода всякие if((PIND & (1<<0)) != 0), temp и т.д. Ваш алгоритм начнёт чётко спотыкаться на месте каждый раз. Прочитать про volatile В студии хороший симулятор. Запустить и прошагать по циклам и обработчикам прерываний с просмотром битов регистров. Я думаю, что вы недостаточно хорошо понимаете работу самого таймера.
Когда вы запускаете таймер timer_COMPA_ON(); значение OCR1B=0. Поэтому сразу выставляется флаг запроса OCF1B. Как только вы повторно запускаете таймер timer_COMPB_ON(); разрешается прерывание OCIE1B и сразу же отрабатывается ранее запрошенное событие OCF1B.
Я смотрел симуляцию и флаг прерывания по регистру OCR1B не выставляется сразу а вместе с флагом переполнения когда счетчик начнет считать по новой с нуля и это подтверждается моими опытами в протеусе. volatile - защита переменной от изменения. Это я так решаю проблему дребезга контакта без использования пауз и остановки выполнения кода микроконтроллером.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения