我今天用遥控来控制定时器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
}
|