最近开发一个项目,想用STC15系列来作为控制芯片,主要看中它的功能还比较丰富,尤其是有四个串口资源,在8位单片机中算是少有,但是开发起来就发现官方提供的库里面只提供了两个串口的库函数,官方提供的库函数的使用相对复杂(要先用结构填一堆参数),本人读了下代码还有一些隐患。
相比现在比较火热的Arduino,51系列单片机的易用性差了好大的一截,宏晶的老大应该在开发易用方面下点功夫。
能给开发者提供一个傻瓜式的调用函数是最好的,串口用到现在,其实参数基本固定了。
常用的协议就是8数据位,1停止位,无校验位,常用的波特率考虑两个就够了,一个是9600,一个是115200。
基于使用最方便的考虑,本人写了一个调用相对简单的库,供大家参考。
本文中的函数库写采用的是同步方式,每次都是等待发送完毕后才返回;读则取采用异步,如果没有数据则返回-1;
好了,开发者最好的语言是代码,下面就贴代码
首先是xyusart.h文件,引用了stc官方库的config.h文件,文件内容如下
//STC15WxxxxS4 系列4串口使用函数库
//开发者,北京创世星辰机器人科技,星辰李
//本程序遵循GPL协议,转载请保留注释和出处
//2016.1.5
#ifndef __XYUSART_H
#define __XYUSART_H
#include "config.h"
#define BAUD9600 0 //波特率9600
#define BAUD115200 1 //波特率115200
//只有一种模式8位数据位,1位停止位,无奇偶校验,只有两种传输速率9600和115200,简化调用者的使用,引脚都使用默认引脚
void S1_init(u8 baud); //初始化串口1 P3.0->RXD P3.1->TXD
void S2_init(u8 baud); //初始化串口2 P1.0->RXD2 P1.1->TXD2
void S3_init(u8 baud); //初始化串口3 P0.0->RXD3 P0.1->TXD3
void S4_init(u8 baud); //初始化串口4 P0.2->RXD4 P0.3->TXD4
void S1_send(u8 c); //串口1发送一个字节
void S2_send(u8 c); //串口2发送一个字节
void S3_send(u8 c); //串口3发送一个字节
void S4_send(u8 c); //串口4发送一个字节
short S1_read(); //串口1,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
short S2_read(); //串口2,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
short S3_read(); //串口3,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
short S4_read(); //串口4,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
#endif
文件中注释已经把用法写得相当清楚,比如S1_init(BAUD9600)代表初始化串口1,8数据位,1停止位,无校验位,波特率9600;
然后是xyusart.c文件
//STC15WxxxxS4 系列4串口使用函数库
//开发者,北京创世星辰机器人科技,星辰李
//本程序遵循GPL协议,转载请保留注释和出处
//2016.1.5
#include "xyusart.h"
#define S3RI 0x01 //S3CON.0
#define S3TI 0x02 //S3CON.1
#define S2RI 0x01 //S2CON.0
#define S2TI 0x02 //S2CON.1
#define S4RI 0x01 //S4CON.0
#define S4TI 0x02 //S4CON.1
void S1_init(u8 baud){ //初始化串口1 P3.0->RXD P3.1->TXD
u32 baudrate;
if (baud)
baudrate=115200;
else
baudrate=9600;
SCON = 0x50;
AUXR |= 0x40;
AUXR &= ~0x01;
TMOD = 0x00;
TL1 = (65536 - (MAIN_Fosc/4/baudrate));
TH1 = (65536 - (MAIN_Fosc/4/baudrate))>>8;
TR1 = 1;
ES = 1;
EA = 1;
}
void S2_init(u8 baud){ //初始化串口2 P1.0->RXD2 P1.1->TXD2
u32 baudrate;
if (baud)
baudrate=115200;
else
baudrate=9600;
S2CON = 0x50; //8-bit variable UART
T2L = (65536 - (MAIN_Fosc/4/baudrate));
T2H = (65536 - (MAIN_Fosc/4/baudrate))>>8;
AUXR &= ~(1<<3);
AUXR |= (1<<2);
AUXR |= (1<<4);
// AUXR |= 0x14;
IE2 |= 0x01;
EA = 1;
}
void S3_init(u8 baud){ //初始化串口3 P0.0->RXD3 P0.1->TXD3
u32 baudrate;
if (baud)
baudrate=115200;
else
baudrate=9600;
S3CON = 0x50;
T3L = (65536 - (MAIN_Fosc/4/baudrate));
T3H = (65536 - (MAIN_Fosc/4/baudrate))>>8;
T4T3M |= 0x02;
T4T3M |= 0x08;
IE2 |= 0x08;
EA = 1;
}
void S4_init(u8 baud){ //初始化串口4 P0.2->RXD4 P0.3->TXD4
u32 baudrate;
if (baud)
baudrate=115200;
else
baudrate=9600;
S4CON = 0x50;
T4L = (65536 - (MAIN_Fosc/4/baudrate));
T4H = (65536 - (MAIN_Fosc/4/baudrate))>>8;
T4T3M |= 0x20;
T4T3M |= 0x80;
IE2 |= 0x10;
EA = 1;
}
void S1_send(u8 c){//串口1发送一个字节
SBUF = c;
while (!TI);
TI = 0;
return ;
}
void S2_send(u8 c){ //串口2发送一个字节
S2BUF = c;
while (!(S2CON & S2TI));
S2CON &= ~S2TI;
return ;
}
void S3_send(u8 c){ //串口3发送一个字节
S3BUF = c;
while (!(S3CON & S3TI));
S3CON &= ~S3TI;
return ;
}
void S4_send(u8 c){ //串口4发送一个字节
S4BUF = c;
while (!(S4CON & S4TI));
S4CON &= ~S4TI;
return ;
}
short S1_read(){ //串口1,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
short c;
if (RI)
{
c=SBUF;
RI=0;
}
else
c=-1;
return c;
}
short S2_read(){ //串口2,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
short c;
if (S2CON & S2RI)
{
c = S2BUF;
S2CON &= ~S2RI;
}
else
c = -1;
return c;
}
short S3_read(){ //串口3,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
short c;
if (S3CON & S3RI)
{
c = S3BUF;
S3CON &= ~S3RI;
}
else
c = -1;
return c ;
}
short S4_read(){ //串口4,读一个字节 ,返回>0表示成功读取数据,返回-1表示没有读到数据,数据放在c中
short c;
if (S4CON & S4RI)
{
c = S4BUF;
S4CON &= ~S4RI;
}
else
c = -1;
return c ;
}
使用例子:
#include "xyusart.h"
#incoude "config.h" //来自于stc15的库函数
void main()
{
short c;
unsigned char d;
S1_init(BAUD9600);
while(1){
c=S1_read(); //读取串口1
if (c>=0){ //将读到的字节回送串口1
d= c & 0xff;
S1_send(d);
}
}
}
本次写的库函数是查询读和同步写的方式,不够完善,有空的话,把它完善成中断方式,并带读写缓冲的库。