下面是很詳細的51系列模擬串口的程序,可供參考或移植
/************* 本程序功能說明 **************
測試說明
本例程是使用STC系列MCU做的模擬串口。用戶根據(jù)自己的時鐘和波特率自行設置后編譯下載。
使用串口助手向MCU發(fā)送數(shù)據(jù),MCU收到后原樣返回給PC。
本例程使用資源: Timer0中斷.
*/
#include "config.h"
/***************************************************************************/
typedef bit BOOL;
typedef unsigned char uchar;
typedef unsigned int uint;
#define Timer0_Reload (65536 - MAIN_Fosc / BaudRate / 3)
#define D_RxBitLenth 9 //9: 8 + 1 stop
#define D_TxBitLenth 9 //9: 1 stop bit
sbit RXB = P3^0; //define UART TX/RX port
sbit TXB = P3^1;
uchar data TBUF,RBUF;
uchar data TDAT,RDAT;
uchar data TCNT,RCNT; //發(fā)送和接收檢測 計數(shù)器(3倍速率檢測)
uchar data TBIT,RBIT; //發(fā)送和接收的數(shù)據(jù)計數(shù)器
uchar data t, r;
uchar data buf[16];
bit TING,RING; //正在發(fā)送或接收一個字節(jié)
bit REND; //接收完的標志位
#define RxBitLenth 9 //8個數(shù)據(jù)位+1個停止位
#define TxBitLenth 9 //8個數(shù)據(jù)位+1個停止位
//-----------------------------------------
//UART模塊的初始變量 initial UART module variable
void UART_INIT()
{
TING = 0;
RING = 0;
REND = 0;
TCNT = 0;
RCNT = 0;
}
void main()
{
InternalRAM_enable();
// ExternalRAM_enable();
Timer0_1T();
Timer0_AsTimer();
Timer0_16bitAutoReload();
Timer0_Load(Timer0_Reload);
Timer0_InterruptEnable();
Timer0_Run();
EA = 1; //打開總中斷
UART_INIT(); //UART模塊的初始變量
while (1)
{
if (REND) //如果接收完,把接收到的值存入接收buff
{
REND = 0;
buf[r++ & 0x0f] = RBUF;
}
if(!TING) //發(fā)送空閑
{
if (t != r) //有要發(fā)送的數(shù)據(jù)
{
TBUF = buf[t++ & 0x0f];
TING = 1;
}
}
}
}
//-----------------------------------------
//定時器0中斷程序for UART 以波特率3倍的速度采樣判斷 開始位
void tm0(void) interrupt 1
{
if (RING)
{
if (--RCNT == 0) //接收數(shù)據(jù)以定時器的1/3來接收
{
RCNT = 3; //重置接收計數(shù)器 接收數(shù)據(jù)以定時器的1/3來接收
if (--RBIT == 0) //接收完一幀數(shù)據(jù)
{
RBUF = RDAT; //存儲數(shù)據(jù)到緩沖區(qū)
RING = 0; //停止接收
REND = 1; //接收完成標志設置
}
else
{
RDAT >>= 1; //把接收的單b數(shù)據(jù) 暫存到 RDAT(接收緩沖)
if (RXB) RDAT |= 0x80; //shift RX data to RX buffer
}
}
}
else if (!RXB) //判斷是不是開始位 RXB=0;
{
RING = 1; //如果是則設置開始接收標志位 set start receive flag
RCNT = 4; //初始化接收波特率計數(shù)器 initial receive baudrate counter
RBIT = RxBitLenth; //初始化接收的數(shù)據(jù)位數(shù)(8個數(shù)據(jù)位+1個停止位)
}
if (TING) //發(fā)送開始標志位 judge whether sending
{
if (--TCNT == 0) //發(fā)送數(shù)據(jù)以定時器的1/3來發(fā)送
{
TCNT = 3; //重置發(fā)送計數(shù)器 reset send baudrate counter
if (TBIT == 0) //發(fā)送計數(shù)器為0 表明單字節(jié)發(fā)送還沒開始
{
TXB = 0; //發(fā)送開始位 send start bit
TDAT = TBUF; //把緩沖的數(shù)據(jù)放到發(fā)送的buff
TBIT = TxBitLenth; //發(fā)送數(shù)據(jù)位數(shù) (8數(shù)據(jù)位+1停止位)
}
else //發(fā)送計數(shù)器為非0 正在發(fā)送數(shù)據(jù)
{
if (--TBIT == 0) //發(fā)送計數(shù)器減為0 表明單字節(jié)發(fā)送結束
{
TXB = 1; //送停止位數(shù)據(jù)
TING = 0; //發(fā)送停止位 stop send
}
else
{
TDAT >>= 1; //把最低位送到 CY(益處標志位) shift data to CY
TXB = CY; //發(fā)送單b數(shù)據(jù) write CY to TX port
}
}
}
}
} |