红外调试求助!

2019-07-20 16:23发布

我用的是STM32F103VE的40引脚E9,
//红外遥控初始化
//设置IO以及TIM1_CH1的输入捕获
void Remote_Init(void)                              
{        GPIO_InitTypeDef GPIO_InitStructure;       
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        TIM_ICInitTypeDef  TIM1_ICInitStructure;

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);//TIM1时钟使能

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE|RCC_APB2Periph_AFIO,ENABLE);
//        GPIO_PinRemapConfig(GPIO_FullRemap_TIM1,ENABLE);
       GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
          GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
       GPIO_Init(GPIOE, &GPIO_InitStructure);
        GPIO_SetBits(GPIOE,GPIO_Pin_9);        //初始化GPIOE.9       
       
        TIM_TimeBaseStructure.TIM_Prescaler=71;  ////预分频器,1M的计数频率,1us加1.       
        TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
        TIM_TimeBaseStructure.TIM_Period=10000;   //设定计数器自动重装值 最大10ms溢出  
        TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_TimeBaseInit(TIM1,&TIM_TimeBaseStructure);
                  
        //初始化TIM1输入捕获参数
        TIM1_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01         选择输入端 IC1映射到TI1上
        TIM1_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
        TIM1_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
        TIM1_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;         //配置输入分频,不分频
        TIM1_ICInitStructure.TIM_ICFilter = 0x03;//IC1F=0003 8个定时器时钟周期滤波
        TIM_ICInit(TIM1, &TIM1_ICInitStructure);//初始化定时器2输入捕获通道
         

        NVIC_InitStructure.NVIC_IRQChannel = TIM1_CC_IRQChannel;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级1
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =1;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //初始化NVIC寄存器

        NVIC_InitStructure.NVIC_IRQChannel = TIM1_UP_IRQChannel;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;                //子优先级2
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //IRQ通道使能
        NVIC_Init(&NVIC_InitStructure);        //初始化NVIC寄存器

        TIM_ITConfig(TIM1,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断       
        TIM_Cmd(TIM1,ENABLE );                  //使能定时器1

}

//处理红外键盘
//返回值:
//0,没有任何按键按下
//其他,按下的按键键值.
u8 Remote_Scan(void)
{        
        u8 sta=0;      
           u8 t1,t2;  
        if(RmtSta&(1<<6))//得到一个按键的所有信息了
        {
            t1=RmtRec>>24;                        //得到地址码
            t2=(RmtRec>>16)&0xff;        //得到地址反码
            if((t1==(u8)~t2)&&t1==REMOTE_ID)//检验遥控识别码(ID)及地址
            {
                t1=RmtRec>>8;
                t2=RmtRec;        
                if(t1==(u8)~t2)sta=t1;//键值正确         
                }   
                if((sta==0)||((RmtSta&0X80)==0))//按键数据错误/遥控已经没有按下了
                {
                         RmtSta&=~(1<<6);//清除接收到有效按键标识
                        RmtCnt=0;                //清除按键次数计数器
                }
        }  
    return sta;
}


/*******************************************************************************
* Function Name  : TIM1_UP_IRQHandler
* Description    : This function handles TIM1 overflow and update interrupt
*                  request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void TIM1_UP_IRQHandler(void)
{

    if(TIM_GetITStatus(TIM1,TIM_IT_Update)!=RESET)
        {
                if(RmtSta&0x80)//上次有数据被接收到了
                {       
                        RmtSta&=~0X10;                                                //取消上升沿已经被捕获标记
                        if((RmtSta&0X0F)==0X00)RmtSta|=1<<6;//标记已经完成一次按键的键值信息采集
                        if((RmtSta&0X0F)<14)RmtSta++;
                        else
                        {
                                RmtSta&=~(1<<7);//清空引导标识
                                RmtSta&=0XF0;        //清空计数器       
                        }                                                                   
                }                                                            
        }

        TIM_ClearITPendingBit(TIM1,TIM_IT_Update);  //清除中断标志位
}


/*******************************************************************************
* Function Name  : TIM1_CC_IRQHandler
* Description    : This function handles TIM1 capture compare interrupt request.
* Input          : None
* Output         : None
* Return         : None
*******************************************************************************/
void TIM1_CC_IRQHandler(void)
{                              

        if(TIM_GetITStatus(TIM1,TIM_IT_CC1)!=RESET)
        {          
                if(RDATA)//上升沿捕获
                {

                TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Falling);                //CC1P=1 设置为下降沿捕获                               
                    TIM_SetCounter(TIM1,0);                   //清空定时器值
                RmtSta|=0X10;                                        //标记上升沿已经被捕获
                }else //下降沿捕获
                {                       
                           Dval=TIM_GetCapture1(TIM1);//读取CCR1也可以清CC1IF标志位
                         TIM_OC1PolarityConfig(TIM1,TIM_ICPolarity_Rising); //CC4P=0        设置为上升沿捕获
                       
                        if(RmtSta&0X10)                                        //完成一次高电平捕获
                        {
                                if(RmtSta&0X80)//接收到了引导码
                                {
                                       
                                        if(Dval>300&&Dval<800)                        //560为标准值,560us
                                        {
                                                RmtRec<<=1;        //左移一位.
                                                RmtRec|=0;        //接收到0          
                                        }else if(Dval>1400&&Dval<1800)        //1680为标准值,1680us
                                        {
                                                RmtRec<<=1;        //左移一位.
                                                RmtRec|=1;        //接收到1
                                        }else if(Dval>2200&&Dval<2600)        //得到按键键值增加的信息 2500为标准值2.5ms
                                        {
                                                RmtCnt++;                 //按键次数增加1次
                                                RmtSta&=0XF0;        //清空计时器               
                                        }
                                }else if(Dval>4200&&Dval<4700)                //4500为标准值4.5ms
                                {
                                        RmtSta|=1<<7;        //标记成功接收到了引导码
                                        RmtCnt=0;                //清除按键次数计数器
                                }                                                 
                        }
                        RmtSta&=~(1<<4);
                }                                                                                                            
        }
TIM_ClearFlag(TIM1,TIM_IT_Update|TIM_IT_CC1);            
}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
5条回答
xuande
1楼-- · 2019-07-20 18:43
 精彩回答 2  元偷偷看……
1206447373
2楼-- · 2019-07-20 21:00
 精彩回答 2  元偷偷看……
xuande
3楼-- · 2019-07-20 23:27

这事确实和IO复用有关系,
但和定时器关系更大,设置更复杂一点。


1206447373
4楼-- · 2019-07-20 23:53
xuande 发表于 2017-1-10 17:02
这事确实和IO复用有关系,
但和定时器关系更大,设置更复杂一点。

上面的代码基本是对的,我调试完成了,谢谢
jeff_梁
5楼-- · 2019-07-21 00:52
楼主 你的是什么情况 我进入不了void TIM1_CC_IRQHandler(void)中断

一周热门 更多>