2017-03-14 12:35 AM
I am beginner in STM32 Programming. I need to code the IR,RC5 Remote protocol in stm32f0 microcontroller. Please help me to do coding it.
♯
♯
https://community.st.com/tags♯/?tags=timer%20delay
♯
‌♯
‌Thanks and Regards
Akhil
#timer-delay #stm32f0 #stm32f30f4 #rc5 #rc5_protocol2017-03-15 12:41 PM
OK, so what do you have already done? What HW do you have? Did you successfully write and run a LED blinky?
JW
2017-03-15 02:36 PM
did you see this link ?
http://www.sbprojects.com/knowledge/ir/rc5.php
you would use two timers for sure...
basically the bit shifter would be under the 1st timer interrupt controlrun the 1st timer overflow at twice the frequency ie 72KHz so you have 2 phases
in the shifter, if its a one, shift zero in the first phase then the one in the second phaseif its a zero, shift a one first then a zero.
1st timer interrupt
stop the 2nd timer now
check the on phase/ off phase
to shift a zero phase, just exit the 1st timer interruptto shift a one phase, run a 2nd timer at the spike frequency and set the pulse length to a few counts.(probably best to use PWM output here)
after setting the 2nd phase move shifting pointer to next bit of the data
2017-03-15 11:20 PM
Hi,
Thanks for replying to my question.
I have done the coding for stm32f030f4p6 microcontroller. I have successfully done coding the led and PWM Output for led brightness control.
Now i have to do RC5 coding,for which i connected the IR Sensor in Pin PA4 and used Timer Input capture method. I am getting an output for the decoded value,but it is not in proper way. Output is coming only after pressing the remote key for long time.
I am posting the code i have done, kindly please go through it and help me to decode the command and address properly.
void init_timer()
{ TIM14->PSC = 47; TIM14->ARR = 2220; //TIM14->CR1 |= (1<<8); TIM14->CR1 &= ~(3<<8); //Clock division tDTS = tCK_INT TIM14->CR1 &= ~(1<<1); //UEV Enabled TIM14->CR1 |= (1<<7); //TIMx_ARR register is buffered TIM14->CR1 |= (1<<2); //Only counter overflow generates an UEV if enabled TIM14->CCMR1 |= 1; //CC1S Input Capture mode 01 //TIM14->CCMR1 |= (1<<2); //ICIPSC Presacler value capture is done once every 2 events// TIM14->CCMR1 |= TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1; //(3<<4); //IC1F Input digital filter TIM14->CCER |= TIM_CCER_CC1E; //(1); //CC1E: Capture/Compare 1 enable. TIM14->CCER |= (1<<1);//Falling edge CC1NP and CC1P Value TIM14->DIER |= 2; //CC1 Capture interrupt enabled, Update Intrpt Disabled TIM14->CR1 |= (1); //Counter enabled NVIC_EnableIRQ(TIM14_IRQn);}void TIM14_IRQHandler(void)
{ int read; if ((TIM14->SR & TIM_SR_CC1IF) != 0) { //if ((TIM14->SR & TIM_SR_CC1OF) != 0) //{ TIM14->SR = 0X0000; read = TIM14->CCR1; //read input capture value cnt++;if(read >=640 && read <= 1140 ) //if(read >=883 && read <= 895) //if(read == 889) { data = data<<1; } else if(read >= 1340 && read <= 2220) //else if(read == 1778) //else if(read >= 1772 && read <= 1784) { data <<= 1; data |= 1; } if(cnt>=13) { cnt=0; data &= 0x7FF; data >>= 6; data &= 0x1F; } if(data == 0x19) //Address = 0X19 {GPIOA->BSRR |= (1<<7); //LED ON } }}2017-03-15 11:35 PM
Hi,
Thanks for replying to my question.
I have tried using timer input capture method and got a partial output i can say. I used only one timer. Since i am not much familiar with the timer function i couldn't able run 2 timer together as you said. Kindly go through the code i have pasted here and help me any suggestion son this.
Thanks and Regards
Akhil
void init_timer()
{TIM14->PSC = 47;TIM14->ARR = 2220;//TIM14->CR1 |= (1<<8);
TIM14->CR1 &= ~(3<<8); //Clock division tDTS = tCK_INTTIM14->CR1 &= ~(1<<1); //UEV EnabledTIM14->CR1 |= (1<<7); //TIMx_ARR register is buffered TIM14->CR1 |= (1<<2); //Only counter overflow generates an UEV if enabledTIM14->CCMR1 |= 1; //CC1S Input Capture mode 01
//TIM14->CCMR1 |= (1<<2); //ICIPSC Presacler value capture is done once every 2 events// TIM14->CCMR1 |= TIM_CCMR1_IC1F_0 | TIM_CCMR1_IC1F_1; //(3<<4); //IC1F Input digital filterTIM14->CCER |= TIM_CCER_CC1E; //(1); //CC1E: Capture/Compare 1 enable.
TIM14->CCER |= (1<<1);//Falling edge CC1NP and CC1P ValueTIM14->DIER |= 2; //CC1 Capture interrupt enabled, Update Intrpt Disabled
TIM14->CR1 |= (1); //Counter enabled
NVIC_EnableIRQ(TIM14_IRQn);
}void TIM14_IRQHandler(void)
{ int read;if ((TIM14->SR & TIM_SR_CC1IF) != 0){//if ((TIM14->SR & TIM_SR_CC1OF) != 0)//{TIM14->SR = 0X0000;read = TIM14->CCR1; //read input capture valuecnt++;if(read >=640 && read <= 1140 )//if(read >=883 && read <= 895)//if(read == 889){data = data<<1;}else if(read >= 1340 && read <= 2220)//else if(read == 1778)//else if(read >= 1772 && read <= 1784){data <<= 1;data |= 1;} if(cnt>=13){cnt=0;data &= 0x7FF;data >>= 6;data &= 0x1F;}if(data == 0x19) //Address = 0X19{GPIOA->BSRR |= (1<<7); //LED ON}}}2017-03-16 01:10 AM
I cannot go through your code.
you only need to transmit, correct ?
initialize:
I suggested using the 1st timer overflow interrupt at 72KHz, did you start there ? check it on a cro. (Oscilloscope)
then you set a 2nd timer set to 256KHz roughly, (does the spec say ?) with PWM mode with approx, 5% duty cycle.
in 1st timer interrupt:
when you need to send pulses, enable the 2nd timer pwm,
when you need to send low signal, disable the 2nd timer pwm.
this is your work to do... please don't ask me to do your work.
I am happy to guide you.
2017-03-16 01:30 AM
Hi
I think you have misunderstood my question.
I have to decode the RC5 Code received in the IR Sensor.
Sorry if i confused You.
Regards
Akhil
2017-03-16 02:02 AM
Look ar AN3174 - Implementing an RC5 infrared remote control receiver
2017-03-16 02:36 AM
OK so you want to measure time between successive trailing edges and make received-0-or-1 decision based on that time in the ISR.
First, you don't rely on any fixed period. That means, you cannot simply read out the captured time from TIM14->CCR1. You need to calculate the time *elapsed since the last edge*, i.e. remember the last readout from the previous time the interrupt fired, in a global variable, and subtract the it from the current readout. For this to work, you need to take into account counter overflows, so better set ARR to maximum value (0xFFFF) and do time_difference = (new_readout - old_readout) & 0xFFFF;.
You might need also to count the counter overflows (i.e. enable interrupts also on update events and input capture events; and in the interrupt routine distinguish whether it was update or capture (or both)) - in case of multiple overflows between capture events it's a long intercharacter gap which needs a restart (see below).
Next, decide what to do if the measured time falls outside the intervals you determined (and you might to fine tune further) for 0 and 1.
Restart is, when you zero your cnt.
JW
2017-03-16 03:52 AM
Thank You so much for Your Reply.
I will try to do in this method.
Regards
Akhil