51模擬串口
熱度 1已有 487 次閱讀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); //發送數據
}
}
}