OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2821|回复: 4

战舰红外遥控求助,程序停在了,使能定时器中断的地方

[复制链接]

3

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
335
金钱
335
注册时间
2016-6-10
在线时间
41 小时
发表于 2016-8-18 10:32:18 | 显示全部楼层 |阅读模式
10金钱
我直接在原有的例程模版上重新写了一边红外的程序,但是程序就停在了remote_init()中        TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC4,ENABLE),屏幕显示全白,按下遥控器之后屏幕才显示出主函数中的默认字符,不显示数据
#include "remote.h"

void remote_init(void)//初始化红外遥控,设置IO及定时器4的输入捕获
{
        GPIO_InitTypeDef GPIO_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
        TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
        TIM_ICInitTypeDef TIM_ICInitStructure;
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//使能GPIOB时钟
        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);//使能定时器4时钟
       
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPD;
//        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_Init(GPIOB,&GPIO_InitStructure);
       
        GPIO_SetBits(GPIOB,GPIO_Pin_9);                //初始化PB9
       
        TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;
        TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up;//向上计数模式
        TIM_TimeBaseInitStructure.TIM_Period=10000;//设置自动重装载值,最大溢出时间10ms
        TIM_TimeBaseInitStructure.TIM_Prescaler=71;//设置预分频器,1M计数频率,1us加1
       
        TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStructure);
       
        TIM_ICInitStructure.TIM_Channel=TIM_Channel_4;//选择输入端IC4映射到IT4上
        TIM_ICInitStructure.TIM_ICFilter=0;//滤波
        TIM_ICInitStructure.TIM_ICPolarity=TIM_ICPolarity_Rising;//上升沿捕获
        TIM_ICInitStructure.TIM_ICPrescaler=TIM_ICPSC_DIV1;
        TIM_ICInitStructure.TIM_ICSelection=TIM_ICSelection_DirectTI;
        TIM_ICInit(TIM4,&TIM_ICInitStructure);
       
        TIM_Cmd(TIM4,ENABLE);
       
        NVIC_InitStructure.NVIC_IRQChannel=TIM4_IRQn;//定时器4中断
        NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;//IQR通道使能
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority=3;//响应优先级
        NVIC_Init(&NVIC_InitStructure);

        TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC4,ENABLE);       

}

//遥控器状态
//[7]收到同步码标志
//[6]得到按键信息
//[5]保留
//[4]标记上升沿捕获
//[3:0]溢出计时器
u8         RmtSta=0;                    
u16 Dval;                //下降沿时计数器的值
u32 RmtRec=0;        //红外接收到的数据                               
u8  RmtCnt=0;        //按键按下的次数       
void TIM4_IRQHandler(void)
{
        if(TIM_GetITStatus(TIM4,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;                                                //清空计数器       
                        }                                               
                }
        }
        if(TIM_GetITStatus(TIM4,TIM_IT_CC4)!=RESET)//得到捕获中断
        {
                if(RDATA)//PBin(9)输入为高电平,则为上升沿
                {
                        TIM_OC4PolarityConfig(TIM4,TIM_ICPolarity_Falling);//更改为下降沿捕获
                        TIM_SetCounter(TIM4,0);//设置装载寄存器值为0
                        RmtSta|=0X10;                                        //标记为捕获到了上升沿
                }else //PBin(9)输入低电平
                {
                        TIM_OC4PolarityConfig(TIM4,TIM_ICPolarity_Rising);//变为上升沿捕获
                        Dval=TIM_GetCapture4(TIM4);        //获取下降沿是寄存器的值
                        if(RmtSta&0X10)//如果已捕获到上升沿
                        {
                                if(RmtSta&0x80)//如果已捕获到引导码
                                {
                                        if(Dval>300&Dval<800)//判断是否为逻辑“0”,560为标准值,560us
                                        {
                                                RmtRec<<=1;//左移一位
                                                RmtRec|=0;//收到0
                                        }
                                        else if(Dval>1400&Dval<1800)//判断逻辑“1”,1680为标准值,1680us
                                        {
                                                RmtRec<<=1;
                                                RmtRec|=1;
                                        }
                                        else if(Dval>2100&Dval<2600)//判断连发码,2500为标准值,2.5ms
                                        {
                                                RmtCnt++;
                                                RmtSta&=0xf0;
                                        }
                                       
                                }
                                else if(Dval>4200&Dval<4700)//如果还未捕获引导码,则判断是否为引导码,4500为标准值,4.5ms
                                {
                                        RmtSta|=1<<7;//设置捕获引导码标志位
                                        RmtCnt=0;//清除按键次数
                                }
                               
                        }
                        RmtSta&=~(1<<4);//清除捕获上升沿标志
                }
                TIM_ClearITPendingBit(TIM4,TIM_IT_Update|TIM_IT_CC4);//清除中断标志位
               
        }
       
}

u8 remote_scan(void)
{
        u8 sta=0;
        u8 t1,t2;
        if(RmtSta&(1<<6))
        {
                t1=RmtRec>>24;
                t2=RmtRec>>16;
                if(t1==(~t2)&&t1==REMOTE_ID)
//                if(t1==(u8)~t2&&t1==REMOTE_ID)
                {
                        t1=RmtRec>>8;
                        t2=RmtRec;
                        if(t1==(~t2)) sta=t1;
//                        if(t1==(u8)~t2) sta=t1;
                }       
                if((sta==0)||((RmtSta&0X80)==0))//按键数据错误/遥控已经没有按下了
                {
                         RmtSta&=~(1<<6);//清除接收到有效按键标识
                        RmtCnt=0;                //清除按键次数计数器
                }
        }
        return sta;
}

红外遥控实验.rar

2.69 MB, 下载次数: 60

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11544
金钱
11544
注册时间
2014-4-1
在线时间
1315 小时
发表于 2016-8-18 10:43:08 | 显示全部楼层

停在里面哪一句?
仿真器走没走?



回复

使用道具 举报

3

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
335
金钱
335
注册时间
2016-6-10
在线时间
41 小时
 楼主| 发表于 2016-8-18 13:17:50 | 显示全部楼层
xuande 发表于 2016-8-18 10:43
停在里面哪一句?
仿真器走没走?

void remote_init(void)里的 TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC4,ENABLE);    这句,仿真器里也是停到这
回复

使用道具 举报

58

主题

6294

帖子

1

精华

资深版主

Rank: 8Rank: 8

积分
11544
金钱
11544
注册时间
2014-4-1
在线时间
1315 小时
发表于 2016-8-18 14:05:13 | 显示全部楼层
末世界 发表于 2016-8-18 13:17
void remote_init(void)里的 TIM_ITConfig(TIM4,TIM_IT_Update|TIM_IT_CC4,ENABLE);    这句,仿真器里也 ...


TIM_ITConfig函数里面还有内容。

回复

使用道具 举报

3

主题

19

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
335
金钱
335
注册时间
2016-6-10
在线时间
41 小时
 楼主| 发表于 2016-8-18 15:07:45 | 显示全部楼层
xuande 发表于 2016-8-18 14:05
TIM_ITConfig函数里面还有内容。

没了吧,里面就3个参数,而且中断优先级我也已经配置过了啊
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-6 21:34

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表