#include <reg52.h>
#define uchar unsigned char
#define ushort unsigned short
#define uint unsigned int
#define ulong unsigned long
#define FOSC 12000000 /*frequency oscillate*/
#define BIT_SPEED_1K 1
#define BIT_SPEED_2K 0
#define BIT_SPEED_4K 0
#define BIT_SPEED_8K 0
#if BIT_SPEED_1K
#define PERRIOD_PER_LEVEL 500 /*500um*/
#define T750US (65536-(FOSC/12/1000)*3/4)
#define T1000US (65536-FOSC/12/1000)
#define T_FIRST T750US /*1.5A*/
#define T_FOLLOW T1000US /*2A*/
#elif BIT_SPEED_2K
#define PERRIOD_PER_LEVEL 250 /*250um*/
#define T375US (65536-(FOSC/12/1000)*3/8)
#define T500US (65536-FOSC/12/1000/2)
#define T_FIRST T375US /*1.5A*/
#define T_FOLLOW T500US /*2A*/
#elif BIT_SPEED_4K
#define PERRIOD_PER_LEVEL 125 /*125um*/
#define T187US (65536-(FOSC/12/1000)*3/16)
#define T250US (65536-FOSC/12/1000/4)
#define T_FIRST T187US /*1.5A*/
#define T_FOLLOW T250US /*2A*/
#elif BIT_SPEED_8K
#define PERRIOD_PER_LEVEL 62 /*62.5um*/
#define T94US (65536-(FOSC/12/1000)*3/32)
#define T125US (65536-FOSC/12/1000/8)
#define T_FIRST T94US /*1.5A*/
#define T_FOLLOW T125US /*2A*/
#endif
sbit Din= P0^0; /*曼码输入端*/
ulong rcv_data;
uchar proc_flag=0;
ulong proc_data;
uchar g_RcvState=0;
sbit OUT10=P1^0;
void tm0Init(void)
{
TL0=0;
TH0=0;
TMOD=0x01; //set timer0 as model1 (16-bit)
TF0=0; //Timer0 interrupt flag
TR0=1; //Timer0 Run Control 1-Start, 0-Stop
ET0=0; //timer0 interrupt
}
void tm0_isr() interrupt 1 using 1
{
TL0=T_FOLLOW;
TH0=T_FOLLOW>>8;
OUT10=!OUT10;
if (g_RcvState==(4+3*8))
{
//取电平
rcv_data<<=1;
rcv_data|=Din;
TL0=0;
TH0=0;
ET0=0;//stop timer
proc_data=rcv_data;
proc_flag=1;
g_RcvState=0;
}
if((g_RcvState>=1)&&(g_RcvState<(4+3*8)))
{
//取电平
rcv_data<<=1;
rcv_data|=Din;
g_RcvState++;
}
}
void exint0() interrupt 0//check Falling
{
ushort us_cnt;
if (0==g_RcvState)
{
us_cnt=TH0*256+TL0;
TH0=0;
TL0=0;
if (us_cnt>1350)
{
//出现了持续3个电平的高电平
g_RcvState=1;
//start timer 1.5
TL0=T750US;
TH0=T750US>>8;
TF0=0;
ET0=1; //start the timer0
}
}
}
void main(void)
{
ulong temp_data;
uchar uc_flag=0;
uchar i;
tm0Init();//初始化定时器,但不开始计数
IT0=1; //set INT0 interrupt type(1:Falling, 0:Low level)
EX0=1; //enable INT0 interrupt
EA=1;
while (1)
{
EA=0;
if (proc_flag)
{
temp_data=proc_data;
proc_flag=0;
uc_flag=1;
}
EA=1;
if (uc_flag&&((temp_data&0x0C000001)==0x08000001))
{
//OK
uchar p;
uchar get_data;
temp_data>>=1;
p=temp_data&0x01;
get_data=temp_data>>=1;
for(i=0; i<(8*3); i++)
{
p+=(get_data>>i)&0x01;
}
if (p&0x01)
{
P2=get_data;
}
else
{
P2=0xFF;
}
uc_flag=0;
}
}
}