51模拟串口
热度 1已有 463 次阅读2015-9-19 17:21
|个人分类:51
#include <reg51.h>
#define uchar unsigned char
#define uint unsigned int
sbit Tx_Pin = P1^1;
sbit Rx_Pin = P1^2; //定义接收、发送引脚
/*******************************************
I/O口模拟232通讯程序
使用两种方式的C程序 占用定时器0
/******************************************/
#define MODE //定义工作模式,决定使用哪种算法
#define Flg F0 //标志位,使用PSW的F0位
#define Start_Timer0 TL0=TH0;TR0=1; //定时计数器0的启动处理
#define Close_Timer0 TR0=0; //定时计数器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 Timer0() interrupt 1 //定时计数器中断处理
{
Flg = 1; //置位标志位
}
//发送一个字符
void SendByte(uchar adata)
{
#ifdef MODE //算法一
ACC = adata; //待发送数据放入ACC
Flg = 0;
Tx_Pin = 0; //启动位
Start_Timer0; //启动定时器
while(!Flg)
;
Tx_Pin = ACC0; //先送出低位
Flg = 0;
while(!Flg)
;
Tx_Pin = ACC1;
Flg = 0;
while(!Flg)
;
Tx_Pin = ACC2;
Flg = 0;
while(!Flg)
;
Tx_Pin = ACC3;
Flg = 0;
while(!Flg)
;
Tx_Pin = ACC4;
Flg = 0;
while(!Flg)
;
Tx_Pin = ACC5;
Flg = 0;
while(!Flg)
;
Tx_Pin = ACC6;
Flg = 0;
while(!Flg)
;
Tx_Pin = ACC7;
Flg = 0;
while(!Flg) //停止位
;
Tx_Pin = 1;
Flg = 0;
while(!Flg)
;
Close_Timer0; //停止定时计数器
#else //第二种算法
uchar j;
j = 0;
Flg = 0; //初始化
Tx_Pin = 0; //起始位
Start_Timer0; //启动定时计数器
while(!Flg)
;
while(j<8) //如果没有发送完一个字节
{
if(adata&1) //如果待发送位是1
{
Tx_Pin = 1;
}
else //如果待发送位是0
{
Tx_Pin = 0;
}
Flg = 0;
while(!Flg)
;
j++;
adata>>=1; //移位
}
Tx_Pin = 1;
Flg = 0;
while(!Flg) //停止发送
;
#endif
Close_Timer0; //停止定时计数器
}
//接收一个字符
uchar RecByte()
{
#ifdef MODE //算法一
Start_Timer0;
Flg = 0;
while(!Flg) //等待起始位
;
ACC0 = Rx_Pin; //接收一位数据
TL0 = TH0;
Flg = 0;
while(!Flg)
;
ACC1 = Rx_Pin;
Flg = 0;
while(!Flg)
;
ACC2 = Rx_Pin;
Flg = 0;
while(!Flg)
;
ACC3 = Rx_Pin;
Flg = 0;
while(!Flg)
;
ACC4 = Rx_Pin;
Flg = 0;
while(!Flg)
;
ACC5 = Rx_Pin;
Flg = 0;
while(!Flg)
;
ACC6 = Rx_Pin;
Flg = 0;
while(!Flg)
;
ACC7 = Rx_Pin;
Flg = 0;
while(!Flg) //等待停止位
{
if(Rx_Pin)
{
break;
}
}
Close_Timer0; //停止timer
return ACC; //函数返回值通过ACC寄存器传递
#else //第二种算法
uchar Rx_Data, j;
Start_Timer0;
Flg = 0;
j = 0;
Rx_Data = 0; //等待起始位
while(!Flg)
;
while(j<8)
{
Rx_Data>>=1;
if(Rx_Pin)
{
Rx_Data |= 0x80; //判断引脚电平
}
j++;
Flg = 0;
while(!Flg)
;
}
Flg = 0;
while(!Flg)
{
if(Rx_Pin)
{
break;
}
}
Close_Timer0; //停止定时计数器
return Rx_Data;
#endif
}
//检查是不是起始位
bit CheckStartBit()
{
return (Rx_Pin == 0); //返回引脚状态
}
void main()
{
uchar temp;
TMOD = 0x02; //定时器0 模式2 8位重装
PCON = 0x00;
TR0 = 0; //在发送或接收才开始使用
TH0 = (256.96);
//9600bps 就是1000000/9600=104.167us 执行时间即是104.167*10.0592/12=96
TL0 = TH0;
ET0 = 1;
EA = 1;
SendByte(0x55);
SendByte(0xaa);
SendByte(0x00);
SendByte(0xff); //发送数据
while(1)
{
if(CheckStartBit()) //如果检测到起始位
{
temp = RecByte(); //接收数据
SendByte(temp); //发送数据
}
}
}