搜档网
当前位置:搜档网 › STC12C5A系列单片机串口编程

STC12C5A系列单片机串口编程

STC12C5A系列单片机串口编程
STC12C5A系列单片机串口编程

STC12C5A系列单片机串口编程

串口头文件uart.h如下:

=================================================================== /*

* File : uart.h

* Description : This file is UART driver header of STC12C5A serial signal chip.

* Author : Chao

* Copyright : Chao

*

* History

* ----------------------

* Rev : 0.0

* Date : 20/08/2011

*

* create.

* ----------------------

*/

#ifndef UART_H_

#define UART_H_

//---------------Config-------------------------//

#define UART1_EN //使能串口1

#define UART1_RECEIVE_EN //允许串口1中断接收函数

#define UART2_EN //使能串口2

#define UART2_RECEIVE_EN //允许串口2中断接收函数

//#define ECHO //使能回显

//---------------Defines-------------------------//

#define SystemFosc 22118400 //系统时钟:22.1184MHz

#define UartBaud 9600 //串口波特率

#define UART_BUFFER_SIZE 16 //串口数据缓冲区大小

#define UartEndChar '>' //串口数据结束字符

//---------------Type define-------------------------//

typedef struct {

unsigned int receive_flag; //数据接收标志

unsigned char data_length; //数据缓冲区中有效数据个数

unsigned char receive_buffer[UART_BUFFER_SIZE]; //数据接收缓冲区

void (* init)(void); //串口初始化函数

void (* send_byte)(unsigned char ddata); //发送单个字符

void (* send_string)(unsigned char *ddata, unsigned char length); //发送字符串

}UART_T;

//---------------Extern-------------------------//

#ifdef UART1_EN

extern UART_T uart1;

#endif

#ifdef UART2_EN

extern UART_T uart2;

#endif

#endif /*UART_H_*/

======================================================================== 串口编程C程序文件uart.c如下:

======================================================================== /*

* File : uart.c

* Description : This file is UART driver of STC12C5A serial signal chip.

* Author : Chao

* Copyright : Chao

*

* History

* ----------------------

* Rev : 0.0

* Date : 20/08/2011

*

* create.

* ----------------------

*/

//---------------Include files-------------------------//

#include

#include"uart.h"

//---------------Function Prototype-------------------------//

#ifdef UART1_EN

static void uart1_init(void); //串口1初始化函数

static void uart1_send_byte(unsigned char ddata); //串口1发送单个字符

static void uart1_send_string(unsigned char *ddata, unsigned char length); //串口1发送字符串#endif

#ifdef UART2_EN

static void uart2_init(void); //串口2初始化函数

static void uart2_send_byte(unsigned char ddata); //串口2发送单个字符

static void uart2_send_string(unsigned char *ddata, unsigned char length); //串口2发送字符串#endif

//---------------Variable-------------------------//

unsigned long Fosc; //波特率设定时中间变量

#ifdef UART1_EN

UART_T uart1 = {

0, // receive_flag

0, // data_length

"Hello\n", // receive_buffer

uart1_init, // init

uart1_send_byte, // send_byte

uart1_send_string // send_string

};

unsigned char uart1_receive_temp;

unsigned char *uart1_receive_point=uart1.receive_buffer;

#endif

#ifdef UART2_EN

unsigned char uart1_receive_temp;

UART_T uart2 = {

0, // receive_flag

0, // data_length

"Hello\n", // receive_buffer

uart2_init, // init

uart2_send_byte, // send_byte

uart2_send_string, // send_string

};

unsigned char uart2_receive_temp;

unsigned char *uart2_receive_point=uart2.receive_buffer;

#endif

#ifdef UART1_EN

/*

* ---- FUNCTION ----------------------------------------------------------------------- * Name : uart1_init

* Description : 串口1初始化程序

* -------------------------------------------------------------------------------------------- */

static void uart1_init(void)

{

unsigned long baud;

//选择波特率产生方式:采用独立波特率发生器

AUXR |= S1BRS;

//设定波特率发生器重新计数初值

Fosc = SystemFosc/32;

baud = UartBaud;

if(baud > 9600)

AUXR |= BRTx12; //时钟频率不分频

else

Fosc /= 12;

BRT = 256-Fosc/baud;

//启动波特率发生器

AUXR |= BRTR;

SCON = 0x50; //设定串口1工作方式:方式1(8n1),允许接收

ES = 1; //开串口1中断

}

/*

* === FUNCTION ---------------------------------------------------------------------

* Name : uart1_send_byte

* Description : 串口1发送单个字节数据

* --------------------------------------------------------------------------------------------

*/

static void uart1_send_byte(unsigned char ddata)

{

SBUF = ddata; //写入要发送的字符

while(!TI); //等待发送完毕

TI = 0; //清发送标志

}

/*

* === FUNCTION ---------------------------------------------------------------------

* Name : uart1_send_string

* Description : 串口1发送以'\0'结尾的字符串

* --------------------------------------------------------------------------------------------

*/

static void uart1_send_string(unsigned char *ddata, unsigned char length)

