;********************************************************
//----------------------------------------------------------------------
//UART.C
//通用模拟串口程序
//资源需求:一个硬件计数器,两个I/O口
//硬件计数器的计数时间设定为三倍波特率
//定义的两个I/O口,用于发送和接收,分别用在receive()和transmit(char)中
//设立了专门的接收缓冲区,用于存储接收数据
//注意:必需根据波特率来设定定时器;
//每次通信开始必须调用初始化函数init_uart()
//----------------------------------------------------------------------------------------------------------------
//----------------------------------管脚定义、库函数声明-------------------------------------------------
#include<reg51.h>
#include<stdio.h>
//端口定义
sbitRXD3=P1^0;
sbitTXD3=P1^1;
//-----------------------------------------------变量声明-----------------------------------------------------
#defineIN_BUF_SIZE10//输入缓冲区长度定义
#defineTRUE1
#defineFALSE0
staticunsignedcharinbuf[IN_BUF_SIZE];//输入缓冲区
staticunsignedcharqin=0;
staticunsignedcharqout=0;
staticcharflag_rx_waiting_for_stop_bit;
staticcharflag_rx_off;
staticcharrx_mask;
staticcharflag_rx_ready;
staticcharflag_tx_ready;
staticchartimer_rx_ctr;
staticchartimer_tx_ctr;
staticcharbits_left_in_rx;
staticcharbits_left_in_tx;
staticcharrx_num_of_bits;
staticchartx_num_of_bits;
staticcharinternal_rx_buffer;
staticcharinternal_tx_buffer;
staticcharuser_tx_buffer;
//----------------------------------与硬件有关的函数声明------------------------------------------------
bitget_rx_pin_status();//1.返回接收管脚返回的值(0或1)
voidset_tx_pin_high(void);//2.发送管脚置高,输出1
voidset_tx_pin_low();//3.发送管脚置低,输出0
voidtimer_set();//4.设置定时器的值为波特率的三倍
voidset_timer_interrupt();//5.使能定时器中断
voididle();//6.等待端口输入时,执行,根据具体应用进行修改
//-----------------------------------声明与硬件无关的函数-------------------------------------------
voidflush_input_buffer(void);//清空接收缓存区
charkbhit(void);//判断数据是否正常接收
charget_char(void);//从接收缓存区读出一个数据
voidturn_rx_on(void);//启动接收函数
voidturn_rx_off(void);//结束接收函数
externvoidput_char(char);//向发送端发送一个数据.
voidtimer_isr(void);//中断处理函数
//-------------------------------------------------------------------------------------------------------
//函数名称:set_tx_pin_high
//功能说明:置串口发送端口为高,与硬件有关
//--------------------------------------------------------------------------------------------------------
voidset_tx_pin_high(void)
{
TXD3=1;
}
//-------------------------------------------------------------------------------------------------------
//函数名称:set_tx_pin_low
//功能说明:置串口发送端口为低,与硬件有关
//--------------------------------------------------------------------------------------------------------
voidset_tx_pin_low(void)
{
TXD3=0;
}
//-------------------------------------------------------------------------------------------------------
//函数名称:get_rx_pin_status
//功能说明:返回接收端口的状态,高为1,低为0,与硬件有关
//--------------------------------------------------------------------------------------------------------
bitget_rx_pin_status()
{
return(RXD3);
}
//-------------------------------------------------------------------------------------------------------
//函数名称:timer_set
//功能说明:设置定时器工作状态,与硬件有关
//--------------------------------------------------------------------------------------------------------
voidtimer_set()
{
TMOD=0x22;//定时器1为工作模式2(8位自动重装),0为模式2(8位自动重装)
PCON=0x00;
TR0=0;//在发送或接收才开始使用
TF0=0;
TH0=(256-96);//9600bps就是1000000/9600=104.167微秒执行的timer是
//104.167*11.0592/12=96
TL0=TH0;
ET0=1;
}
//-------------------------------------------------------------------------------------------------------
//函数名称:set_timer_interrupt
//功能说明:打开定时器中断允许,与硬件有关
//--------------------------------------------------------------------------------------------------------
voidset_timer_interrupt()
{
EA=1;
}
//-------------------------------------------------------------------------------------------------------
//函数名称:IntTimer0
//功能说明:定时器中断函数,与硬件有关,但不做处理,直接调用通用中断处理函数
//--------------------------------------------------------------------------------------------------------
voidIntTimer0()interrupt1
{
timer_isr();//调用中断处理函数
}
//-------------------------------------------------------------------------------------------------------
//函数名称:idle
//功能说明:等待定时器中断时的执行程序,与具体应用有关
//--------------------------------------------------------------------------------------------------------
voididle()
{
}
//-------------------------------------------------------------------------------------------------------
//函数名称:timer_isr
//功能说明:中断处理函数,与硬件无关,通用函数
//--------------------------------------------------------------------------------------------------------
voidtimer_isr(void)/*中断服务程序*/
{
charmask,start_bit,flag_in;
//发送程序
if(flag_tx_ready)
{
if(--timer_tx_ctr<=0)
{
mask=internal_tx_buffer&1;
internal_tx_buffer>>=1;
if(mask)
{
set_tx_pin_high();
}
else
{
set_tx_pin_low();
}
timer_tx_ctr=3;
if(--bits_left_in_tx<=0)
{
flag_tx_ready=FALSE;
}
}
}
//接收程序
if(flag_rx_off==FALSE)
{
if(flag_rx_waiting_for_stop_bit)
{
if(--timer_rx_ctr<=0)
{
flag_rx_waiting_for_stop_bit=FALSE;
flag_rx_ready=FALSE;
internal_rx_buffer&=0xFF;
if(internal_rx_buffer!=0xC2)
{
inbuf[qin]=internal_rx_buffer;
if(++qin>=IN_BUF_SIZE)
{
qin=0;
}
}
}
}
else//rx_test_busy接收忙
{
if(flag_rx_ready==FALSE)
{
start_bit=get_rx_pin_status();
//判断起始位
if(start_bit==0)
{
flag_rx_ready=TRUE;
internal_rx_buffer=0;
timer_rx_ctr=4;
bits_left_in_rx=
rx_num_of_bits;
rx_mask=1;
}
}
else
{
if(--timer_rx_ctr<=0)
{
timer_rx_ctr=3;
flag_in=
get_rx_pin_status();
if(flag_in)
{
internal_rx_buffer|=rx_mask;
}
rx_mask<<=1;
if(--bits_left_in_rx<=0)
{
flag_rx_waiting_for_stop_bit=TRUE;
}
}
}
}
}
}
//-------------------------------------------------------------------------------------------------------
//函数名称:init_uart
//功能说明:初始化异步串口,与硬件无关,通用函数
//--------------------------------------------------------------------------------------------------------
voidinit_uart(void)
{
flag_tx_ready=FALSE;
flag_rx_ready=FALSE;
flag_rx_waiting_for_stop_bit=FALSE;
flag_rx_off=FALSE;
rx_num_of_bits=10;
tx_num_of_bits=10;
set_tx_pin_low();
timer_set();
set_timer_interrupt();//使能计时器中断
}
//-------------------------------------------------------------------------------------------------------
//函数名称:get_char
//输入参数:无
//输出参数:ch,接收数据
//功能说明:接收一个字节,与硬件无关,通用函数
//--------------------------------------------------------------------------------------------------------
charget_char(void)
{
charch;
do
{
while(qout==qin)
{
idle();
}
ch=inbuf[qout]&0xFF;
if(++qout>=IN_BUF_SIZE)
{
qout=0;
}
}
while(ch==0x0A||ch==0xC2);
return(ch);
}
//-----------------------------------------------------------------------------------------
//函数名称:put_char
//功能说明:接收一个字节,与硬件无关,通用函数
//-----------------------------------------------------------------------------------------
voidput_char(charch)
{
while(flag_tx_ready);
user_tx_buffer=ch;
//唤醒串口
timer_tx_ctr=3;
bits_left_in_tx=tx_num_of_bits;
internal_tx_buffer=(user_tx_buffer<<1)|0x200;
flag_tx_ready=TRUE;
}
//-------------------------------------------------------------------------------------------------------
//函数名称:flush_input_buffer
//功能说明:初始化缓冲区,与硬件无关,通用函数
//--------------------------------------------------------------------------------------------------------
voidflush_input_buffer(void)
{
qin=0;
qout=0;
}
//-----------------------------------------------------------------------------------------
//函数名称:kbhit
//功能说明:判断接收指针与发送指针是否相等,与硬件无关,通用函数
//-----------------------------------------------------------------------------------------
charkbhit(void)
{
return(qin!=qout);
}
//-----------------------------------------------------------------------------------------
//函数名称:turn_rx_on
//功能说明:开始接收,与硬件无关,通用函数
//-----------------------------------------------------------------------------------------
voidturn_rx_on(void)
{
flag_rx_off=FALSE;
}
//-----------------------------------------------------------------------------------------
//函数名称:turn_rx_off
//功能说明:停止接收,与硬件无关,通用函数
//-----------------------------------------------------------------------------------------
voidturn_rx_off(void)
{
flag_rx_off=TRUE;
}