专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

stm单片机红外编码程序

作者:罗运冰   来源:本站原创   点击数:  更新时间:2013年11月21日   【字体:

    上回书说到,ht6621,可以通过hs0038进行解码,但由于只可以通过遥控器进行控制,觉得不爽,而且项目中,也不允许用遥控器,所以就决定弄个单片机来做个编码。上回书说了,pt6221可以进行编码,于是百度,去找数据手册,就有了日志里的编码方式,然后,用示波器打了一下波形,看了一下,真是和手册上说的一样,于是傻了吧唧,的按照手册上说的时序,写了一个只是电平变化的程序。写完后,把红外二极管,接到管脚上一试,结果接收木有反映,但按下红外遥控器就有反映,拿手机照相机看,也都有光。于是我陷入了纠结。开始是以为红外二极管的波长不对,于是跑到了鞍山西道,分别找了4家,买了各式各样不同的红外二极管。本以为会好了,但回来一试,还是一样 。于是我一狠心,把红外遥控器拆掉,把外面塑料皮拆掉的时候还挺心疼 , 拿万用表打红外的波形,看到了结果以后,我忽然间想起了数据手册里的一句话,信号被调制在37.92khz 于是忽然明白。hs0038需要在发光管发射38khz频率的时候,才会变成低电平。否则一直会是高电平。于是将单片机的高低电平改为了38k频率的方波,再一试,这回hs0038上面有了反映 由于使用的单片机是stm8的,可以通过定时器来产生38k方波,这样的话,就方便多了,如果要是在程序中实现38k,肯定需要延时的调试。时序方便控制不容易。由于使用了定时器来产生38k方波,那么直接配置就好了。控制的时候,通过开启和关闭定时器即可。这样的话,就可以驱动高低电平一样的方便了。所以大家在使用的时候一定要注意。不要简单的以为红外接收,都是和光敏三极管类似,那么你在调试的时候,就比较麻烦了。
以下是初始化配置函数,和红外发射函数,
使用的单片机为stm8s103,没有使用外部晶振,若用其他的单片机或晶振,在发送函数中的软件延时,还要通过示波器来调试。
还有一个问题,就是关于编译器的优化,这东西在时序要求很高的时候,尽量采用一些方式,把优化关掉,否则,软件延时很可能会有误差,从而造成通讯的问题。

void init()
{
    //时钟配置
    CLK_SYSCLKConfig(CLK_PRESCALER_HSIDIV1);//内部高速RC振荡时钟分频  
    CLK_SYSCLKConfig(CLK_PRESCALER_CPUDIV1);//CPU核心时钟分频     
    //IO配置
    //可不用设置,在开启相应外设时,外设会接管io
    //TIM配置
    asm("sim");  // 关全局中断
  
    TIM2->PSCR = 0x00;
    TIM2->ARRH = (u8)(418 >> 8);
    TIM2->ARRL = (u8)(418);
   
    TIM2->CCMR1 = 0x60;
    TIM2->CCER1 = 0x01;
    TIM2->CCMR1 |= 0x08;
    TIM2->CCR1H = 0;
    TIM2->CCR1L = 100;
    TIM2_OC1PreloadConfig(ENABLE); 
     
    TIM2->CCMR2 = 0x60;
    TIM2->CCER1 |= 0x10;
    TIM2->CCMR2 |= 0x08;
    TIM2->CCR2H = 1;
    TIM2->CCR2L = 0;
    TIM2->CCMR3 = 0x60;
    TIM2->CCER2 |= 0x01;
    TIM2->CCMR3 |= 0x08;
    TIM2->CCR3H = 1;
    TIM2->CCR3L = 0;
    TIM2->CR1 |= 0x81;
   
   
   
    GPIOD->DDR &= ~(1<<5);
    GPIOD->CR1 |= (1<<5);
    GPIOD->ODR |= (1<<5);       
               
    GPIOD->DDR &= ~(1<<6);
    GPIOD->CR1 |= (1<<6);
    GPIOD->ODR |= (1<<6);
   
    GPIO_Init(GPIOD, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST);
   
    UART1->BRR2 = 0x02;         // 设置波特率9600
    UART1->BRR1 = 0x68;         // 8M/9600 = 0x341
    UART1->CR2 = 0x2C;          // 允许接收中断,允许接收,允许发送
    UART1->CR1 &=~ (1 << 5);    //使能uart1
    GPIO_DeInit(GPIOB);
    asm("rim");  // 开全局中断
}

 


#pragma optimize=none
void IR_send(u8 add_l,u8 add_h,u8 dat)
{
    u8 t,temp;
    temp =~ dat;
   
    //发送前导码
    IR_1;
    IR_delay(4350);
    IR_0;
    IR_delay(2200); 
   
    for(t = 0; t < 8; t++) //发送低8位地址
    {
        if(add_l&0x01)
        {
            IR_1;
            IR_delay(300);
            IR_0;
            IR_delay(800);
        }
        else
        {
            IR_1;
            IR_delay(270);
            IR_0;
            IR_delay(270);
        }
        add_l >>= 1;
    } 
   
    for(t = 0; t < 8; t++) //发送高8位地址
    {
        if(add_h&0x01)
        {
            IR_1;
            IR_delay(300);
            IR_0;
            IR_delay(800);
        }
        else
        {
            IR_1;
            IR_delay(270);
            IR_0;
            IR_delay(270);
        }
        add_h >>= 1;
    }
   
    for(t = 0; t < 8; t++) //发送8位数据
    {
        if(dat&0x01)
        {
            IR_1;
            IR_delay(300);
            IR_0;
            IR_delay(800);
           
        }
        else
        {
            IR_1;
            IR_delay(270);
            IR_0;
            IR_delay(270);
           
        }
        dat >>= 1;
    }
   
    for(t = 0; t < 8; t++) //发送8位数据反码
    {
        if(temp&0x01)
        {
            IR_1;
            IR_delay(300);
            IR_0;
            IR_delay(800);
        }
        else
        {
            IR_1;
            IR_delay(270);
            IR_0;
            IR_delay(270);
        }
        temp >>= 1;
    }
   
    IR_1;IR_delay(270);
    IR_0;IR_delay(270);
   
}

关闭窗口

相关文章