STM32捕获天地飞接收机信号.

这里涉及定时器的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

 

posted @ 2019-03-06 16:10  Montauk  阅读(1000)  评论(0编辑  收藏  举报