基于stm32f103的红外遥控程序设计

以下是irsensor初始化程序设计

#include "stm32f10x.h"
#ifndef   __IRSENSOR_H
#define   __IRSENSOR_H
#define   RCC_APB2Periph_GPIO         RCC_APB2Periph_GPIOB
#define   GPIO_Pinx                               GPIO_Pin_14
#define   GPIO                                        GPIOB
#define   IRGet_Pin_Status                    GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)
                                                                //以下是中断线的配置
#define   GPIO_PortSourceGPIO           GPIO_PortSourceGPIOB  
#define   GPIO_PinSource_PIN             GPIO_PinSource14

#define   EXTI_Linex                              EXTI_Line14
//定义结构体,这是在程序写完后的优化,不是预先设计
typedef struct
{
    unsigned char  key[5];                      //key[2]为command,实际命令码,key[0],key[1]为地址码和地址反码;
    uint8_t  count;                                  //连续递增的计数值
    int  cnt;                       //32位的编码计次
}NEC;

void IR_init(void);                                   //IR引脚初始化,EXTI中断线初始化;
void number_back(uint16_t *num);      //改变地址传参,指针截引用改变内值 ,返回红外的数据;
#endif


以下是Irsensor传感器的c代码编写:

#include "stm32f10x.h"                  // Device header
#include "IRsensor.h"
#include "string.h"
#include "Delay.h"
#include "dz.h"
#include "timer.h"
uint16_t flag=0;
NEC nec={0};                                 //NEC结构体类型的初始化书写;
uint16_t  number;
//2,中断定义的建模顺序:开启AFIO以及引脚GPIO的时钟+引脚定义+外部中断(EXIT)定义+NVIC(中断控制器)
void IR_init(void)
{
    DZ_init();
    //配置AFIO时钟以及引脚GPIO引脚的时钟;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIO|RCC_APB2Periph_AFIO , ENABLE);//使能APB2,在总线B的时钟;    
    //引脚定义
    GPIO_InitTypeDef GPIOB_INSTRUCT;//引脚定义声明
    
    GPIOB_INSTRUCT.GPIO_Mode=GPIO_Mode_IN_FLOATING ;//接受信号配置上拉;
    GPIOB_INSTRUCT.GPIO_Pin=GPIO_Pinx;
    GPIOB_INSTRUCT.GPIO_Speed=GPIO_Speed_50MHz;//
    GPIO_Init(GPIO,&GPIOB_INSTRUCT );
    
    //外部中断定义
    EXTI_InitTypeDef GPIOB_EXIT;           
    
    GPIO_EXTILineConfig(GPIO_PortSourceGPIO, GPIO_PinSource_PIN);                    //中断线配置;
    
    GPIOB_EXIT.EXTI_Line=EXTI_Linex;
    GPIOB_EXIT.EXTI_LineCmd=ENABLE;
    GPIOB_EXIT.EXTI_Mode=EXTI_Mode_Interrupt ;                                         //启用中断模式;
    GPIOB_EXIT.EXTI_Trigger=EXTI_Trigger_Rising_Falling;                               //由于NEC编码中有上升沿和下降沿一并存在,所以上升下降皆需要;
    EXTI_Init(&GPIOB_EXIT);
                                                                                                                                       //中断控制器的定义//在misc,h中
    NVIC_InitTypeDef GPIOB_NVIC;                                                 
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);                                     //整个芯片的分组代                                                                码只用一种,所以若有其他module使用,则只能是其一种;
    GPIOB_NVIC.NVIC_IRQChannel=EXTI15_10_IRQn;  
    GPIOB_NVIC.NVIC_IRQChannelCmd=ENABLE;
    GPIOB_NVIC.NVIC_IRQChannelPreemptionPriority=1;                                     //抢占优先级因                                                                                  为选择了2组值在0~2浮动,这里选择了1
    GPIOB_NVIC.NVIC_IRQChannelSubPriority=1;                                            //响应优先级因为选择了2组,所以值在0~2浮动,这里选择了1
    NVIC_Init(&GPIOB_NVIC);
    
  NVIC_EnableIRQ(EXTI15_10_IRQn);                                                   //中断寄存器使能线
}

//返回外来参数
void number_back(uint16_t *num)
{
   *num=number; 
}

//外部中断(高电平低电平都会触发)
void EXTI15_10_IRQHandler(void)                                      //中断函数名,需要在启动文件stm32f10x_md.s中寻找;
{
    if( EXTI_GetFlagStatus(EXTI_Linex) != RESET)
    {
            //引脚变化即刻计时
        switch(nec.count)//count初始为零
            {
                case 0:
                    TIME_OPEN();//计时器打开
                    TIME_CLEAR();//计时器清零
                     nec.count++;
                     break;
                case 1:
                    TIME_CLOSE();//计时器关闭
                     if(TIME_GET<10000&&TIME_GET>8000)//9.5ms的电平
                     {
                          nec.count++;
                          TIME_OPEN();//计时器打开
                         TIME_CLEAR();//计时器清零
                     }
                     else
                     {
                         nec.count=0;
                     }
                     break;
                case 2:
                    TIME_CLOSE();//定时器关闭
                     if(TIME_GET<5500&&TIME_GET>3500)//4.5ms的电平
                     {
                          nec.cnt=0;
                          memset(nec.key,0,sizeof(nec.key));
                          nec.key[2]=0;
                         //以上操作是清空数据为,且保证每次循环都有空间。
                          nec.count++;
                     }
                     else
                     {
                         nec.count=0;
                     }
                     break;
                    default://以下到达实际nec编码,由于低电平时间一样,所以此时判断高电平时间来决定是1还是0逻辑
                     if(IRGet_Pin_Status)  {    TIME_OPEN();TIME_CLEAR(); }//高电平时打开计时器
                     else
                     {
                         TIME_CLOSE();
                         if(TIME_GET<700&&TIME_GET>400) { }                 //检测位逻辑0的电平,不执行任何操作
                        else
                  if(TIME_GET<1800&&TIME_GET>1500)                   //脉宽宽度取长一点,以免用不了;
              {nec.key[nec.cnt/8] |=1<<(nec.cnt%8);}           //检测到逻辑1的操作,执行位移的操作            
                         else
                             {nec.count=0;}//不为高低电平,就说明传入信息有误,赋值为零,从新开始
                          
                         if(nec.cnt>=32)
                             { 
                                 nec.count=0;    //连续算法的终端位,为下一次信号连续做准备。
                                 
              if(nec.key[2]-0x40==0)
                             {
                                 flag=1;
                 number=0x40;
                             }
               else
              if(nec.key[2]!=0x40)
                            {
                                flag=1;
                                number=0x01;
                            }                                
                         }
                          nec.cnt++;  
                     }
        } 
        EXTI_ClearITPendingBit(EXTI_Linex);//清除中断位(pending bit)标志位;
    }
}
//使用红外时解除
//定时4中断,溢出就参数清零
//void TIM4_IRQHandler (void)//计数器4一旦溢出,就触发itconfig的同时也出发其中断函数,进行全局状态的清除,保持信号的连续。
//{
//    TIME_CLEAR();
//  TIME_CLOSE();
//    nec.count=0;
//    nec.cnt=0;
//    TIM_ClearITPendingBit(TIM,TIM_IT_Update);
//}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值