找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 8062|回复: 8
收起左侧

昨晚上写的AVR红外遥控解码代码

[复制链接]
ID:51090 发表于 2014-10-13 14:54 | 显示全部楼层 |阅读模式
/******************红外遥控器解码源代码****************
编译环境:ICCAVR
编译人员:RJW
编译时间:2013_01_10  06:36
代码功能:实现红外遥控器解码,数码管显示用户码和数据码

*******************************************************/
#include<iom16v.h>
#include<macros.h>
#define uchar unsigned char
#define uint unsigned int
//定义外部中断和定时器中断
#progma interrupt_handler timer1:9
#progma interrupt_handler int0:2
//573使能端宏定义
#define DUAN    PA3
#define WEI     PA4
#define DUAN_OUT   DDRA |= BIT(DUAN)
#define DUAN_SET   PORTA |= BIT(DUAN)
#define DUAN_CLR   PORTA &= ~BIT(DUAN)
#define WEI_OUT   DDRA |= BIT(WEI)
#define WEI_SET   PORTA |= BIT(WEI)
#define WEI_CLR   PORTA &= ~BIT(WEI)
#progma data:code
    const uchar duan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x76};
#progma data:code
    const uchar wei[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf};
//定义全局变量
uchar t_num=0,i_num=0,guide_ok=0,receive_ok=0;
//定义用来保存零时数据和编码的数组
uchar time[33];
uchar code[4]={0x40,0x40,0x040,0x40};
/***********1us延时子函数***********
功能:用于延时1us
参数:无
返回值:无
******************************************/
void delay_1us()
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=3;a>0;a--);
}
/***********nus延时子函数***********
功能:用于延时nus
参数:z:代表延时时长,即本函数可延时范围为:(0~65535us)
返回值:无
******************************************/
void delay_nus(int z)
{
     int i;
     for(i=z;i>0;i--)
     delay_1us();
}
/***********定时器中断初始化函数***********
功能:设置定时器1中断方式以及分频情况
参数:无
返回值:无
******************************************/
void timer1_init()
{
    TCCR1B = 0x01;//设置外部中断1无预分频
    TCNT1H = 0xfb;
    TCNT1L = 0x4f;//设置定时时长为100US
    SREG |= BIT(7);//开启总中断
}
/***********外部中断初始化函数***********
功能:设置外部中断中断方式以及开启外部中断
参数:无
返回值:无
******************************************/
void int0_init()
{
    MCUCR = 0x02;//设置外部中断0下降沿触发方式
    GICR = 0x40;//开启外部中断0中断
    SREG |= BIT(7);//开启总中断
}
/***********定时器中断服务程序***********
功能:用于定时器中断时,计时变量加1
参数:无
返回值:无
******************************************/
void timer1()
{
    t_num++;
}
/***********外部中断服务程序***********
功能:用于在响应外部中断的情况下执行相应操作
参数:无
返回值:无
******************************************/
void int0()
{
    TIMSK |= BIT(2);//开启定时器1中断
    if(i_num==1)  //判断是否是第二次外部中断
   {
       if(t_num>80)//是否是引导码
       {
            guide_ok=1; //是引导码则标志1  
        }
        else
       {
            guide_ok=0;//不是引导码则标志0
        }
    }
    if(guide_ok==1)    //如果是引导码
    {
        time[i_num]=t_num; //将接收的各位数据保存
        t_num=0;         
        i_num++;
    }
    if(i_num==33)
    {
        i_num=0;
        guide_ok==0;    //清楚引导码标志
        receive_ok=1;  //接收完成标志
    }
}
/***********红外解码函数***********
功能:将接收到的计时码转换为16进制码
参数:无
返回值:无
******************************************/
void decode()
{
    uchar i,j,k=1,dat=0;
    for(i=0;i<4;i++)//循环4次取得用户码'用户码'数据码'数据反码
    {
        for(j=0;j<8;j++) //循环8次整合8个bit构成一个字节
        {
            dat>>=1;
            if(time[k]>17)  //PPM方式判断该bit是0还是1
            {
                dat|=0x80;
            }
            k++;
         }
         code[i]=dat;   
     }
     k=0;
     receive_ok=0;
}
/***********数码管显示初始化函数***********
功能:设置数码管段选位选为输出模式
参数:无
返回值:无
******************************************/
void smg_init()
{
     DUAN_OUT;  //设置段选端为输出模式
     WEI_OUT;   //设置位选端为输出模式
     DDRB = 0xff;//设置数据端为输出模式
}
/***********数码管显示函数***********
功能:用于显示用户码和数据码
参数:无
返回值:无
******************************************/
void smg_display()
{  
    uchar i,k=0;
    for(i=1;i<4;i++)
    {
        DUAN_SET;
        PORTB = duan[code[i]/10];   //将每个码字节的数据高4位送入
        DUAN_CLR;

        WEI_SET;
        PORTB = wei[k];
        WEI_CLR;
        delay_nus(500);  //显示驻留500us

        DUAN_SET;
        PORTB = duan[code[i]%10];   //将每个码字节的数据低4位送入
        DUAN_CLR;

        WEI_SET;
        PORTB = wei[k+1];
        WEI_CLR;
        k=k+2;
        delay_nus(500);  //显示驻留500us
     }
     k=0;
}
void main()
{
    smg_init();   //数码管初始化
    timer1_init();//定时器1初始化
    int0_init();  //外部中断0初始化
    while(1)
   {
       if(receive_ok==1)  //判断33位数据是否接收完成
       {
           decode();      //完成接收开始解码
       }
       smg_display();     //显示
    }
}

回复

使用道具 举报

ID:67366 发表于 2014-10-14 13:56 | 显示全部楼层
谢谢楼主
回复

使用道具 举报

ID:72859 发表于 2015-1-27 10:57 | 显示全部楼层
楼主你也没说你的avr是什么型号啊,晶振多少的,还有你的数码管是怎么回事,一个数字9的十六进制还要高四位第四位读写吗?
回复

使用道具 举报

ID:72859 发表于 2015-1-27 11:00 | 显示全部楼层
小泡泡 发表于 2015-1-27 10:57
楼主你也没说你的avr是什么型号啊,晶振多少的,还有你的数码管是怎么回事,一个数字9的十六进制还要高四位 ...

还有你的I_time++,在int0的中断服务程序中何时才能为1,没看到呢
回复

使用道具 举报

ID:75533 发表于 2015-3-28 19:36 | 显示全部楼层
好人!!受教了!!
回复

使用道具 举报

ID:85582 发表于 2015-8-3 14:53 | 显示全部楼层
楼主好人,一生平安
回复

使用道具 举报

ID:67705 发表于 2018-6-2 18:20 来自手机 | 显示全部楼层
正需要,好人呀!
回复

使用道具 举报

ID:308958 发表于 2018-6-8 09:58 | 显示全部楼层
谢谢搂主无私奉献!
回复

使用道具 举报

ID:373684 发表于 2018-7-21 17:00 | 显示全部楼层
控制什么的啊 ??楼主
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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