/********************************************************************************************** **文件名 :RS232.c **功能 :RS232标准有关的函数实现 **建立日期:07/11/14 **版本 :Ver1.0 **说明 :该版本使用在11.0592MHz,固定波特率19200 **修改记录: **********************************************************************************************/ #include"config.h" #include"Port.h" #include"RS232.h" /****一般情况下,与PC通信,接收缓冲区应适当的比发送缓冲区大*****/ #define XBUFLEN 4 //发送缓冲区的长度 #define RBUFLEN 8 //接收缓冲区的长度 /* 可以根据实际情况把缓冲区定义在idata,pdata,xdata*/ static uint8 rbuf[RBUFLEN], xbuf[XBUFLEN]; /*这两个缓冲区遵循队列的先进先出原则 */ static uint8 rcnt, xcnt, rpos, xpos; /*分别用来指示缓冲区的长度和将要出队的数据位置 */ static bit busy; /*指示发送是否忙 */ /********************************************************************************************* *名称:Ser_Init *功能:串口初始化子程序 *参数:无 *返回:无 *说明:初始化串口在11.0529MHZ频率下,使用19200bps **********************************************************************************************/ void Ser_Init (void) { ES = 0; rcnt = xcnt = rpos = xpos = 0; /* 初始化buffer */ busy = 0; SCON = 0x50; /*工作在方式1下,接收允许 */ PCON |= 0x80; /* SMOD = 1; */ TMOD &= 0x0f; /* 使用定时器1 */ TMOD |= 0x20; /*定时器工作在方式2下 */ TL1 = 0xFD; /*波特率为:19200bps 时钟频率为11.059MHz */ TH1 = 0xFD; TR1 = 1; ES = 1; /*开串口中断 */ EA = 1; /*使能中断 */ } /********************************************************************************************* *名称:Ser_Handler *功能:串口中断处理函数 *参数:无 *返回:无 *说明:根据是接收还是发送中断,将数据放入相应的缓冲区 *********************************************************************************************/ void Ser_Handler (void) __interrupt 4 { if (RI) { RI = 0; if (rcnt < RBUFLEN) /* 判断是否还有缓冲区空间可以存放,防止覆盖缓冲区已经存在的数据 */ rbuf [(uint8)(rpos+rcnt++) % RBUFLEN] = SBUF; } if (TI) { TI = 0; if (busy = xcnt) /*注意:这里并不是比较,而是赋值运算,用来判断是否有数据需要发送*/ { xcnt--; /*有数据需要发送 */ SBUF = xbuf [xpos++]; if (xpos >= XBUFLEN) xpos = 0; } } } /********************************************************************************************* *名称:Ser_Putc *功能:串口发送数据函数 *参数:c--要发送的数据 *返回:无 *说明:根据发送是否忙,将进行相应的处理 *********************************************************************************************/ void Ser_Putc (uint8 c) { while (xcnt >= XBUFLEN) /* 等待发送缓冲区有空间可以使用 */ ; ES = 0; if (busy) { //如果发送正忙 xbuf[(uint8)(xpos+xcnt++) % XBUFLEN] = c; //送入发送缓冲区 } else { SBUF = c; //直接发送 busy = 1; } ES = 1; } /********************************************************************************************* *名称:Ser_Getc *功能:串口接收数据函数 *参数:无 *返回:接收的数据 *说明:直接从接收缓冲区取数据 *********************************************************************************************/ uint8 Ser_Getc (void) { uint8 c; while (!rcnt) /* 等待接收缓冲取有数据可读 */ ; ES = 0; rcnt--; c = rbuf [rpos++]; if (rpos >= RBUFLEN) rpos = 0; ES = 1; return (c); } /********************************************************************************************* *名称:Ser_Puts *功能:串口发送字符串函数 *参数:s--发送的字符串地址 *返回:无 *说明:直接调用Ser_Putc发送 *********************************************************************************************/ void Ser_Puts (uint8 *s) { uint8 c; while (c=*s++) { if (c == '\n') Ser_Putc ('\r'); Ser_Putc (c); } } /********************************************************************************************* *名称:Ser_GetS *功能:串口接收送字符函数 *参数:s--接收字符串地址 len--要接收的长度 *返回:无 *说明:直接调用Ser_Getc接收 *********************************************************************************************/ void Ser_Gets (uint8 *s, uint8 len) { uint8 pos, c; pos = 0; while (pos <= len) { c = Ser_Getc (); if (c == '\r') continue; /* 丢弃 CR */ s[pos++] = c; if (c == '\n') break; /* 接收到一行 */ } s[pos] = '\0'; } /******************************************************************************************** *名称:Ser_Can_Xmt *功能:发送缓冲区还可以接收数据的长度 *参数: *返回:返回可放到发送缓冲区的数据长度 *说明: ********************************************************************************************/ uint8 Ser_Can_Xmt (void) { return XBUFLEN - xcnt; } /******************************************************************************************** *名称:Ser_Can_Rcv *功能:接收缓冲区已经有的数据长度 *参数:无 *返回:可读取数据的长度 *说明: ********************************************************************************************/ uint8 Ser_Can_Rcv (void) { return rcnt; }