找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2302|回复: 0
收起左侧

AVR 红外遥控程序 不知道错在哪里求解

[复制链接]
ID:70636 发表于 2014-12-17 19:38 | 显示全部楼层 |阅读模式

      #define uchar unsigned char
          #define uint  unsigned int
          #include <iom16v.h>
          #include <macros.h>
          #define Set_Bit(val, bitn)    (val |=(1<<(bitn)))
      #define Clr_Bit(val, bitn)    (val&=~(1<<(bitn)))
      #define Get_Bit(val, bitn)    (val &(1<<(bitn)) )
          
      //uchar  disbuf[4]={2,4,6,8};
          //定义数码管显示0~9及a~f,全灭,全亮的字型码,使用unsigned code定义
      uchar discode[18]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x00,0xff};

     //定义带小数点的数码管显示0~9及a~f,全灭,全亮的字型码,使用unsigned code定义
      uchar disbuf[18]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e,0x00,0xff};
      uchar  disbit[4]={0xFE,0xFD,0xFB,0xF7}; //选通值  
          //定义全局变量
uchar t_num=0,i_num=0,guide_ok=0,receive_ok=0;
//定义用来保存零时数据和编码的数组
uchar time[33];
uchar code[4];  //储存用户码、用户反码与键数据码、键数据反码
                                                                                                              
//*****************延时函数ms级***************************//   
void delayms(uint ms)     
{   
  uint i,j;   
    for( i=0;i<ms;i++)   
       for(j=0;j<1141;j++); //1141是在8MHz晶振下
}
/******************延时函数us级**************************/
void delayus(uint us)     
{   
  uint i;   
    us=us*5/4;      //5/4是在8MHz晶振下  
     for( i=0;i<us;i++);  
}
/******************************************************************************/

/***********定时器中断初始化函数***********
功能:设置定时器1中断方式以及分频情况
参数: 8M晶振
返回值:无
******************************************/
void timer1_init()
{
    TCCR1B = 0x01;//设置外部中断1无预分频
    TCNT1H = 0xfd;
    TCNT1L = 0xdd;//设置定时时长为100US
    SREG = 0x80;//开启总中断
}
/***********外部中断初始化函数***********
功能:设置外部中断中断方式以及开启外部中断
参数:无
返回值:无
******************************************/
void int0_init()
{
    MCUCR = 0x02;//设置外部中断0下降沿触发方式
    GICR = 0x40;//开启外部中断0中断
    SREG = 0x80;//开启总中断
}
/***********定时器中断服务程序***********
功能:用于定时器中断时,计时变量加1
参数:无
返回值:无
******************************************/
#progma interrupt_handler timer1_isr:9
void timer1_isr()
{
    t_num++;
}
/***********外部中断服务程序***********
功能:用于在响应外部中断的情况下执行相应操作
参数:无
返回值:无
******************************************/
#progma interrupt_handler int0_isr:2
void int0_isr()
{   
    GICR = 0x00; //关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
    TIMSK = 0x40;//开启定时器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;  //接收完成标志
    }

   GICR = 0x40; //开启外中断0
}
/***********红外解码函数***********
功能:将接收到的计时码转换为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]>6)  //PPM方式判断该bit是0还是1
            {
             dat=0x80;
            }
            k++;
         }
         code[i]=dat;   
     }
     k=0;
     receive_ok=0;
}
/***********主函数***********
功能:主要实现小车运动
参数:无
返回值:无
******************************************/

void main()
{
    DDRA=0xFF;
    PORTA=0x00;
    timer1_init();//定时器1初始化
    int0_init();  //外部中断0初始化
    while(1)
   {  
     if(receive_ok==1)  //判断33位数据是否接收完成
       {
           decode();      //完成接收开始解码
         if(DeCode()==1)  //如果解码完成
         {
         if (code[2]==0x09) {PORTA=0x05;} //如果按下前进键,则小车前进
         if (code[2]==0x15) {PORTA=0x0A;} //如果按下后退键,则小车后退
         if (code[2]==0x47) {PORTA=0x00;} //如果按下停止键,则小车停止
          }
       }
    }
}

不知道

回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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