20120725-51单片机IO口模拟串口通讯4

硬件环境:STC89C52

软件环境:IDE Keil uVision V4.10

                    编译器 C51 V9.0

代码如下:

/**********************************************
硬件:11.0592MHz晶振,STC89C52,RXD P1.0 TXD P1.1
波特率:9600
描述:这是网上《51单片机模拟串口的三种方法》中附的程序
      占用定时器0

时间:2012.07.25 于单位
**********************************************/

#include "reg52.h"
sbit BT_SND =P1^1;
sbit BT_REC =P1^0;
/**********************************************

IO 口模拟232通讯程序

使用两种方式的C程序 占用定时器0

**********************************************/

#define MODE_QUICK

#define F_TM F0

#define TIMER0_ENABLE   TL0=TH0; TR0=1;
#define TIMER0_DISABLE TR0=0;

sbit ACC0=    ACC^0;
sbit ACC1=    ACC^1;
sbit ACC2=    ACC^2;
sbit ACC3=    ACC^3;
sbit ACC4=    ACC^4;
sbit ACC5=    ACC^5;
sbit ACC6=    ACC^6;
sbit ACC7=    ACC^7;

void IntTimer0() interrupt 1
{
	F_TM=1;
}

//发送一个字符
void PSendChar(unsigned char inch)
{
	#ifdef MODE_QUICK
		ACC=inch;
		
		F_TM=0;
		BT_SND=0; 			//start bit
		TIMER0_ENABLE;	 	//启动
		while(!F_TM);
		
		BT_SND=ACC0;		//先送出低位
		F_TM=0;
		while(!F_TM);
		
		BT_SND=ACC1;
		F_TM=0;
		while(!F_TM);
		
		BT_SND=ACC2;
		F_TM=0;
		while(!F_TM);
		
		BT_SND=ACC3;
		F_TM=0;
		while(!F_TM);
		
		BT_SND=ACC4;
		F_TM=0;
		while(!F_TM);
		
		BT_SND=ACC5;
		F_TM=0;
		while(!F_TM);
		
		BT_SND=ACC6;
		F_TM=0;
		while(!F_TM);
		
		BT_SND=ACC7;
		F_TM=0;
		while(!F_TM);
		
		BT_SND=1;
		F_TM=0;
		while(!F_TM);
		
		
		TIMER0_DISABLE; 	//停止timer
	#else
		unsigned char ii;
		
		ii=0;
		
		F_TM=0;
		BT_SND=0; 			//start bit
		TIMER0_ENABLE; 		//启动
		while(!F_TM);
		
		while(ii<8)
		{
		if(inch&1)
		{
		BT_SND=1;
		}
		else
		{
		BT_SND=0;
		}
		F_TM=0;
		while(!F_TM);
		ii++;
		inch>>=1;
		}
		BT_SND=1;
		F_TM=0;
		while(!F_TM);
		
	#endif

	TIMER0_DISABLE; 		//停止timer
}

//接收一个字符
unsigned char PGetChar()
{
	#ifdef MODE_QUICK
	
		TIMER0_ENABLE;
		F_TM=0;
		while(!F_TM); 		//等过起始位
		ACC0=BT_REC;
		
		TL0=TH0;
		
		F_TM=0;
		while(!F_TM);
		ACC1=BT_REC;
		
		F_TM=0;
		while(!F_TM);
		ACC2=BT_REC;
		
		F_TM=0;
		while(!F_TM);
		ACC3=BT_REC;
		
		F_TM=0;
		while(!F_TM);
		ACC4=BT_REC;
		
		F_TM=0;
		while(!F_TM);
		ACC5=BT_REC;
		
		F_TM=0;
		while(!F_TM);
		ACC6=BT_REC;
		
		F_TM=0;
		while(!F_TM);
		ACC7=BT_REC;
		
		F_TM=0;
		
		while(!F_TM)
		{
		if(BT_REC)
		{
		break;
		}
		}
		TIMER0_DISABLE; 	//停止timer
		return ACC;
	#else
		unsigned char rch,ii;
		TIMER0_ENABLE;
		F_TM=0;
		ii=0;
		rch=0;
		while(!F_TM); 		//等过起始位
		
		while(ii<8)
		{
		rch>>=1;
		if(BT_REC)
		{
		rch|=0x80;
		}
		ii++;
		F_TM=0;
		while(!F_TM);
		
		}
		F_TM=0;
		while(!F_TM)
		{
		if(BT_REC)
		{
		break;
		}
		
		}
		TIMER0_DISABLE; 	//停止timer
		return rch;		
	#endif 
}

//检查是不是有起始位
bit StartBitOn()
{
	return   (BT_REC==0); 
}

void main()
{
	unsigned char gch;
	
	TMOD=0x22; /*定时器1为工作模式2(8位自动重装),0为模式2(8位	自动重装) */
	PCON=00;
	
	TR0=0; 				//在发送或接收才开始使用
	TF0=0;
	TH0=(256-96); 		//9600bps 就是 1000000/9600=104.167微秒 执行的timer是104.167*11.0592/12= 96
	TL0=TH0;
	ET0=1;
	EA=1;
	
	PSendChar(0x55);
	PSendChar(0xaa);
	PSendChar(0x00);
	PSendChar(0xff);
	
	while(1)
	{
		if(StartBitOn())
		{
			gch=PGetChar();
			PSendChar(gch);
		}
	}
}


 

你可能感兴趣的:(timer,IO,编译器,BT,通讯)