{

while(length--)

uart1_send_byte(*ddata++);

}

#ifdef UART1_RECEIVE_EN

/*

* === FUNCTION ---------------------------------------------------------------------

* Name : ISR_uart1

* Description : 串口1中断数据接收程序

* --------------------------------------------------------------------------------------------

*/

void ISR_uart1(void) interrupt 4

{

if(RI) //确认接收到字符

{

uart1_receive_temp = SBUF;

#ifdef ECHO

uart1.send_byte(uart1_receive_temp);

#endif

if(uart1_receive_temp != UartEndChar) //如果没有接收到(假设接收缓冲区足够大){

*uart1_receive_point++ = uart1_receive_temp;

uart1.data_length++;

}

else

{

uart1_receive_point = uart1.receive_buffer; //重新将接收字符指针指向接收缓冲区头uart1.receive_flag = 1; //置位接收命令完成标志

}

RI = 0; //清接收标志

}

}

#endif

#endif

#ifdef UART2_EN

/*

* === FUNCTION ---------------------------------------------------------------------

* Name : uart2_init

* Description : 串口1初始化程序

* --------------------------------------------------------------------------------------------

*/

static void uart2_init(void)

{

#ifndef UART1_EN

unsigned long baud;

//选择波特率产生方式:采用独立波特率发生器

AUXR |= S1BRS;

//设定波特率发生器重新计数初值

Fosc = SystemFosc/32;

baud = UartBaud;

if(baud > 9600)

AUXR |= BRTx12; //时钟频率不分频

else

Fosc /= 12;

BRT = 256-Fosc/UartBaud;

//启动波特率发生器

AUXR |= BRTR;

#endif

S2CON=0x50; //设定串口工作方式:方式1(8n1),允许接收

IE2=0x01; //允许串口2中断

}

/*

* --- FUNCTION ---------------------------------------------------------------------

* Name : uart2_send_byte

* Description : 串口2发送单个字节数据

* --------------------------------------------------------------------------------------------

*/

static void uart2_send_byte(unsigned char ddata)

{

S2CON &= 0xFD; //清发送标志

S2BUF = ddata; //发送数据

while(!(S2CON&0x02)); //等待发送完成

}

/*

* === FUNCTION ---------------------------------------------------------------------

* Name : uart2_send_string

* Description : 串口2发送以'\0'结尾的字符串

* --------------------------------------------------------------------------------------------

*/

static void uart2_send_string(unsigned char *ddata, unsigned char length)

{

while(length--)

uart2_send_byte(*ddata++);

}

#ifdef UART2_RECEIVE_EN

/*

* ----- FUNCTION ---------------------------------------------------------------------

* Name : ISR_uart2

* Description : 串口2中断数据接收程序

* --------------------------------------------------------------------------------------------

*/

void ISR_uart2(void) interrupt 8 //单片机接收从机发来的数据

{

if(S2CON&0x01) //如果接收到数据

{

uart2_receive_temp = S2BUF; //读取数据

#ifdef ECHO

uart2.send_byte(uart2_receive_temp);

#endif

if(uart2_receive_temp != UartEndChar) //如果没有接收到(假设接收缓冲区足够大){

*uart2_receive_point++ = uart2_receive_temp;

uart2.data_length++;

}

else

{

uart2_receive_point = uart2.receive_buffer; //重新将接收字符指针指向接收缓冲区头uart2.receive_flag = 1; //置位接收命令完成标志

}

S2CON &= 0xFE; //清接收标志

}

}

#endif

#endif

======================================================================= 通过上面两个文件,就能很方便的实现STC12C5A系列单片机中串口操作,

并且能够通过配置uart.h文件来实现串口1、串口2的条件编译,测试主函数main.c如下:

======================================================================= #include

#include"uart.h"

void Sys_init(void); //系统初始化

void main()

{

Sys_init();

while(1)

{

if(uart1.receive_flag)

{

uart1.send_string(uart1.receive_buffer, uart1.data_length);

uart1.receive_flag = 0;

uart1.data_length = 0;

}

if(uart2.receive_flag)

{

uart2.send_string(uart2.receive_buffer, uart2.data_length);

uart2.receive_flag = 0;

uart2.data_length = 0;

}

}

}

void Sys_init(void) //系统初始化

{

uart1.init();

uart1.send_string("uart1\r\n",7);

uart2.init();

uart2.send_string("uart2\r\n",7);

EA = 1;

}

该测试主函数实现的功能是:上电后,从串口1、串口2分别输出字符串"uart1\r\n"、“uart2\r\n”,然后两路串口分别等待接收数据,接收的字符串以字符“>”作为结束标志(可以在uart.h文件中进行修改),串口每接收完一个以“>”作为结尾的字符串,会通过相应串口将接收的字符串发送出去。

总结:该项目采用C++中封装思想进行编程,利用自定义数据结构UART_T对串口相关数据和操作函数进行了封装,这让整体程序看起来非常清晰。另外,通过使用条件编译,能够让程序实现“按需编译”。

相关主题