<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=46&amp;t=21384&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2018-10-19T22:28:16+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=46&amp;t=21384&amp;mode</id>
<entry>
<author><name><![CDATA[mikandrzej]]></name></author>
<updated>2018-10-19T22:28:16+01:00</updated>
<published>2018-10-19T22:28:16+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212797#p212797</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212797#p212797"/>
<title type="html"><![CDATA[Re: [STM32F103 ][STD] Sterowanie Pilotem Biblioteka Nec]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212797#p212797"><![CDATA[
Napisz ją sam <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br />Wystarczy użyć przerwania sprzętowego oraz jednego z TIMERów <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br />Ja robię to tak:<br />1. W przerwaniu wyzwalanym na zboczu opadającym odczytuję z TIMERa czas jaki minął od ostatniego przerwania. Licznik tyka co 0,1ms.<br />2. pierwszy impuls powinien trwać 155 tyknięć (wartość +/- ustawiłem na 3 tyknięcia [0,3ms])<br />   jeśli jest poprawny, to zwiększam licznik poprawnych bitów, jeśli nie, to zeruję licznik i znów czekam na impuls przynajmniej 155 tk<br />3. kolejne impulsy to:<br />a) 12 tyknięć (+/- 3tk) - logiczne 0<br />b) 22 tyknięcia (+/- 3tk) - logiczne 1<br />4. Z każdym tyknięciem inkrementuję licznik i w przypadku logicznej jedynki, ustawiam odpowiedni bit w 32 bitowej zmiennej<br />5. Jeśli cała ramka zostanie odebrana poprawnie, to wywołuję zarejestrowaną funkcję. Jeśli nie, zeruję licznik i czekam na impuls startowy.<br /><br />Z każdym przerwaniem zeruję timer. Należy zawrzeć w programie możliwość wystąpienia impulsu startu nawet w trakcie liczenia bitów, w razie gdyby w trakcie transmisji coś zawiodło ( w praktyce często tak jest) - czyli za każdym razem jak przyjdzie impuls 155 tk należy przerwać odbiór, wyzerować licznik i czekać na kolejne dane.<br /><br />Kod tak naprawde na kilka linijek <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> Dodatkowo trzeba jeszcze opanować przytrzymywanie przycisku - ja tego nie robiłem, ale z analizatorem stanów nie powinien to być problem.<br /><br />Powodzenia <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /><br /><br />btw. polecam stronę:<br /><a href="https://exploreembedded.com/wiki/NEC_IR_Remote_Control_Interface_with_8051"  class="postlink">https://exploreembedded.com/wiki/NEC_IR_Remote_Control_Interface_with_8051</a><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=431">mikandrzej</a> — 19 paź 2018, o 22:28</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[danny]]></name></author>
<updated>2018-10-07T14:19:14+01:00</updated>
<published>2018-10-07T14:19:14+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212389#p212389</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212389#p212389"/>
<title type="html"><![CDATA[Re: [STM32F103 ][STD] Sterowanie Pilotem Biblioteka Nec]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212389#p212389"><![CDATA[
Do zrobienia jest obsługa dłużej przytrzymywanego przycisku.<br /><br />    Oryginał pochodzi ze strony firmy Lispol, przy okazji oferty sprzedaży pilota NEC.<br />  <br />    W miejscach gdzie ingerowałem w kod, oryginalna częśc jest zakomentowana.<br />  <br />    Dodałem callbacki i wydaje mi się, że w oryginale był błąd:<br />    Standard NEC mówi, że bity address i command są ustawione tak, że bit najmłodszy LSB powinien<br />    być po lewej stronie, najstarszy po prawej. Źródło:<br />  <br />    <!-- m --><a class="postlink" href="http://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol" >http://techdocs.altium.com/display/FPGA ... n+Protocol</a><!-- m --><br />  <br />    Tak więc ramkę z załącznika powinien odczytywać: address 0x04; command 0x72<br />  <br />    Natomiast odczytywana była jako: address 0x20, command 0x4E<br /><br /><br />nec.h<br />[syntax=c]#ifndef NEC_H<br />#define NEC_H<br /><br />//długości &#91;ms&#93;:<br />// http://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol<br /><br />#define HEADER13.5//9ms + 4,5ms przerwa<br />#define ZERO1.125//562,5us + 562,5us przerwa<br />#define ONE2.25//562,5us + 1,6875ms przerwa<br />#define REPEAT11.25//co 108ms 9ms + 2.25ms<br />#define OFFSET0.4<br /><br /><br />#define F_STARTF_CPU/8000*HEADER<br />#define F_ONEF_CPU/8000*ONE<br />#define F_ZEROF_CPU/8000*ZERO<br />#define F_REPEATF_CPU/8000*REPEAT<br />#define F_OFFSETF_CPU/8000*OFFSET<br /><br />//Atmega32<br /><br />#define IR_PIN PD6// numer pinu wejścia ICP<br />#define IR_DIR DDRD<br />#define IR_PORT PORTD<br /><br /><br />//kody pilota<br /><br />#define LG_ADDRESS0x04<br /><br />#define STOP0xB1<br />#define RWD0x8F<br />#define PLAY0xB0<br />#define FF0x8E<br />#define PAUSE0xBA<br />#define RED0x72<br />#define GREEN0x71<br />#define YELLOW0x63<br />#define BLUE0x61<br /><br />//#define REC0xBD<br />//#define AVMODE0x30<br />//#define EXIT0x5B<br />//#define BACK0x28<br />//#define OK0x44<br />//#define QMENU0x45<br />//#define SETTINGS0x43<br />//#define TEXT0x20<br />//#define INFO0xAA<br />//#define TOPT0x21<br />//#define MUTE0x09<br />//#define GUIDE0xAB<br />//#define FAV0x1E<br />//#define VOL+0x02<br />//#define VOL-0x03<br />//#define P+0x00<br />//#define P-0x01<br />//#define LIST0x53<br />//#define QVIEW0x1A<br />//#define 00x10<br />//#define 10x11<br />//#define 20x12<br />//#define 30x13<br />//#define 40x14<br />//#define 50x15<br />//#define 60x16<br />//#define 70x17<br />//#define 80x18<br />//#define 90x19<br />//#define SUBTITLE0x39<br />//#define AD0x91<br />//#define RATIO0x79<br />//#define INPUT0x0B<br />//#define TV-RADIO0xF0<br />//#define ON-OFF0x08<br /><br /><br />void ir_init();<br /><br />void NEC_IR_EVENT(void);<br /><br />void register_NEC_ir_event_callback(void (*callback)(uint8_t address,<br />uint8_t command));<br />#endif[/syntax]<br /><br /><br />nec.c<br />[syntax=c]/*<br /> *  Oryginał pochodzi ze strony firmy Lispol, przy okazji oferty sprzedaży pilota NEC.<br /> *<br /> *  W miejscach gdzie ingerowałem w kod, oryginalna częśc jest zakomentowana.<br /> *<br /> *  Dodałem callbacki i wydaje mi się, że w oryginale był błąd:<br /> *  Standard NEC mówi, że bity address i command są ustawione tak, że bit najmłodszy LSB powinien<br /> *  być po lewej stronie, najstarszy po prawej. Źródło:<br /> *<br /> *  http://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol<br /> *<br /> *  Tak więc ramkę z załącznika powinien odczytywać: address 0x04; command 0x72<br /> *<br /> *  Natomiast odczytywana była jako: address 0x20, command 0x4E<br /> *<br /> */<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br /><br />#include &quot;nec.h&quot;<br /><br />//volatile uint8_t frame_ready;<br /><br />volatile uint8_t address;<br />volatile uint8_t command;<br />volatile uint8_t key_flag;<br /><br />static void (*NEC_ir_event_callback)(uint8_t address, uint8_t command);<br /><br />void register_NEC_ir_event_callback(<br />void (*callback)(uint8_t address, uint8_t command)) {<br />NEC_ir_event_callback = callback;<br />}<br /><br />void NEC_IR_EVENT(void) {<br /><br />if (key_flag) {<br /><br />if (NEC_ir_event_callback)<br />(*NEC_ir_event_callback)(address, command);<br /><br />address = 0xff;<br />command = 0xff;<br />key_flag = 0;<br />}<br />}<br /><br />void ir_init(void) {<br />//DDRD &amp;=~(1&lt;&lt;PD6);<br />IR_PORT |= (1 &lt;&lt; IR_PIN); /* podciągnięcie wejścia IR */<br />// KONFIGURACJA PRACY PRZERWANIA ICP I TIMERA1<br /><br />TCCR1B |= (1 &lt;&lt; CS11); /* prescaler = 8 */<br />//     TCCR1B &amp;= ~(1&lt;&lt;ICES1);  /* falling edge */<br />TIMSK |= (1 &lt;&lt; TICIE1); /* enable interrupt */<br />}<br /><br />ISR(TIMER1_CAPT_vect) {<br />static uint32_t temp_frame;<br />static uint16_t last_icr;<br />uint16_t width;<br />//        static uint8_t frame_idx = 33;<br />static uint8_t frame_idx = 0;<br /><br />uint8_t bit = 2;<br /><br />width = ICR1 - last_icr;<br />last_icr = ICR1;<br /><br />if (!frame_idx &amp;&amp; width &gt; F_START - F_OFFSET &amp;&amp; width &lt; F_START + F_OFFSET)//frame_idx == 33<br />// &gt; 27000 - 800 = 26200 i &lt; 27800<br />{<br />//            frame_idx--;<br /><br />frame_idx++;<br />}<br /><br />//if(frame_idx &lt; 32)<br />if (frame_idx &gt; 1)<br /><br />{<br /><br />if (width &gt; F_ONE - F_OFFSET &amp;&amp; width &lt; F_ONE + F_OFFSET)<br />bit = 1;<br />// &gt; 3700 i &lt; 5300<br />if (width &gt; F_ZERO - F_OFFSET &amp;&amp; width &lt; F_ZERO + F_OFFSET)<br />bit = 0;<br />// &gt; 2250 - 800 = 900 i &lt; 3050<br /><br />if (bit != 2) {<br />temp_frame |= (uint32_t) bit &lt;&lt; (frame_idx - 2);//frame_idx;<br /><br />//if(frame_idx == 0)<br />if (frame_idx == 33)<br /><br />{<br />//                                address = (uint8_t)(temp_frame &gt;&gt; 24);<br />address = (uint8_t) (temp_frame);<br /><br />//                                command = (uint8_t)(temp_frame &gt;&gt; 8);<br />command = (uint8_t) (temp_frame &gt;&gt; 16);<br /><br />temp_frame = 0;<br />//                                frame_idx = 33;<br />frame_idx = 0;<br /><br />//                                frame_ready = 1;<br /><br />key_flag = 1;<br />} else {<br />//                                frame_idx--;<br />frame_idx++;<br /><br />}<br />} else {<br />//                        frame_idx = 33;<br />frame_idx = 0;<br /><br />}<br />}<br /><br />//if(frame_idx == 32) frame_idx--;<br />if (frame_idx == 1)<br />frame_idx++;<br />}[/syntax]<br /><br />main.c<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;util/delay.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br /><br />#include &quot;IR_NEC/nec.h&quot;<br />#include &quot;KS108/gLCD.h&quot;<br /><br />void moja_obsluga_ir(uint8_t address, uint8_t command);<br /><br />/* ***************** główna funckja programu ******************* */<br />int main(void) {<br /><br />gLCD_switchon();<br />gLCD_cls();<br /><br />gLCD_locate(25, 40);<br />printf_P(PSTR(&quot;Tester pilota&quot;));<br /><br />ir_init();<br /><br />register_NEC_ir_event_callback(moja_obsluga_ir);<br /><br />sei();<br /><br />while (1) {<br />NEC_IR_EVENT();<br />/*<br /><br /> if (frame_ready) {<br /><br /> gLCD_locate(0, 10);<br /> printf_P(PSTR(&quot;Adres: %02X&quot;), address);<br /> gLCD_locate(0, 20);<br /> printf_P(PSTR(&quot;Przycisk: %02X&quot;), command);<br /><br /> frame_ready = 0;<br /> command = 0xff;<br /> address = 0xff;<br /> }<br /> */<br /><br />}<br />}<br /><br />void moja_obsluga_ir(uint8_t address, uint8_t command) {<br /><br />if (LG_ADDRESS == address) {<br /><br />switch (command) {<br /><br />case (FF): {<br />gLCD_locate(0, 50);<br />printf_P(PSTR(&quot;&gt;&gt;     &quot;));<br />}<br />break;<br /><br />case (RWD): {<br />gLCD_locate(0, 50);<br />printf_P(PSTR(&quot;&lt;&lt;     &quot;));<br />}<br />break;<br /><br />case (RED): {<br />gLCD_locate(0, 50);<br />printf_P(PSTR(&quot;CZERWONY&quot;));<br />}<br />break;<br /><br />case (GREEN): {<br />gLCD_locate(0, 50);<br />printf_P(PSTR(&quot;ZIELONY&quot;));<br />}<br />break;<br /><br />}<br />}<br /><br />gLCD_locate(0, 0);<br />printf_P(PSTR(&quot;Kodowanie: NEC&quot;));<br />gLCD_locate(0, 10);<br />printf_P(PSTR(&quot;Adres: 0x%02X&quot;), address);<br />gLCD_locate(0, 20);<br />printf_P(PSTR(&quot;Przycisk: 0x%02X&quot;), command);<br /><br />/*command = 0xff;<br /> address = 0xff;*/<br />}[/syntax]<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1505">danny</a> — 7 paź 2018, o 14:19</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[NeverGiveUp]]></name></author>
<updated>2018-10-07T13:41:01+01:00</updated>
<published>2018-10-07T13:41:01+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212388#p212388</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212388#p212388"/>
<title type="html"><![CDATA[[STM32F103 ][STD] Sterowanie Pilotem Biblioteka Nec]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=21384&amp;p=212388#p212388"><![CDATA[
Witem znalazłem bibliotekę nec która za bardzo nie chcę działać próbuję uruchomi i coś mi to nie wychodzi potrzebował bym pomocy w uruchomieniu tej biblioteki albo napisaniu nowej dla pilota jak na zdjęciu <br /><br />main.c <br /><br />[syntax=c]#include &lt;stm32f10x_tim.h&gt;<br />#include &lt;misc.h&gt;<br />#include &lt;stdio.h&gt;<br /><br /><br />#include &quot;ir.h&quot;<br /><br />#define DELAY 10<br /><br />void LED_Init() {<br />/* Enable GPIO clock */<br />RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);<br /><br />// Use PC8 and PC9 // Discovery LEDs<br />GPIO_InitTypeDef GPIO_InitStructure;<br /><br />GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;<br />GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;<br />GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9;<br />GPIO_Init(GPIOC, &amp;GPIO_InitStructure);<br /><br />}<br /><br />void IR_Init() {<br />/* Enable GPIO clock */<br />RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);<br /><br />// Use PC6 as input from IR receiver<br />GPIO_InitTypeDef GPIO_InitStructure;<br /><br />GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;<br />GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;<br />GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;<br />GPIO_Init(GPIOB, &amp;GPIO_InitStructure);<br /><br />// Enable clock and its interrupts<br />RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);<br /><br />GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource6);<br /><br />    NVIC_InitTypeDef NVIC_InitStructure;<br />    NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;<br />    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;<br />    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;<br />    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;<br />    NVIC_Init(&amp;NVIC_InitStructure);<br /><br />EXTI_InitTypeDef EXTI_InitStructure;<br />    EXTI_InitStructure.EXTI_Line = EXTI_Line6;<br />    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;<br />    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;<br />    EXTI_InitStructure.EXTI_LineCmd = ENABLE;<br />    EXTI_Init(&amp;EXTI_InitStructure);<br /><br /><br />}<br /><br />void TIM_Init() {<br />// Enable clock and its interrupts<br />RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);<br /><br />    NVIC_InitTypeDef NVIC_InitStructure;<br />    NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;<br />    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;<br />    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;<br />    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;<br />    NVIC_Init(&amp;NVIC_InitStructure);<br /><br />TIM_TimeBaseInitTypeDef TIM_InitStructure;<br /><br />RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);<br />TIM_InitStructure.TIM_CounterMode = TIM_CounterMode_Up;<br />TIM_InitStructure.TIM_Prescaler = 24 - 1;<br />TIM_InitStructure.TIM_Period = 10000 - 1; // Update event every 10000 us / 10 ms<br />TIM_InitStructure.TIM_ClockDivision = TIM_CKD_DIV1;<br />TIM_InitStructure.TIM_RepetitionCounter = 0;<br />TIM_TimeBaseInit(TIM2, &amp;TIM_InitStructure);<br />TIM_ITConfig(TIM2, TIM_IT_Update, ENABLE);<br />TIM_Cmd(TIM2, ENABLE);<br />}<br /><br />int main(void)<br />{<br />LED_Init();<br />IR_Init();<br />TIM_Init();<br /><br />ir_nec_init(GPIO_Pin_6, GPIOB);<br /><br /><br /><br />    while(1)<br />    {<br />    }<br />}<br /><br />void TIM2_IRQHandler()<br />{<br />    if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)<br />    {<br />        TIM_ClearITPendingBit(TIM2, TIM_IT_Update);<br />        // Timeout<br />        ir_nec_reset_transmission();<br />    }<br />}<br /><br />void EXTI9_5_IRQHandler(void)<br />{<br />    static unsigned int counter;<br /><br />    if (EXTI_GetITStatus(EXTI_Line6) != RESET)<br />    {<br />        u8 bit = GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_6);<br />        if (bit) {<br />        GPIO_ResetBits(GPIOC, GPIO_Pin_9);<br />        } else {<br />        GPIO_SetBits(GPIOC, GPIO_Pin_9);<br />        }<br /><br />        // Restart Timer<br />        counter = TIM_GetCounter(TIM2);<br />        TIM_SetCounter(TIM2, 0);<br />        ir_nec_state_machine(counter);<br /><br />        EXTI_ClearITPendingBit(EXTI_Line6);<br />    }<br />}[/syntax]<br /><br />ir.c<br />[syntax=c]#include &quot;ir.h&quot;<br /><br />u16 pin;<br />GPIO_TypeDef *gpio;<br />ir_nec_state ir_nec_current_state;<br />u8 cnt = 0;<br /><br />unsigned int data, prev_data;<br />u16 ir_nec_pulse_lengths&#91;6&#93;;<br />bool ir_nec_repeat_last_command = false;<br /><br />void ir_nec_init(u16 p, GPIO_TypeDef *g) {<br />pin = p;<br />gpio = g;<br />ir_nec_current_state = IR_NEC_NONE;<br /><br />ir_nec_pulse_lengths&#91;IR_NEC_NONE&#93; = 0;<br />ir_nec_pulse_lengths&#91;IR_NEC_FIRST_BURST&#93; = 9000;<br />ir_nec_pulse_lengths&#91;IR_NEC_SECOND_BURST&#93; = 4500;<br />ir_nec_pulse_lengths&#91;IR_NEC_1&#93; = 560;<br />ir_nec_pulse_lengths&#91;IR_NEC_NDEF&#93; = 1;<br />ir_nec_pulse_lengths&#91;IR_NEC_SECOND_BURST_REPEAT&#93; = 2250;<br />}<br /><br />void ir_print_data(unsigned int p_data) {<br />static u8 dev_id;<br />//static u8 dev_id2;<br />static u8 cmd_id;<br />static u8 cmd_id2;<br /><br />dev_id =  (p_data &amp; 0xFF000000) &gt;&gt; 24;<br />//dev_id2 = (p_data &amp; 0x00FF0000) &gt;&gt; 16;<br />cmd_id =  (p_data &amp; 0x0000FF00) &gt;&gt; 8;<br />cmd_id2 = (p_data &amp; 0x000000FF);<br /><br />if (cmd_id + cmd_id2 == 0xFF) {<br /><br />}<br />}<br /><br />void ir_nec_reset_transmission() {<br />if (ir_nec_current_state != IR_NEC_NONE) {<br />ir_nec_current_state = IR_NEC_NONE;<br /><br />if (ir_nec_repeat_last_command) {<br />ir_print_data(prev_data);<br />} else {<br />ir_print_data(data);<br />prev_data = data;<br />}<br /><br />data = 0;<br />cnt = 0;<br />ir_nec_repeat_last_command = false;<br />}<br />}<br /><br />bool ir_nec_check_tolerance(unsigned int received, ir_nec_state current_state) {<br />unsigned int expected = ir_nec_pulse_lengths&#91;current_state&#93;;<br /><br />if (current_state == IR_NEC_NONE ||<br />current_state == IR_NEC_NDEF) {<br />return true;<br />} else if (current_state == IR_NEC_SECOND_BURST) {<br />// We can receive long (4.5 ms) or short (2.25 ms) burst.<br />if (received &lt; 3000) {<br />ir_nec_current_state = IR_NEC_SECOND_BURST_REPEAT;<br />// ^ nasty hack, but we are can determine type of burst after receiving<br />expected = ir_nec_pulse_lengths&#91;IR_NEC_SECOND_BURST_REPEAT&#93;;<br />} else {<br />expected = ir_nec_pulse_lengths&#91;IR_NEC_SECOND_BURST&#93;;<br />}<br />}<br /><br />u32 min = expected - (TOLERANCE / 100.0) * expected;<br />u32 max = expected + (TOLERANCE / 100.0) * expected;<br />if ((received &gt;= min) &amp;&amp; (received &lt;= max)) {<br />return true;<br />}<br />return false;<br />}<br /><br />void ir_nec_state_machine(unsigned int time) {<br />//BitAction bit = 1 - GPIO_ReadInputDataBit(gpio, pin); // Invert received value<br />//GPIO_WriteBit(GPIOC, GPIO_Pin_8, bit);<br /><br />if (!ir_nec_check_tolerance(time, ir_nec_current_state)) {<br />ir_nec_reset_transmission();<br />return;<br />}<br /><br />switch (ir_nec_current_state) {<br />case IR_NEC_NONE:<br />ir_nec_current_state = IR_NEC_FIRST_BURST;<br />break;<br />case IR_NEC_FIRST_BURST:<br />ir_nec_current_state = IR_NEC_SECOND_BURST;<br />break;<br />case IR_NEC_SECOND_BURST:<br />ir_nec_current_state = IR_NEC_1;<br />break;<br />case IR_NEC_1:<br />ir_nec_current_state = IR_NEC_NDEF; // we can receive either 0 or 1<br />break;<br />case IR_NEC_NDEF:<br />ir_nec_current_state = IR_NEC_1;<br />if (time &lt; 1000) {<br />data = data &lt;&lt; 1 | 1;<br />} else {<br />data = data &lt;&lt; 1 | 0;<br />}<br /><br />//if (cnt++ == 32) { //all data received<br />//<br />//}<br />break;<br />case IR_NEC_SECOND_BURST_REPEAT:<br />// repeat last message<br />//ir_nec_repeat_last_command = true;<br />ir_nec_current_state = IR_NEC_1;<br />break;<br />default:<br />ir_nec_reset_transmission();<br />break;<br />}<br />}[/syntax]<br /><br />ir.h<br />[syntax=c]#ifndef __IR_H__<br />#define __IR_H__<br />#include &lt;stm32f10x.h&gt;<br />#include &lt;stm32f10x_gpio.h&gt;<br />#include &lt;stdbool.h&gt;<br />#include &lt;stdio.h&gt;<br /><br />#define TOLERANCE 20<br /><br />typedef enum {<br />IR_NEC_NONE = 0,<br />IR_NEC_NDEF,<br />IR_NEC_FIRST_BURST,<br />IR_NEC_SECOND_BURST,<br />IR_NEC_SECOND_BURST_REPEAT,<br />IR_NEC_1<br />} ir_nec_state;<br /><br />void ir_nec_init(u16 pin, GPIO_TypeDef *gpio);<br />void ir_nec_state_machine(unsigned int time);<br />void ir_nec_reset_transmission();<br /><br />#endif // __IR_H__[/syntax]<br /><br />pilot<br /><a href="https://obrazkiforum.atnel.pl/8017/8780e2612ec4ad74d1eb30f2704ada95.jpg"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/8017/8780e2612ec4ad74d1eb30f2704ada95.jpg" alt="Obrazek" /></a><a href="https://obrazkiforum.atnel.pl/8017/e1488891de19c62155bf3238b7528c76.png"  class="postlink"><img src="https://obrazkiforum.atnel.pl/thumb/8017/e1488891de19c62155bf3238b7528c76.png" alt="Obrazek" /></a><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=8017">NeverGiveUp</a> — 7 paź 2018, o 13:41</p><hr />
]]></content>
</entry>
</feed>