以前没有弄过红外发射,这两天恶补了一下,写了个程序,调试中出现了问题,先把程序贴出来:
/*&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//==== 红外遥控器发射程序 ====//
At89s52, 晶振12,
38KHz, 1/38=26.3μS
方波高低各50%,也就是:中断2次: 26.3/2=13.15μS =13μS
几个时序需要的中断次数的计算:
9ms/13μS = 692(次实现)
4.5ms/13 = 346
0.56ms/13 = 43
1.69ms/13 = 130
定时器初值计算:
初值 = 65536 - (f(晶振) * (y)需定时数)/ 12(分频)
本例:f=12 y=13μS
计算:初值 = 65536-13 = 65523 = fff3
红外传输发射协议:
引导码+16位用户数据码+8位设备码+8位识别反码
引导码: 9ms高电平 + 4.5ms低电平
用户码和设备码中:
“1”: 0.56ms高电平 + 1.69ms低电平
“0”: 0.56ms低电平 + 0.56ms低电平
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&& */
#include "reg52.h"
#define uint16 unsigned int
#define uchar unsigned char
sbit ir_Tr =P1^0; //Transmit 发射 //控制发射管的 i/o,
#define ir_Tr_on ir_Tr = 0 //ir=0;低电平启动发射
#define ir_Tr_off ir_Tr = 1
sbit ir_Re =P1^1; //Receive 接收 //接收管输出的i/o
#define ir_Re_True ir_Re == 1 //接收到信号
#define ir_Re_Fales ir_Re == 0
sbit led = P1^3; //接收到信号的指示灯
#define led_on led = 0
#define led_off led = 1
bit ir_Tr_on_flag=0; //发射标志
uchar irsys[4]={0,1,0x12,~0x12}; //16位用户码+设备码+设备反码(这里的数值是随意的)
uint16 count, set_count; //13μs中断计数, 和为得到特定时序的中断次数
//---- 定时器初始化 ------
void Timer_init()
{
TMOD=0x11; //定时器 0、1:均工作在方式 1;
TH0=0xfc; //定时器 0 :系统1ms 时标,晶振=12。 =11.0592时:0xfc66
TL0=0x18;
ET0=1; //允许 0 中断
TR0=1; //开中断 0, 本定时器常开!!
TH1=0xff; //定时器1为红外专用:定时13μs
TL1=0xf3;
ET1=1;
TR1=0; //红外需要时打开!!
PT1=1; //定时器1中断优先
EA=1; //开总中断
}
//---- (定时器0)中断:计时器 ----
uint16 ms_time=0; //ms级计时
uchar s_time=0; //秒级计时
uint16 msForIr=0; //红外定时启动、ms级
void Timer0() interrupt 1
{
TH0=0xfc; //1ms 定时,初值
TL0=0x18;
msForIr++;
if(msForIr>=200) //定时发射一次
{
msForIr=0;
ir_Tr_on; //启动
ir_Tr_on_flag=1; //启用标志
}
ms_time++;
if(ms_time==1000)
{
ms_time=0;
s_time++; //秒级计时
// SecondFor1820++;
if(s_time==60)
{
s_time=0;
// MinuteForPump++; //泵启动计时
}
}
}
//---- (定时器1)中断:38KHz红外专用 -----
void Timer1() interrupt 3
{
TH1=0xff; //13μs 定时 初值
TL1=0xf3;
count++; //中断次数
ir_Tr=~ir_Tr; //方波高、低波换向
}
//----- 发射计时 -----
void ir_On()
{
count=0;
TR1=1;
while(count<set_count); // 1
TR1=0;
}
//----- 发送一个字节(8位)--------
void ir_sendbyte(uchar n)
{
uchar i;
for(i=0;i<8;i++)
{
if(n & 0x01) //发射高电平
{
set_count = 130;
}
else //发射低电平
{
set_count=43;
}
ir_On();
n>>=1; //从低位开始发送
}
}
//---- 发送数据 --------
void ir_Send()
{
uchar i;
set_count=692; //9ms高电平引导
ir_On();
set_count=346; //4.5ms低电平引导
ir_On();
for(i=0;i<4;i++) //连续发射16位用户码和设备码及它的反码
{
ir_sendbyte(irsys);
}
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
void main()
{
Timer_init();
while(1)
{
if(ir_Tr_on_flag) //发射
{
ir_Send();
ir_Tr_on_flag=0;
ir_Tr_off;
}
if(ir_Re_True) //接收
{
led_on;
}
else
{
led_off;
}
}
}
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
问题是:
红外发射专用计时器(定时器1)出现如下情况,看图:
============================
===========================
============================
上图的定时器值是FF,FA;再一个单步就是下图的00 04 了,再一单步就重装初值。
这个定时器初值是TH1=0XFF, TL1=0XF3, 定时13μs,重装初值时TH1是不应该变的,
由于这一变,定时值变为了22μs,多出了9μs,
实际定时值是通过上图所示的sec算出的,定时器1工作方式1,换成工作方式0也不行,
弄一天 了,找不出原因了,望高手们出手相帮,先谢谢了!!
|