OpenEdv-开源电子网

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

用遥控器来控制定时器2的初值时,红外解码会出错。

[复制链接]

13

主题

35

帖子

0

精华

初级会员

Rank: 2

积分
107
金钱
107
注册时间
2013-4-4
在线时间
0 小时
发表于 2014-8-13 19:23:01 | 显示全部楼层 |阅读模式
5金钱
我今天用遥控来控制定时器2中TH1,TL1的初值,结果会导致遥控器发送的值在单片机中读取会乱码,只有把TH1,TL1的值确定了之后遥控器才不会乱码。这让我觉得很奇怪,不明白为什么会这样子,如果只是用按键来控制TH1,TL0的值,那不会有问题。
请各位大神帮帮忙,以下是我的代码。

#include<reg52.h>    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
#include"1602.h"
#include"delay.h"
#define uchar unsigned char
#define uint unsigned int
sbit IR=P3^2;  //红外接口标志
sbit key=P2^0;
sbit led=P3^7;

sbit   Dj_Cp1=P1^0;
uchar int_num;

char code Tab[16]="0123456789ABCDEF";
/*------------------------------------------------
                全局变量声明
------------------------------------------------*/
unsigned char  irtime=0;//红外用全局变量
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
unsigned char TempData[16];
#define speed1 5000
uint speed=5000; //频率
uint adj_speed; //档数
/*------------------------------------------------
                  函数声明
------------------------------------------------*/
void EX0init(void);
void TIMinit(void);//定时器0初始化
void Ir_work(void);
void Ircordpro(void);
/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main(void)
{
  DJ_Init();
  TIMinit();           //初始化定时器
  EX0init();            //初始化外部中断
  LCD_Init();           //初始化液晶
  DelayMs(20);          //延时有助于稳定
  LCD_Clear();          //清屏
  LCD_Write_String(0,0,"www.doflye.net");
  LCD_Write_String(0,1,"Code:");
  while(1)//主循环
    {

   if(irok)                        //如果接收好了进行红外处理
     {  
   Ircordpro();
       irok=0;
     }
        if(irpro_ok)                   //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
     {
         Ir_work();
       switch(IRcord[3])
     { 
      //调频
     case 246:   adj_speed=adj_speed+1;  if(adj_speed==10) adj_speed=9; break;
     case 234:   adj_speed=adj_speed-1;  if(adj_speed==0) adj_speed = 1;break;
     default: break;
      }
      switch(adj_speed)
      {
       case 1:  speed = 5000; break; //100HZ  
     case 2:     speed = 3333; break; //150HZ
     case 3:  speed = 2500; break; //200HZ
     case 4:  speed = 2000; break; //250HZ
     case 5:     speed = 1666; break; //300HZ
     case 6:     speed = 1429; break; //350HZ
     case 7:  speed = 1250; break; //400HZ
     case 8:  speed = 1111; break; //450HZ
     case 9:  speed = 1000; break; //500HZ
     default: break;
      }
       }   
    }
}
 
/*------------------------------------------------
                  定时器0中断处理
------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
  irtime++;  //用于计数2个下降沿之间的时间
}
/*------------------------------------------------
                  外部中断0中断处理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
  static unsigned char  i;             //接收红外信号处理
  static bit startflag;                //是否开始处理标志位
if(startflag)                        
   {
    if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
                        i=0;
      irdata=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
      irtime=0;
      i++;
       if(i==33)
         {
       irok=1;
     i=0;
      }
          }
    else
  {
  irtime=0;
  startflag=1;
  }
}
/*------------------------------------------------
                定时器1中断服务子程序
------------------------------------------------*/
void int2_serive(void) interrupt 3
{
 TH1=(65536-speed)/256;
   TL1=(65536-speed)%256;
    int_num++;
 if(int_num==1)
 {
  Dj_Cp1=1; 
 }else
 {
  Dj_Cp1=0;
  int_num = 0;
 }
}
/*------------------------------------------------
                定时器初始化
------------------------------------------------*/
void TIMinit(void)//定时器初始化
{
  TMOD=0x12;//定时器0工作方式2,TH0是重装值,TL0是初值,定时器1工作方式1
  TH0=0x00; //重载值
  TL0=0x00; //初始化值
  TH1=(65536-speed)/256;
  TL1=(65536-speed)%256;
  ET0=1;    //开中断0
  ET1=1;
  TR1=0;    //定时器T1允许中断
  TR0=1;
}
/*------------------------------------------------
                  外部中断0初始化
------------------------------------------------*/
void EX0init(void)
{
 IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
 EX0 = 1;   //使能外部中断
 EA = 1;    //开总中断
}
/*------------------------------------------------
                  键值处理
------------------------------------------------*/
void Ir_work(void)
{
       TempData[0] = Tab[IRcord[0]/16];   //处理客户码
    TempData[1] = Tab[IRcord[0]%16];
       TempData[2] = '-';
    TempData[3] = Tab[IRcord[1]/16];   //处理客户码
    TempData[4] = Tab[IRcord[1]%16];
    TempData[5] = '-';
    TempData[6] = Tab[IRcord[2]/16];   //处理数据码
    TempData[7] = Tab[IRcord[2]%16];
    TempData[8] = '-';
    TempData[9] = Tab[IRcord[3]/16];   //处理数据反码
    TempData[10] = Tab[IRcord[3]%16];
       LCD_Write_String(5,1,TempData);
    irpro_ok=0;//处理完成标志
  }
/*------------------------------------------------
                红外码值处理
------------------------------------------------*/
void Ircordpro(void)//红外码值处理函数
{
  unsigned char i, j, k;
  unsigned char cord,value;
  k=1;
  for(i=0;i<4;i++)      //处理4个字节
     {
      for(j=1;j<=8;j++) //处理1个字节8位
         {
          cord=irdata[k];
          if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
             value|=0x80;
          if(j<8)
      {
    value>>=1;
   }
           k++;
         }
     IRcord=value;
     value=0;    
     }
  irpro_ok=1;//处理完毕标志位置1
}

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

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2014-8-13 22:57:16 | 显示全部楼层
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-11-23 04:47

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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