把我用的串口通讯程序(中断方式)搭个便车让大家看看,并非原创,从<<嵌入式系统构件>>的相关代码移植而来。
#include "../inc/includes.h"
char xdata ser_buffer[SERIAL_BUFF_SIZE]; /* the receive buffer*/
int ser_end = -1;
int ser_start=-1; /* indexes into receive buffer*/
int ser_ch;
int char_ready=0; /* current character and ready flag*/
int serial_lock = 0; /* serial ISR semaphore so the buffer*/
/* isn't altered will it is being written*/
//功能介绍:串口通讯中断服务程序。
//入口参数:无
//出口参数:无
//备注:系统开中断后由中断触发执行。
void Serial_Isr(void) interrupt 4
{
/* this is the ISR (Interrupt Service Routine) for the com port. It is very*/
/* simple. When it gets called, it gets the next character out of the receive*/
/* buffer register 0 and places it into the software buffer. Note: C takes care*/
/* of all the register saving and house work. Cool huh!*/
/* lock out any other functions so the buffer doesn't get corrupted*/
if(TI)
{
//TI = 0;
return ;
}
if ( !RI )
{
return ; //有数据或无数据用1、0表示
}
serial_lock = 1; /*封锁对串行缓冲区的其它操作*/
/* place character into next position in buffer*/
ser_ch = SBUF;
if (++ser_end > SERIAL_BUFF_SIZE-1)
{
ser_end = 0; /*寻找到循环缓冲区的结尾位置*/
}
ser_buffer[ser_end] = ser_ch; /*将串行口读取到的数据放入队列尾部*/
++char_ready; /*接收数量计数器加1 */
serial_lock = 0; /*打开对串行接收数据缓冲区的锁定*/
RI = 0;
}
/*///////////////////////////////////////////////////////////////////////*/
//功能介绍:检查缓冲区是否接收到数据。获取收到的数据的数量
//入口参数:无
//出口对数:返回接收的数据个数,没有数据返回0
//备注:
int Ready_Serial(char SeriesComID)
{
SeriesComID = SeriesComID;
return(char_ready);
}
/*/////////////////////////////////////////////////////////////////////////*/
// 功能介绍:从串行缓冲接收区中读取1个数据
// 入口参数:存放读取到的数据的地址指针
// 出口参数: 读取成功,返回1,失败时,返回数据0
// 备注:
int Serial_Read(char SeriesComID,char *RdData)
{
/* wait for isr to end*/
SeriesComID = SeriesComID;
while(serial_lock); /*等待串行接收中断完成*/
if (ser_end != ser_start)
{
if (++ser_start > SERIAL_BUFF_SIZE-1) /*移动头指针, 找到读取数据的位置*/
ser_start = 0;
*RdData = ser_buffer[ser_start]; /*从缓冲区中取数*/
/*并送到入口变量中*/
if (char_ready > 0) /*接收数据数量计数器减1*/
--char_ready;
return(1); /*返回读取到数据的成功标志*/
}
else
{
return(0); /*读取失败时,返回读取失败的标志*/
}
}
//功能介绍:将字符的内容从串行口发出
//入口参数:准备发送的数据
//出口参数:无
//备注: 程序中没有使用超时退出机制,如果硬件发生故障,会出现死循环.
void Serial_Write(char SeriesComID,char ch)
{
SeriesComID = SeriesComID;
SBUF = ch;
while ( !TI );
TI = 0;
}
//功能介绍:打开串行口
// 入口参数: port_base 使用串行口的端口号
// baud 串行口设定的波特率
// configuration 串行口工作参数设置,包括数据位数,剞偶校验等
// 出口参数:
// 备注: 请使用头文件中定义的符号常量来设置工作参数
void Open_Serial(int port_base, int baud, int configuration)
{
port_base = port_base;
baud = baud;
configuration = configuration;
//串口初始化
SCON = 0x52; //设置串口
PCON &= 0x80;
TMOD = 0x20;
TH1 = 0xFB; //波特率19200
TL1 = 0xFB;
TR1 = 1;
TI = 0;
ES = 1; //允许串口中断
EA = 1;
}
/*功能介绍:关闭串行口
入口参数:将关闭的串行口号
出口参数:无
备注:
*/
void Close_Serial(int port_base)
{
port_base = port_base;
ES = 0;
}
嵌入式系统构件 Embedded Systems Building Blocks: Complete and Ready-to-Use Modules in C (Hardcover) Jean J. Labrosse (Author) ,准备看之中……
分析一下程序的组成:
打开串行口 void Open_Serial(int port_base, int baud, int configuration)
关闭串行口 void Close_Serial(int port_base)
将字符的内容从串行口发出 void Serial_Write(char SeriesComID,char ch)
从串行缓冲接收区中读取1个数据 int Serial_Read(char SeriesComID,char *RdData)
检查缓冲区是否接收到数据/获取收到的数据的数量int Ready_Serial(char SeriesComID)
串口通讯中断服务程序 void Serial_Isr(void) interrupt 4
使用的数据结构:数组,循环数组
使用semaphore来控制对缓存的访问,只是在void Serial_Isr(void) interrupt 4使用,在int Serial_Read(char SeriesComID,char *RdData)中使用,不怕在读取过程中发生中断吗?读取一个字符这样做可能比较不错,如果字符多了,可能就有点危险的,我认为,在读一个字符的情况下,这样就足够了吧
如何加入超时机制呢?
以后再来修改^^^^^超时机制 环数据结构