/*
* FileName: uart.c
* Description: Implementation of SerialPort
* Author: SangWei, HUST-CEEE-2004
* Contact: swkyer@163.com, swkyer@hotmail.com
* Date: 2005-09-22
*
* Platform: STC89C52(STC), KeilC51(ver: 7.20)
*
* (C)All Rights Reserved.
*/
#include <intrins.h>
#include <REGX52.h>
#include "uart.h"
static unsigned char idata uartbuf;
static unsigned char idata bufwptr, bufrptr;
unsigned char idata uartbuff[UARTBUFFLEN];
/* 波特率设置表(22.1184MHZ), 4800, 9600, 19200, 38400, 57600, 115200 */
//static unsigned char code BAUD[] = {0x70, 0xB8, 0xDC, 0xEE, 0xF4, 0xFA};
/* 波特率设置表(11.0592MHZ), 4800, 9600, 19200, 38400, 57600, 115200 */
static unsigned char code BAUD[] = {0xB8, 0xDC, 0xEE, 0xF7, 0xFA, 0xFD};
/*
* 初始化串口, 波特率57600
*/
void UartInit(unsigned char baudrate)
{
ES = 0;
TR2 = 0;
bufwptr = 0; // 写指针
bufrptr = 0; // 读指针
PCON = 0x00; // 设置串口波特率, 时钟频率30MHZ
T2CON = 0x30; // 定时器2作为波特率发生器
SCON = 0x50; // 模式1
// n = 65536 - [fosc/baud*32]
// n = 65536 - 22118400/(57600*32) = 65536 - 12 = 65524 = 0xfff4
RCAP2H = 0xff;
RCAP2L = BAUD[baudrate]; // baud rate 57600
TH2 = 0xff;
TL2 = BAUD[baudrate];
IP = 0x10; // 串口中断优先级高
REN = 1;
TI = 0;
RI = 0;
TR2 = 1; // 启动定时器2
ES = 1; // 使能串口中断
}
/*
* 发送一个字节数据
*/
void SendChar(unsigned char ch)
{
SBUF = ch;
while(TI == 0);
TI = 0;
}
/*
* 发送字符串
*/
void SendString(char *str)
{
while(*str)
{
SendChar(*str);
str++;
}
}
/*
* 判断是否接收到数据,如果没有返回0,如果有,返回数据长度
*/
unsigned char IsUartReceived(void)
{
unsigned char num;
EA = 0; // 关中断
if(bufwptr == bufrptr)
num = 0;
else if(bufwptr > bufrptr)
num = (bufwptr-bufrptr);
else // if(bufwptr < bufrptr)
num = (UARTBUFFLEN-bufwptr+bufrptr);
EA = 1;
return num;
}
/*
* 从缓冲区中读一个字节数据
* 返回剩下的字节数
*/
unsigned char ReadChar(unsigned char idata *buf)
{
unsigned char ch, num;
EA = 0;
if(bufwptr == bufrptr)
{
*buf = 0;
num = 0;
}
else if(bufwptr > bufrptr)
{
ch = uartbuff[bufrptr];
*buf = ch;
bufrptr++;
num = (bufwptr-bufrptr);
}
else // if(bufwptr < bufrptr)
{
ch = uartbuff[bufrptr];
*buf = ch;
bufrptr++;
if(bufrptr == UARTBUFFLEN)
bufrptr = 0;
num = (UARTBUFFLEN-bufrptr+bufwptr);
}
EA = 1;
return num;
}
/*
* 串口中断接受
*/
void UartInt(void) interrupt 4 using 1
{
if(RI)
{
ES = 0;
uartbuf = SBUF;
RI = 0; // 清中断标志
uartbuff[bufwptr] = uartbuf; // 数据写入缓冲区
if(bufwptr >= UARTBUFFLEN-1) // 循环缓冲指针
bufwptr = 0;
else
bufwptr++;
if(bufwptr == bufrptr) // 未读数据被覆盖,读指针更新到写指针的上一个单元
bufrptr = bufwptr + 1;
ES = 1;
}
}
评论0