从51串口驱动可认识基本串口的使用,这里遇到的主要问题是使用assert时,assert的实现也使用了4号串口中断,导致报警,因此采用数码管来
调试,通过数码管来打印一些变量等
另外,单片机能使用的全局变量区好小啊,定义的BUFFER超过64字节就很难编译通过了
比较坑的是定时器溢出率计算,书里和DATASHEET举了半天例子,就是不直接给出算法,以下式子中,9600目标波特率,
11002000是系统时钟
//(TH1)N== 256-9600*12*32/11002000
以下代码实现从串口读取一串数据,遇到回车(0X0D,0X0A)返回原数据,如果数据小于29字节,会在尾巴加上 ok后返回原数据
有什么疑问与不对欢迎大家交流
#include <reg52.h>
#include <string.h>
//#include <assert.h>
//(TH1)N== 256-9600*12*32/11002000 =256- 3.3 USE 253(0xfd)
#define UINT16 unsigned int
#define BYTE unsigned char
#define UART_MAX_SEND_BUFF 32
#define UART_MAX_RECV_BUFF 32
//#define C51_DEBUG
sbit weBit = P1^6; //数码管使能脚
sbit duBit = P1^7; //数码管显示位控制脚
BYTE digitArr[] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-9,A-F
BYTE weMask[] = {0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
//BYTE* testbuff[5] = {"read1","read2","","","",""};
typedef struct
{
BYTE sendbuff[UART_MAX_SEND_BUFF];
BYTE recvbuff[UART_MAX_RECV_BUFF];
BYTE recvok;//收到0X0D,0X0A通知应用处理
BYTE isSending;
UINT16 sendbytes;
UINT16 sendindex;
UINT16 recvindex;
}UART_DEV_T;
UART_DEV_T uart_dev;
//UINT16 g_timer_cnt = 0;
void Delayms(UINT16 time) //@11.0592MHz
{
BYTE i, j;
UINT16 k;
for (k=0;k<time;k++)
{
i = 2;
j = 199;
do
{
while (--j);
} while (--i);
}
}
void digit_show_hex(UINT16 left,UINT16 right)
{
UINT16 i=0;
BYTE index = 0;
for (i=0;i<8;i++)
{
P0=0;
duBit = 0;
weBit = 1;
P0 = weMask[i];
weBit = 0;
P0=0;
duBit = 1;
if (i<4)
{
index = (left>>(4*(3-i)))&0xf;
}
else
{
index = (right>>(4*(7-i)))&0xf;
}
P0=digitArr[index];
Delayms(2);
}
}
void uart_clock_init(void)
{
TH1 = TL1= 0xfd;
TMOD = 0x20;//自动装载TH1
TR1 = 1;//开始计数
}
void uart_init(void)
{
//SM0 = 0;
//SM1 = 1;//模式1
//SM2 = 1;//收到有效停止位才置中断
//REN = 1;//允许接收
SCON = 0x70;
PCON = PCON&0x3f;//SMOD=0,SMOD0=0
//IPH=IPH|0x10; 52没有该中断优先级寄存器
PS=1; //中断优先级较高
EA = 1;
ES = 1;//打开中断
uart_clock_init();
}
void uart_int_process(void) interrupt 4
{
if (1==RI&&0==uart_dev.recvok)
{//接收
#ifdef C51_DEBUG
assert(uart_dev.recvindex<UART_MAX_RECV_BUFF);
#endif
uart_dev.recvbuff[uart_dev.recvindex] = SBUF;
if (0x0a==uart_dev.recvbuff[uart_dev.recvindex]&&uart_dev.recvindex>0&&0x0d==uart_dev.recvbuff[uart_dev.recvindex-1])
{
uart_dev.recvok = 1;
}
uart_dev.recvindex++;
if (uart_dev.recvindex>=UART_MAX_RECV_BUFF)
uart_dev.recvok = 1;
if (uart_dev.recvok)
SCON = 0x60;//停止接收,等待接收数据被处理
RI = 0;
}
if (1==TI)
{//发送
#ifdef C51_DEBUG
assert(uart_dev.sendbytes>0);
#endif
uart_dev.sendbytes--;
if (0==uart_dev.sendbytes)
{
uart_dev.isSending = 0;
uart_dev.sendindex = 0;
}
else
{
#ifdef C51_DEBUG
assert(uart_dev.sendindex<UART_MAX_SEND_BUFF);
#endif
SBUF=uart_dev.sendbuff[uart_dev.sendindex];
uart_dev.sendindex++;
}
TI = 0;
//uart_send_byte = 0xaa;
}
ES = 1;
}
void uart_send_buffer(BYTE* buff,UINT16 size)
{
#ifdef C51_DEBUG
assert(size<UART_MAX_SEND_BUFF&&0==uart_dev.isSending);
#endif
memcpy(uart_dev.sendbuff,buff,size);
uart_dev.sendbytes = size;
uart_dev.sendindex=1;
SBUF=uart_dev.sendbuff[0];
uart_dev.isSending = 1;
//ES = 0;//关中断,避免BUFFER出错
//ES = 1;//写完BUFFER,打开中断
}
void main(void)
{
UINT16 recvLen = 0;
BYTE recvByte1;
BYTE recvByte2;
uart_init();
if (0==uart_dev.isSending)
{
uart_send_buffer("System Ready!\r\n",15);
}
while (1)
{
if (uart_dev.recvok)
{
recvLen = uart_dev.recvindex;
if (0==uart_dev.isSending)
{
if (uart_dev.recvindex>=3)
{
recvByte1 = uart_dev.recvbuff[uart_dev.recvindex-3];
recvByte2 = uart_dev.recvbuff[uart_dev.recvindex-2];
}
if (uart_dev.recvindex<UART_MAX_RECV_BUFF-3&&uart_dev.recvindex>=2)
{
memcpy(&uart_dev.recvbuff[uart_dev.recvindex-2]," ok\r\n",5);
uart_dev.recvindex+=3;
}
uart_send_buffer(uart_dev.recvbuff,uart_dev.recvindex);
uart_dev.recvok = 0;
uart_dev.recvindex = 0;
SCON = 0x70;//允许接收
}
}
digit_show_hex(recvLen,(recvByte1<<8)|recvByte2);
}
}