单片机做红外遥控发射码,引导码延时就是不对,求助!
大家好,
从网上DOWN了程序,优化了一下,主要想调整NEC编码的占空比(不是38K载波的占空比),但是实际测试输出LEAD波形时并不按设计的走(地址码与数据码都未发现有问题),如,695次调用TIMER0中断,输出延时是对的,但是900次调用中断后就不对了,感觉哪里有东西打断了进程?也尝试在不同的地方加中断、计数使能,但是总有问题。
我用的是STC12C5202AD单片机,用KEIL 5编译,已经将芯片导入到KEIL里,使用外部12M晶振。
代码如下:
------------------------自定义头文件----------------------------
#ifndef _C51_ZY_H_
#define _C51_ZY_H_
void UartInit();
void delay_us(int i);
void IR_transfer(char iraddr1,char iraddr2,charp_irdat);
void timer0_int_13us(void);
void delay_100ms(int k) ;
#endif
---------------主程序-----------------------------------------
#include<reg51.h>
#include <C51_ZY.h>
sbit P1_1=P1^1; // LED
char iraddr1=0x44; //thefirst byte of the hex address
char iraddr2=0x9b; //the second byte of the hex address
char p_irdata=0x12; //IRDATA
void main(void)
{
P1_1=0;
AUXR |= 0x80; //SET TIMER0 1T MODE
P1M1 &= 0xF7;
P1M0 |= 0x08; //SET P1_3 PUSH-PULL MODE
//UartInit();
IR_transfer(iraddr1,iraddr2,p_irdata);
//delay_us(10);
}
----------------------TIMER0初始化-----------------------------
#include <reg51.h>
#include <C51_ZY.h>
void timer0_int_13us(void)
{
AUXR |= 0x80; //定时器时钟1T模式
TMOD &=0xF0; //设置定时器模式
TMOD |= 0x01; //设置定时器模式
ET0 = 1;
TL0 = 0x64; //设置定时初值
TH0 = 0xFF; //设置定时初值
TF0 = 0; //清除TF0标志
TR0 = 1; //定时器0开始计时
}
-----------------------延时子程序--------------------------
void delay_100ms(int k)
{
int i,j;
for(k;k>0;k--)
{
for(i=0;i<150;i++)
{
for(j=0;j<400;j++);
}
}
}
--------------------发射程序---------------------------
#define uchar unsigned char //just for convenience
#define uint unsigned int
#define ulong unsigned long
#include <reg51.h> //the standard head file
#include <C51_ZY.h>
static bit OP; //the turn on or off of the IR led
int count; //delay count
int endcount; //terminate count
unsigned char flag; //the flag of IR emission
sbit P1_3=P1^3; // IRpin
extern char iraddr1; //the first byte of the hex address
extern char iraddr2; //the second byte of the hex address
extern char p_irdata; //IR DATA
int test_mode;//0 mean constant period,1 meanconstant duty cycle
int logic_high;
int logic0_low;
int logic1_low;
int lead_high;
int lead_low;
void SendIRdata();
void IR_transfer(char iraddr1,char iraddr2,charp_irdata);
//void delay_us(int i);
//void timer0_int_13us(void);
void IR_transfer(char iraddr1,char iraddr2,charp_irdata)
{
count=0;
flag=0;
OP=0;
P1_3=0;
EA = 1; // permit cpuinterrupt
timer0_int_13us();
//TMOD = 0x11; //set timer0&1 to the HEXmode of 1
//ET0 = 1; //permittimer0 interrupt
//TH0 = 0xFF;
//TL0 = 0x7d; //set timer0 have ainterrup per 13us(38k/2)
//TR0 = 1; //start count
test_mode=0; //0 mean constant period,1 mean constant duty cycle
logic_high=43; //43=0%;34=-20%,52=+20%;21=-50%,65=+50%
lead_high=903; //625(-10%),556(-20%),486(-30%),417(-40%),347(-50%)
//695(0%)
//764(+10%),834(+20%),903(+30%),973(+40%),1000(+45%)
if(test_mode==0)
{
lead_low=350;//1045 is standard,
logic1_low=173-logic_high; //173 is standard,
logic0_low=87-logic_high; //87 is standard,
}
else
{
lead_low=lead_high/2+1; //+1 为了补偿中断子程序中取反操作与赋值操作的时间差
logic0_low=logic_high+1;
logic1_low=logic_high*3+1;
}
do{
//ET0=0;
//TR0=1;
//EA=1;
SendIRdata();
//TR0=0;
//ET0=0;
//EA=0;
delay_100ms(5);
}
while(1);
}
void SendIRdata()
{
int i;
char irdata;
//---------------send thestarting code of 9ms---------------------
endcount=lead_high; //690 is standard,
flag=1;
count=0;
//ET0=1;TR0=1;
do{}while(count<endcount);
//---------------send the endingcode of 4.5ms--------------------
//ET0=0;TR0=0;
endcount=lead_low; //
flag=0;
count=0;
//ET0=1;TR0=1;
do{}while(count<endcount);
//ET0=0;TR0=0;
//-----------------send the first 8 bit of theaddress----------------
irdata=iraddr1;
for(i=0;i<8;i++)
{
//---------------first,send 0.56ms ir wave(38k),voltagehigh-----------
//ET0=1;TR0=1;
endcount=logic_high;
flag=1;
count=0;
do{}while(count<endcount);
//----------------stopsend ir wave,voltage low-----------------
if(irdata-(irdata/2)*2) //judge the last binary bit is 1 or 0
{
endcount=logic1_low; //1 mean wide low level
}
else
{
endcount=logic0_low; //0 mean narrow low level
}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//-------------send the last 8 bit of the HEXaddress-----------------
irdata=iraddr2;
for(i=0;i<8;i++)
{
endcount=logic_high;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{endcount=logic1_low;}
else
{endcount=logic0_low;}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//------------------send 8 bit data---------------------
irdata=p_irdata;
for(i=0;i<8;i++)
{
endcount=logic_high;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{endcount=logic1_low;}
else
{endcount=logic0_low;}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
//---------------------send the 8 bit complementdata----------------------
irdata=~p_irdata;
for(i=0;i<8;i++)
{
endcount=logic_high;
flag=1;
count=0;
do{}while(count<endcount);
if(irdata-(irdata/2)*2)
{endcount=logic1_low;}
else
{endcount=logic0_low;}
flag=0;
count=0;
do{}while(count<endcount);
irdata=irdata>>1;
}
endcount=logic_high;
flag=1;
count=0;
do{}while(count<endcount);
flag=0;
P1_3=0;
//ET0 = 0;
}
//***********************************************************************************
//timer0execute interrupt
void timeint(void) interrupt 1 using1
{
//ET0=0;
TH0=0xFF;
TL0=0x7E;
TR0=0;
count++;
if(flag==1)
{
OP=~OP;
}
else
{OP = 0;}
P1_3 =OP;
//ET0=1;
TR0=1;
}
-------------------------------
自己顶。