Форум РадиоКот https://radiokot.ru/forum/ |
|
Некоторые протоколы ИК-пультов. Часть первая https://radiokot.ru/forum/viewtopic.php?f=25&t=7170 |
Страница 1 из 1 |
Автор: | VladimirVladimirovitch [ Ср ноя 28, 2007 14:52:18 ] |
Заголовок сообщения: | Некоторые протоколы ИК-пультов. Часть первая |
Объясните плз. программу на http://www.radiokot.ru/articles/14/ interrupt [EXT_INT0] void ext_int0_isr(void) { TCNT0=0xFD; //запускаем таймер TCCR0=0x04; ??????????????????????????? if (tick >= 139 && tick < 150) //если случилось от 139 до 150 тиков { start_cond = 1; //фиксируем стартовое условие repeat_cond = 0; //обнуляем флаг повтора addr_1 = addr_0 = cmd_1 = cmd_0 = 0; //и ранее полученную команду и адрес } Я пометил знаком ? После запуска таймера в предыдущей строке ожидается инкремент переменной tick. Но вопрос - что раньше выполнется - отработка прерывания по таймеру (с соответственным инкрементом) или переход на следующую строку ( if (tick...) ? И почему? |
Автор: | Aheir [ Ср ноя 28, 2007 17:46:36 ] |
Заголовок сообщения: | |
Изначально Вы создали тему не на месте, для вопросов по статьям есть специальный раздел, где мы теперь находимся. Пожалуйста, внимательнее в следующий раз. По существу. Инкремент переменной осуществляется в теле прерывания таймера, а рассматриваемый Вами кусок кода относится к внешнему прерыванию. В АВРах "прервать прерывание" нельзя, т.е. прерывание от таймера получит шанс состояться только после завершения кода тела внешнего прерывания. |
Автор: | VladimirVladimirovitch [ Чт ноя 29, 2007 10:23:32 ] |
Заголовок сообщения: | |
Цитата: Пожалуйста, внимательнее в следующий раз. Хорошо Цитата: В АВРах "прервать прерывание" нельзя, т.е. прерывание от таймера получит шанс состояться только после завершения кода тела внешнего прерывания.
Спасибо. С программой разобрался. |
Автор: | Aheir [ Чт ноя 29, 2007 10:31:58 ] |
Заголовок сообщения: | |
Да не за что. ![]() |
Автор: | Vytih [ Пт авг 14, 2015 12:07:48 ] |
Заголовок сообщения: | Re: Некоторые протоколы ИК-пультов. Часть первая |
Помогите не опытному. Имеется Мега 8, китайский пульт, приёмник VS 1838B и двухстрочный символьный дисплей на HD44780. Пульт работает по протоколу nec (выяснил по осциллограмме). Atmega 8 тактируется от внутреннего генератора 8 МГц. Взял кусок кода из этой статьи отвечающий за дешифровку сигнала и попытался вывести код кнопки на дисплей. На дисплее отображается ноль на нажатие кнопок пульта не реагирует. Пытался слепить всё в CodeVisionAVR V2.05.3. СпойлерКод: #include <mega8.h> #include <delay.h> #include <alcd.h> #include <stdio.h> unsigned int tick = 0; //счетчик тиков таймера unsigned char b_cnt = 0; //счетчик принятых бит bit start_cond = 0; //флаг стартового условия bit repeat_cond = 0; //флаг повтора unsigned char addr_1 = 0; //прямой байт адреса unsigned char addr_0 = 0; //инверсный байт адреса unsigned char cmd_1 = 0; //прямой байт команды unsigned char cmd_0 = 0; //инверсный байт команды unsigned char addr = 0; //байт адреса unsigned char cmd = 0; //байт команды unsigned char text[17]; interrupt [EXT_INT0] void ext_int0_isr(void) { TCNT0=0xFD; //запускаем таймер TCCR0=0x04; if (tick >= 139 && tick < 150) //если случилось от 139 до 150 тиков { start_cond = 1; //фиксируем стартовое условие repeat_cond = 0; //обнуляем флаг повтора addr_1 = addr_0 = cmd_1 = cmd_0 = 0; //и ранее полученную команду и адрес } if (tick >= 116 && tick < 139) //если случилось от 116 до 138 тиков { repeat_cond = 1; //фиксируем флаг повтора start_cond = 0; //обнуляем флаг стартового условия TCNT0=0x00; } if (tick >= 22 && tick < 116 && start_cond) //если случилось от 22 до 115 тиков { ++b_cnt; //приняли "1" и увеличили счетчик битов if (b_cnt < 9) addr_1 = (addr_1 << 1) + 1; //первый байт - прямой адрес if (b_cnt >= 9 && b_cnt < 17) addr_0 = (addr_0 << 1) + 1; //второй байт - инверсный адрес if (b_cnt >= 16 && b_cnt < 25) cmd_1 = (cmd_1 << 1) + 1; //третий байт - прямая команда if (b_cnt >= 24) cmd_0 = (cmd_0 << 1) + 1; //четвертый байт - инверсная команда } if (tick >= 10 && tick < 22 && start_cond) //если случилось от 10 до 21 тика { ++b_cnt; //приняли "0" и увеличили счетчик битов if (b_cnt < 9) addr_1 = (addr_1 << 1); //далее - аналогично по байтам if (b_cnt >= 9 && b_cnt < 17) addr_0 = (addr_0 << 1); if (b_cnt >= 16 && b_cnt < 25) cmd_1 = (cmd_1 << 1); if (b_cnt >= 24) cmd_0 = (cmd_0 << 1); } tick = 0; //обнулили тики if (b_cnt == 32) //если приняли уже 4 байта { if ((addr_1+addr_0) == 0xFF) addr = addr_0; //закомментировано, потому как в пульте First else addr = 0; //16-bit адрес 0x6120, т.о. проверка адреса не проходит if ((cmd_1 + cmd_0) == 0xFF) cmd = cmd_1; //проверили правильность приема команды else cmd = 0; b_cnt = 0; //обнулили счетчик битов start_cond = 0; //сбросили стартовое условие repeat_cond = 0; TCCR0=0x00; //остановили таймер TCNT0=0x00; } } // Timer 0 overflow interrupt service routine interrupt [TIM0_OVF] void timer0_ovf_isr(void) { TCNT0=0xFD; //переинициализировали таймер - отсчитывает 96мкс if (++tick > 1200) //если насчитали более 1200 тиков { TCCR0=0x00; //сбросили все к исходному состоянию TCNT0=0x00; tick = 0; start_cond = 0; repeat_cond = 0; addr_1 = addr_0 = cmd = 0; } } void main(void) { // Declare your local variables here // Input/Output Ports initialization // Port B initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTB=0x00; DDRB=0x00; // Port C initialization // Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTC=0x00; DDRC=0x00; // Port D initialization // Func7=In Func6=In Func5=In Func4=In Func3=In Func2=In Func1=In Func0=In // State7=T State6=T State5=T State4=T State3=T State2=T State1=T State0=T PORTD=0x00; DDRD=0x00; // Timer/Counter 0 initialization // Clock source: System Clock // Clock value: Timer 0 Stopped TCCR0=0x00; TCNT0=0x00; // Timer/Counter 1 initialization // Clock source: System Clock // Clock value: Timer1 Stopped // Mode: Normal top=0xFFFF // OC1A output: Discon. // OC1B output: Discon. // Noise Canceler: Off // Input Capture on Falling Edge // Timer1 Overflow Interrupt: Off // Input Capture Interrupt: Off // Compare A Match Interrupt: Off // Compare B Match Interrupt: Off TCCR1A=0x00; TCCR1B=0x00; TCNT1H=0x00; TCNT1L=0x00; ICR1H=0x00; ICR1L=0x00; OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x00; OCR1BL=0x00; // Timer/Counter 2 initialization // Clock source: System Clock // Clock value: Timer2 Stopped // Mode: Normal top=0xFF // OC2 output: Disconnected ASSR=0x00; TCCR2=0x00; TCNT2=0x00; OCR2=0x00; // External Interrupt(s) initialization // INT0: Off // INT1: Off GICR|=0x40; MCUCR=0x02; GIFR=0x40; // Timer(s)/Counter(s) Interrupt(s) initialization TIMSK=0x00; // USART initialization // USART disabled UCSRB=0x00; // Analog Comparator initialization // Analog Comparator: Off // Analog Comparator Input Capture by Timer/Counter 1: Off ACSR=0x80; SFIOR=0x00; // ADC initialization // ADC disabled ADCSRA=0x00; // SPI initialization // SPI disabled SPCR=0x00; // TWI initialization // TWI disabled TWCR=0x00; // Alphanumeric LCD initialization // Connections are specified in the // Project|Configure|C Compiler|Libraries|Alphanumeric LCD menu: // RS - PORTB Bit 0 // RD - PORTB Bit 1 // EN - PORTB Bit 2 // D4 - PORTB Bit 4 // D5 - PORTB Bit 5 // D6 - PORTB Bit 6 // D7 - PORTB Bit 7 // Characters/line: 16 lcd_init(16); #asm("sei") while (1) { sprintf (text, "%X", cmd); lcd_gotoxy(0,0); lcd_puts (text); } } |
Страница 1 из 1 | Часовой пояс: UTC + 3 часа |
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |