这里涉及定时器的PWM的输入捕获的功能, 通过配置TIM2, 普通定时器, 通道3, 引脚PA2接遥控接收机的某个通道的输出, 就可以捕获接收的信号了, 这个信号就可以通过MQTT传到云端, 做远程遥控处理.
首先我把接收机挂上逻辑分析仪, 发现, 遥控信号基本上是高电平从1000us到2500us之间, 所以就利用定时器的计数器, 计算高电平时, 计数器数了多少个数, 就知道高电平持续了多久.
基本上照搬了原子的代码, 改了一下端口, 因为我用的F103C8上面, 只有3个基本定时器, TIM2,3,4.
定时器部分, timer.c
//¶¨Ê±Æ÷2ͨµÀ3ÊäÈ벶»ñÅäÖà TIM_ICInitTypeDef TIM2_ICInitStructure; void TIM2_Cap_Init(u16 arr,u16 psc) { GPIO_InitTypeDef GPIO_InitStructure; TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; NVIC_InitTypeDef NVIC_InitStructure; RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //ʹÄÜTIM2ʱÖÓ RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); //ʹÄÜGPIOAʱÖÓ GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2 Çå³ý֮ǰÉèÖà GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD; //PA2 ÊäÈë GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_ResetBits(GPIOA,GPIO_Pin_2); //PA2 ÏÂÀ //³õʼ»¯¶¨Ê±Æ÷2 TIM2 TIM_TimeBaseStructure.TIM_Period = arr; //É趨¼ÆÊýÆ÷×Ô¶¯ÖØ×°Öµ TIM_TimeBaseStructure.TIM_Prescaler =psc; //Ô¤·ÖƵÆ÷ TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //ÉèÖÃʱÖÓ·Ö¸î:TDTS = Tck_tim TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; //TIMÏòÉϼÆÊýģʽ TIM_TimeBaseInit(TIM2, &TIM_TimeBaseStructure); //¸ù¾ÝTIM_TimeBaseInitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯TIMxµÄʱ¼ä»ùÊýµ¥Î» //³õʼ»¯TIM2ÊäÈ벶»ñ²ÎÊý TIM2_ICInitStructure.TIM_Channel = TIM_Channel_3; //CC3S=03 Ñ¡ÔñÊäÈë¶Ë IC3Ó³Éäµ½TI3ÉÏ TIM2_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising; //ÉÏÉýÑز¶»ñ TIM2_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //Ó³Éäµ½TI3ÉÏ TIM2_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1; //ÅäÖÃÊäÈë·ÖƵ,²»·ÖƵ TIM2_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 ÅäÖÃÊäÈëÂ˲¨Æ÷ ²»Â˲¨ TIM_ICInit(TIM2, &TIM2_ICInitStructure); //ÖжϷÖ×é³õʼ»¯ NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn; //TIM3ÖÐ¶Ï NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2; //ÏÈÕ¼ÓÅÏȼ¶2¼¶ NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //´ÓÓÅÏȼ¶0¼¶ NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQͨµÀ±»Ê¹ÄÜ NVIC_Init(&NVIC_InitStructure); //¸ù¾ÝNVIC_InitStructÖÐÖ¸¶¨µÄ²ÎÊý³õʼ»¯ÍâÉèNVIC¼Ä´æÆ÷ TIM_ITConfig(TIM2,TIM_IT_Update|TIM_IT_CC3,ENABLE);//ÔÊÐí¸üÐÂÖÐ¶Ï ,ÔÊÐíCC3IE²¶»ñÖÐ¶Ï TIM_Cmd(TIM2,ENABLE ); //ʹÄܶ¨Ê±Æ÷2 } u8 TIM2CH3_CAPTURE_STA=0; //ÊäÈ벶»ñ״̬ u16 TIM2CH3_CAPTURE_VAL; //ÊäÈ벶»ñÖµ //¶¨Ê±Æ÷5ÖжϷþÎñ³ÌÐò void TIM2_IRQHandler(void) { if((TIM2CH3_CAPTURE_STA&0X80)==0)//»¹Î´³É¹¦²¶»ñ { if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET) { if(TIM2CH3_CAPTURE_STA&0X40)//ÒѾ²¶»ñµ½¸ßµçƽÁË { if((TIM2CH3_CAPTURE_STA&0X3F)==0X3F)//¸ßµçƽ̫³¤ÁË { TIM2CH3_CAPTURE_STA|=0X80;//±ê¼Ç³É¹¦²¶»ñÁËÒ»´Î TIM2CH3_CAPTURE_VAL=0XFFFF; }else TIM2CH3_CAPTURE_STA++; } } if (TIM_GetITStatus(TIM2, TIM_IT_CC3) != RESET)//²¶»ñ1·¢Éú²¶»ñʼþ { if(TIM2CH3_CAPTURE_STA&0X40) //²¶»ñµ½Ò»¸öϽµÑØ { TIM2CH3_CAPTURE_STA|=0X80; //±ê¼Ç³É¹¦²¶»ñµ½Ò»´Î¸ßµçƽÂö¿í TIM2CH3_CAPTURE_VAL=TIM_GetCapture3(TIM2); TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Rising); //CC1P=0 ÉèÖÃΪÉÏÉýÑز¶»ñ }else //»¹Î´¿ªÊ¼,µÚÒ»´Î²¶»ñÉÏÉýÑØ { TIM2CH3_CAPTURE_STA=0; //Çå¿Õ TIM2CH3_CAPTURE_VAL=0; TIM_SetCounter(TIM2,0); TIM2CH3_CAPTURE_STA|=0X40; //±ê¼Ç²¶»ñµ½ÁËÉÏÉýÑØ TIM_OC3PolarityConfig(TIM2,TIM_ICPolarity_Falling); //CC1P=1 ÉèÖÃΪϽµÑز¶»ñ } } } TIM_ClearITPendingBit(TIM2, TIM_IT_CC3|TIM_IT_Update); //Çå³ýÖжϱê־λ }
因为原先文件时ASCI编码的,所以中文贴在utf8的页面会乱码, 没辙了.
main.c:
extern u8 TIM5CH1_CAPTURE_STA; //ÊäÈ벶»ñ״̬ extern u16 TIM5CH1_CAPTURE_VAL; //ÊäÈ벶»ñÖµ int main(void) { u32 temp=0; delay_init(); //ÑÓʱº¯Êý³õʼ»¯ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //ÉèÖÃNVICÖжϷÖ×é2:2λÇÀÕ¼ÓÅÏȼ¶£¬2λÏìÓ¦ÓÅÏȼ¶ uart_init(115200); //´®¿Ú³õʼ»¯Îª115200 LED_Init(); //LED¶Ë¿Ú³õʼ»¯ TIM3_PWM_Init(899,0); //²»·ÖƵ¡£PWMƵÂÊ=72000/(899+1)=80Khz TIM5_Cap_Init(0XFFFF,72-1); //ÒÔ1MhzµÄƵÂʼÆÊý while(1) { delay_ms(10); TIM_SetCompare2(TIM3,TIM_GetCapture2(TIM3)+1); if(TIM_GetCapture2(TIM3)==300)TIM_SetCompare2(TIM3,0); if(TIM5CH1_CAPTURE_STA&0X80)//³É¹¦²¶»ñµ½ÁËÒ»´ÎÉÏÉýÑØ { temp=TIM5CH1_CAPTURE_STA&0X3F; temp*=65536;//Òç³öʱ¼ä×ÜºÍ temp+=TIM5CH1_CAPTURE_VAL;//µÃµ½×ܵĸߵçƽʱ¼ä printf("HIGH:%d us\r\n",temp);//´òÓ¡×ܵĸߵãƽʱ¼ä TIM5CH1_CAPTURE_STA=0;//¿ªÆôÏÂÒ»´Î²¶»ñ } } }
然后, 接线, 把串口输出到pc上, 推动遥控器的遥感, 就可以看到stm32可以知道油门变化了.
接下来是把电机驱动板装到我的车上, 这样最起码, 可以把车改装成带油门控制的版本了, 而不是现在这样, 油门跟方向都只有开关功能...
具体工程代码在这里:
https://github.com/MontaukLaw/stm32PWMInput