原创 STC单片机之串口

2010-8-23 23:07 9664 12 16 分类: MCU/ 嵌入式

STC12C5A60S2单片机的串口从传统的一个扩展到了两个,


而且还增加了一个独立波特率发生器,把定时器1解放了出来,真的不是一般的方便,


还而且能用1T模式,速度大大滴提高了。。。


于是,就写了串口模块,方便以后用


有关STC12C5A60S2串口的寄存器


 1e3de9c2-0281-48a0-aaf3-b3fbd317c2da.gif


 836fa4af-087c-4249-9f8c-7ec101973d89.gif


 


 


UART.C
/* 
 * 文 件 名:UART.C 
 * 芯    片:STC12C5A60S2 
 * 晶    振:12MHz 
 * 创 建 者:冷月 
 * 创建日期:2010.8.16 
 * 修 改 者: 
 * 修改日期: 
 * 功能描述:STC12C5A系列单片机串口模块,包括串口1和串口2,方式1,使用独立波特率发生器 
 *           功能:1.发送一个字符;2.发送一个字符串;3.接收一个字符。 
 */
 
#include <STC12C5A.H>     //STC12C5A系列单片机 
#include <intrins.h> 
#include "UART.H" 
 
#define uchar   unsigned char 
#define uint    unsigned int  
 
//缓存串口1和串口2接收到的字符  
uchar UART1_Recv_Val = 0;  
uchar UART2_Recv_Val = 0;  
 
 
/* 
 * 函 数 名:UART1_Init 
 * 功能描述:串口1初始化 
 * 输入参数:RELOAD:BRT初值; 
 *           doubleBaud:0波特率不加倍,1波特率加倍 
 *           timeMod:0独立波特率发生器12T模式,1为1T模式 
 * 返 回 值:无 
 */ 
void UART1_Init(uchar RELOAD, bit doubleBaud, bit timeMod)  
{  
    SCON |= 0x50;       //串口1方式1,接收充许  
 
    BRT = RELOAD;       //波特率2400  
 
    if (timeMod == 1)       //1T  
    {  
        //T0x12   T1x12   UM0x6   BRTR    S2SMOD  BRTx12  EXTRAM  S1BRS  
        AUXR |= 0x15;       //串口1使用独立波特率发生器,独立波特率发生器1T  
    }  
    else                    //12T  
    {  
        AUXR |= 0x11;  
    }  
 
    if (doubleBaud == 1)  
    {  
        PCON |= 0x80;     //波特率加倍  
    }  
    else 
    {  
        PCON &= 0x7F;     //波特率不加倍  
    }  
 
    EA = 1;  
    ES = 1;             //充许串口1中断  
}  
 
 
/* 
 * 函 数 名:UART2_Init 
 * 功能描述:串口2初始化 
 * 输入参数:RELOAD:BRT初值; 
 *           doubleBaud:0波特率不加倍,1波特率加倍 
 *           timeMod:0独立波特率发生器12T模式,1为1T模式 
 * 返 回 值:无 
 */ 
void UART2_Init(uchar RELOAD, bit doubleBaud, bit timeMod)  
{  
    //S2SM0  S2SM1   S2SM2   S2REN   S2TB8   S2RB8   S2TI     S2RI  
    S2CON |= 0x50;      //串口2,方式1,接收充许  
 
    BRT = RELOAD;  
 
    if (timeMod == 1)       //1T  
    {  
        //T0x12   T1x12   UM0x6   BRTR    S2SMOD  BRTx12  EXTRAM  S1BRS  
        AUXR |= 0x14;       //串口1使用独立波特率发生器,独立波特率发生器1T  
    }  
    else                    //12T  
    {  
        AUXR = (AUXR | 0x10) & 0xFB;  
    }  
 
    if (doubleBaud == 1)  
    {  
        AUXR |= 0x08;       //波特率加倍  
    }  
    else 
    {  
        AUXR &= 0xF7;       //波特率不加倍  
    }  
 
    EA = 1;   
    //-       -       -       -       -       -       ESPI    ES2  
    IE2 |= 0x01;            //充许串口2中断             
}  
 
 
/* 
 * 函 数 名:UART1_SendOneChar 
 * 功能描述:串口1发送一个字符 
 * 输入参数:val:要发送的字符 
 * 返 回 值:无 
 */ 
void UART1_SendOneChar(uchar val)  
{  
    //ES = 0;                   //关闭串口1中断  
 
    SBUF = val;  
    while(TI == 0);  
    TI = 0;  
 
    //ES = 1;                  //恢复串口1中断  
}                            
 
 
/* 
 * 函 数 名:UART2_SendOneChar 
 * 功能描述:串口2发送一个字符 
 * 输入参数:val:要发送的字符 
 * 返 回 值:无 
 */ 
void UART2_SendOneChar(uchar val)  
{  
    //IE2 = 0x00;                 //关闭串口2中断  
 
    S2BUF = val;      
    while ((S2CON & 0x02) == 0);  
    S2CON &= 0xFD;  
 
    //IE2 = 0x01;                //恢复串口2中断  
}  
 
 
/* 
 * 函 数 名:UART1_SendStr 
 * 功能描述:串口1发送字符串 
 * 输入参数:str:指向要发送的字符串的指针 
 * 返 回 值:无 
 */ 
void UART1_SendStr(uchar *str)  
{  
    while( (*str)!='\0' )  
    {  
        UART1_SendOneChar(*str);  
        str++;  
    }  
}  
 
 
/* 
 * 函 数 名:UART2_SendStr 
 * 功能描述:串口2发送字符串 
 * 输入参数:str:指向要发送的字符串的指针 
 * 返 回 值:无 
 */ 
void UART2_SendStr(uchar *str)  
{  
    while( (*str)!='\0' )  
    {  
        UART2_SendOneChar(*str);  
        str++;  
    }  
}  
 
 
/* 
 * 函 数 名:UART1_Int 
 * 功能描述:串口1中断服务程序,接收串口1字符 
 * 输入参数:无 
 * 返 回 值:无 
 */ 
void UART1_Int(void) interrupt 4  
{  
    if (RI == 1)  
    {  
        RI = 0;  
        UART1_Recv_Val = SBUF;  
    }     
}  
 
 
/* 
 * 函 数 名:UART2_Int 
 * 功能描述:串口2中断服务程序,接收串口2字符 
 * 输入参数:无 
 * 返 回 值:无 
 */ 
void UART2_Int(void) interrupt 8  
{  
    if ((S2CON & 0x01) == 1)  
    {  
        S2CON &= 0xFE;  
        UART2_Recv_Val = S2BUF;  
    }     

/*
 * 文 件 名:UART.C
 * 芯    片:STC12C5A60S2
 * 晶    振:12MHz
 * 创 建 者:冷月
 * 创建日期:2010.8.16
 * 修 改 者:
 * 修改日期:
 * 功能描述:STC12C5A系列单片机串口模块,包括串口1和串口2,方式1,使用独立波特率发生器
 *    功能:1.发送一个字符;2.发送一个字符串;3.接收一个字符。
 */


#include <STC12C5A.H>  //STC12C5A系列单片机
#include <intrins.h>
#include "UART.H"


#define uchar unsigned char
#define uint unsigned int


//缓存串口1和串口2接收到的字符
uchar UART1_Recv_Val = 0;
uchar UART2_Recv_Val = 0;



/*
 * 函 数 名:UART1_Init
 * 功能描述:串口1初始化
 * 输入参数:RELOAD:BRT初值;
 *    doubleBaud:0波特率不加倍,1波特率加倍
 *    timeMod:0独立波特率发生器12T模式,1为1T模式
 * 返 回 值:无
 */
void UART1_Init(uchar RELOAD, bit doubleBaud, bit timeMod)
{
 SCON |= 0x50;  //串口1方式1,接收充许


 BRT = RELOAD;  //波特率2400


 if (timeMod == 1)  //1T
 {
  //T0x12   T1x12   UM0x6   BRTR    S2SMOD  BRTx12  EXTRAM  S1BRS
  AUXR |= 0x15;  //串口1使用独立波特率发生器,独立波特率发生器1T
 }
 else     //12T
 {
  AUXR |= 0x11;
 }


 if (doubleBaud == 1)
 {
  PCON |= 0x80;   //波特率加倍
 }
 else
 {
  PCON &= 0x7F;   //波特率不加倍
 }


 EA = 1;
 ES = 1;    //充许串口1中断
}



/*
 * 函 数 名:UART2_Init
 * 功能描述:串口2初始化
 * 输入参数:RELOAD:BRT初值;
 *    doubleBaud:0波特率不加倍,1波特率加倍
 *    timeMod:0独立波特率发生器12T模式,1为1T模式
 * 返 回 值:无
 */
void UART2_Init(uchar RELOAD, bit doubleBaud, bit timeMod)
{
 //S2SM0  S2SM1   S2SM2   S2REN   S2TB8   S2RB8   S2TI     S2RI
 S2CON |= 0x50;  //串口2,方式1,接收充许


 BRT = RELOAD;


 if (timeMod == 1)  //1T
 {
  //T0x12   T1x12   UM0x6   BRTR    S2SMOD  BRTx12  EXTRAM  S1BRS
  AUXR |= 0x14;  //串口1使用独立波特率发生器,独立波特率发生器1T
 }
 else     //12T
 {
  AUXR = (AUXR | 0x10) & 0xFB;
 }


 if (doubleBaud == 1)
 {
  AUXR |= 0x08;  //波特率加倍
 }
 else
 {
  AUXR &= 0xF7;  //波特率不加倍
 }


 EA = 1; 
 //-       -       -       -       -       -       ESPI    ES2
 IE2 |= 0x01;   //充许串口2中断   
}



/*
 * 函 数 名:UART1_SendOneChar
 * 功能描述:串口1发送一个字符
 * 输入参数:val:要发送的字符
 * 返 回 值:无
 */
void UART1_SendOneChar(uchar val)
{
 //ES = 0;     //关闭串口1中断


 SBUF = val;
 while(TI == 0);
 TI = 0;


 //ES = 1;       //恢复串口1中断
}        



/*
 * 函 数 名:UART2_SendOneChar
 * 功能描述:串口2发送一个字符
 * 输入参数:val:要发送的字符
 * 返 回 值:无
 */
void UART2_SendOneChar(uchar val)
{
 //IE2 = 0x00;      //关闭串口2中断


 S2BUF = val; 
 while ((S2CON & 0x02) == 0);
 S2CON &= 0xFD;


 //IE2 = 0x01;     //恢复串口2中断
}



/*
 * 函 数 名:UART1_SendStr
 * 功能描述:串口1发送字符串
 * 输入参数:str:指向要发送的字符串的指针
 * 返 回 值:无
 */
void UART1_SendStr(uchar *str)
{
 while( (*str)!='\0' )
 {
  UART1_SendOneChar(*str);
  str++;
 }
}



/*
 * 函 数 名:UART2_SendStr
 * 功能描述:串口2发送字符串
 * 输入参数:str:指向要发送的字符串的指针
 * 返 回 值:无
 */
void UART2_SendStr(uchar *str)
{
 while( (*str)!='\0' )
 {
  UART2_SendOneChar(*str);
  str++;
 }
}



/*
 * 函 数 名:UART1_Int
 * 功能描述:串口1中断服务程序,接收串口1字符
 * 输入参数:无
 * 返 回 值:无
 */
void UART1_Int(void) interrupt 4
{
 if (RI == 1)
 {
  RI = 0;
  UART1_Recv_Val = SBUF;
 } 
}



/*
 * 函 数 名:UART2_Int
 * 功能描述:串口2中断服务程序,接收串口2字符
 * 输入参数:无
 * 返 回 值:无
 */
void UART2_Int(void) interrupt 8
{
 if ((S2CON & 0x01) == 1)
 {
  S2CON &= 0xFE;
  UART2_Recv_Val = S2BUF;
 } 
}


 



 


UART.H
/* 
 * 模 块 名:UART.H 
 * 芯    片:STC12C5A60S2 
 * 晶    振:12MHz 
 * 创 建 者:冷月 
 * 创建日期:2010.8.16 
 * 修 改 者: 
 * 修改日期: 
 * 功能描述:STC12C5A系列单片机串口模块,包括串口1和串口2,方式1,使用独立波特率发生器 
 *           可设置串口波特率 
 *           功能:1.发送一个字符;2.发送一个字符串;3.接收一个字符。 
 */
 
#ifndef _UART_H_ 
#define _UART_H_ 
 
#define uchar   unsigned char 
#define uint    unsigned int  
 
//定义串口1口开关,关闭则不能接收数据 
#define OpenUART1()     ES=1 
#define CloseUART1()    ES=0 
#define OpenUART2()     IE2|=0x01 
#define CloseUART2()    IE2&=0xFE  
 
//缓存串口1和串口2接收到的字符  
extern uchar UART1_Recv_Val;  
extern uchar UART2_Recv_Val;  
 
 
/* 
 * 函 数 名:UART1_Init 
 * 调    用:UART1_Init(0xD9, 0, 0); 
 *           BRT=OxD9,波特率不加倍,独立波特率发生器12T模式,Fosc = 12MHz, Baud0 = 9600 
 *           UART1_Init(0xB2, 1, 1); 
 *           BRT=0xB2,波特率加倍,独立波特率发生器1T模式,Fosc = 12MHz, Baud0 = 9600 
 * 功能描述:串口1初始化 
 */ 
void UART1_Init(uchar RELOAD, bit doubleBaud, bit timeMod);  
 
 
/* 
 * 函 数 名:UART2_Init 
 * 调    用:UART2_Init(0xD9, 0, 0); 
 *           BRT=OxD9,波特率不加倍,独立波特率发生器12T模式,Fosc = 12MHz, Baud0 = 9600 
 *           UART2_Init(0xB2, 1, 1); 
 *           BRT=0xB2,波特率加倍,独立波特率发生器1T模式,Fosc = 12MHz, Baud0 = 9600 
 * 功能描述:串口2初始化 
 */ 
void UART2_Init(uchar RELOAD, bit doubleBaud, bit timeMod);  
 
 
/* 
 * 函 数 名:UART1_SendOneChar 
 * 调    用:UART1_SendOneChar('A'); 
 * 功能描述:串口1发送一个字符 
 */ 
void UART1_SendOneChar(uchar val);  
 
 
/* 
 * 函 数 名:UART2_SendOneChar 
 * 调    用:UART2_SendOneChar('A'); 
 * 功能描述:串口2发送一个字符 
 */ 
void UART2_SendOneChar(uchar val);  
 
 
/* 
 * 函 数 名:UART1_SendStr 
 * 调    用:UART1_SendStr("MCU"); 
 * 功能描述:串口1发送字符串 
 */ 
void UART1_SendStr(uchar *str);  
 
 
/* 
 * 函 数 名:UART2_SendStr 
 * 调    用:UART2_SendStr("MCU"); 
 * 功能描述:串口2发送字符串 
 */ 
void UART2_SendStr(uchar *str); 
 
 
#endif 
/*
 * 模 块 名:UART.H
 * 芯    片:STC12C5A60S2
 * 晶    振:12MHz
 * 创 建 者:冷月
 * 创建日期:2010.8.16
 * 修 改 者:
 * 修改日期:
 * 功能描述:STC12C5A系列单片机串口模块,包括串口1和串口2,方式1,使用独立波特率发生器
 *    可设置串口波特率
 *    功能:1.发送一个字符;2.发送一个字符串;3.接收一个字符。
 */


#ifndef _UART_H_
#define _UART_H_


#define uchar unsigned char
#define uint unsigned int


//定义串口1口开关,关闭则不能接收数据
#define OpenUART1()  ES=1
#define CloseUART1() ES=0
#define OpenUART2()  IE2|=0x01
#define CloseUART2() IE2&=0xFE


//缓存串口1和串口2接收到的字符
extern uchar UART1_Recv_Val;
extern uchar UART2_Recv_Val;



/*
 * 函 数 名:UART1_Init
 * 调    用:UART1_Init(0xD9, 0, 0);
 *    BRT=OxD9,波特率不加倍,独立波特率发生器12T模式,Fosc = 12MHz, Baud0 = 9600
 *    UART1_Init(0xB2, 1, 1);
 *    BRT=0xB2,波特率加倍,独立波特率发生器1T模式,Fosc = 12MHz, Baud0 = 9600
 * 功能描述:串口1初始化
 */
void UART1_Init(uchar RELOAD, bit doubleBaud, bit timeMod);



/*
 * 函 数 名:UART2_Init
 * 调    用:UART2_Init(0xD9, 0, 0);
 *    BRT=OxD9,波特率不加倍,独立波特率发生器12T模式,Fosc = 12MHz, Baud0 = 9600
 *    UART2_Init(0xB2, 1, 1);
 *    BRT=0xB2,波特率加倍,独立波特率发生器1T模式,Fosc = 12MHz, Baud0 = 9600
 * 功能描述:串口2初始化
 */
void UART2_Init(uchar RELOAD, bit doubleBaud, bit timeMod);



/*
 * 函 数 名:UART1_SendOneChar
 * 调    用:UART1_SendOneChar('A');
 * 功能描述:串口1发送一个字符
 */
void UART1_SendOneChar(uchar val);



/*
 * 函 数 名:UART2_SendOneChar
 * 调    用:UART2_SendOneChar('A');
 * 功能描述:串口2发送一个字符
 */
void UART2_SendOneChar(uchar val);



/*
 * 函 数 名:UART1_SendStr
 * 调    用:UART1_SendStr("MCU");
 * 功能描述:串口1发送字符串
 */
void UART1_SendStr(uchar *str);



/*
 * 函 数 名:UART2_SendStr
 * 调    用:UART2_SendStr("MCU");
 * 功能描述:串口2发送字符串
 */
void UART2_SendStr(uchar *str);



#endif


 


 


main.c
/*
 * 文 件 名:main.C
 * 芯    片:STC12C5A60S2
 * 晶    振:12MHz
 * 创 建 者:冷月
 * 创建日期:2010.8.16
 * 修 改 者:
 * 修改日期:
 * 功能描述:单片机通过串口与PC机通讯,通过PC机控制与单片机IO相连的LED灯亮灭
 *    串口1和串口2使用独立波特率发生器,波特率默认设置为9600,波特率不加倍,1T模式
 */


#include <STC12C5A.H>  //STC12C5A系列单片机
#include <intrins.h>
#include "UART.H"


#define uchar unsigned char
#define uint unsigned int



//独立波特率发生器初值,1T模式
//Fosc = 晶振频率, Baud0 = 标准波特率
//RELOAD = 256 - INT(Fosc/Baud0/32 + 0.5)  
//Baud = Fosc/(256 - RELOAD)/32
//error = (Baud - Baud0)/Baud0 * 100%
uchar RELOAD = 0xD9;     //Fosc = 12MHz, Baud0 = 9600


//波特率是否加倍,0不倍,1加倍
bit doubleBaud = 0;


//独立波特率发生器,0为12T模式,1为1T模式
bit timeMod = 1;



/*LED定义*/
sbit LED1 = P1^0;
sbit LED2 = P1^1;



/*
 * 函 数 名:main
 * 功能描述:程序入口
 * 输入参数:无
 * 返 回 值:无
 */
void main(void)
{
 //串口标志位,0使用串口1,1使用串口2
 bit UART_flag = 1;


 LED1 = 1;
 LED1 = 1;


 //串口1和串口2初始化
 UART1_Init(RELOAD, doubleBaud, timeMod);
 UART2_Init(RELOAD, doubleBaud, timeMod);


 //先用串口1接收字符
 OpenUART1();
 CloseUART2();


 UART1_SendOneChar(0x0C);   //超级终端清屏
 UART1_SendStr("\r\n");
 UART1_SendStr("\r\n");
 UART1_SendStr("1.串口1通讯\r\n");
 UART2_SendStr("2.串口2通讯\r\n");


 while (UART1_Recv_Val == 0);


 UART1_SendStr("\r\n");   //换行


 if (UART1_Recv_Val == '1')
 {
  OpenUART1();
  CloseUART2();
  UART1_SendStr("Light LED(UART1):\r\n");


  UART_flag = 0;
 }
 else
 {
  CloseUART1();
  OpenUART2();
  UART2_SendStr("Light LED(UART2):\r\n");


  UART_flag = 1;
 }
 UART1_Recv_Val = 0;   //缓存清零
 UART2_Recv_Val = 0;   //缓存清零
 
 while (1)
 {
  if (UART_flag == 0)    //串口1接收字符
  {
   if (UART1_Recv_Val != 0)
   {
    switch (UART1_Recv_Val)
    {
     case '1':
      LED1 = ~LED1;
      break;
     case '2':
      LED2 = ~LED2;
      break;
     default:
      LED1 = 1;
      LED1 = 1;
      break;
    }
    UART1_Recv_Val = 0;      //缓存清零
   }
  }
  else          //串口2接收字符
  {
   if (UART2_Recv_Val != 0)
   {
    switch (UART2_Recv_Val)
    {
     case '1':
      LED1 = ~LED1;
      break;
     case '2':
      LED2 = ~LED2;
      break;
     default:
      LED1 = 1;
      LED1 = 1;
      break;
    }
    UART2_Recv_Val = 0;      //缓存清零
   }
  }
 }
}


最后,用超级终端调试一下下


设置如下


6ef8e934-ad76-409d-b7da-bb82329c09c1.gif


实验结果:


7d1207b5-9bed-4cf4-891d-9910faf10b33.gif


 

PARTNER CONTENT

文章评论4条评论)

登录后参与讨论

用户377235 2014-7-28 17:18

就是,两个串口共用一个波特率发生器么?

用户435699 2012-11-22 20:33

一看就是不能两串口独立工作的

用户410358 2011-10-20 09:15

楼主辛苦了,分享这么多真的很感谢。但是我还是有很多不明白的地方,请问楼主,串口2的波特率是多少?我知道STC单片机串口2只能使用独立波特率发生器的,若是同时两个串口都要用到,而一口用了独立波特率发生器,那串口2能和1共用么?

用户1552953 2011-6-17 22:21

两个串口可以同时开启使用么,比如串口1连PC,串口2连其他设备
相关推荐阅读
用户230358 2010-12-06 17:38
通用Makefile
Makefile初学者,看了点Makefile的资料,想着写个通用的Makefile,于是写了三天。。。可能还有很多错误,测试通过的有gcc的.s和.c,以及嵌入式开发arm-linux-gcc的.S...
用户230358 2010-11-28 09:30
RFID MFRC522
单片机:STC12C5A60S2读卡器:MFRC522非接触IC卡:M1卡keil版本:V4程序是看了网上找的,做了些整理,其中有?号的,是不理解为什么那么设置射频做了好多天,还是有很多不明白,希望对...
用户230358 2010-09-16 23:33
eclipse代码自动提示功能设置
默认是输入"."后出现自动提示,用于类成员的自动提示,可是有时候我们希望它能在我们输入类的首字母后就出现自动提示,可以节省大量的输入时间(虽然按alt + /会出现提示,但还是要多按一次按键,太麻烦了...
用户230358 2010-09-16 23:32
EmEditor配置JAVA
1、选择“工具->外部工具->自定义工具”菜单;2、在“外部工具”对话框中点击“新建”按钮,并进行如下设置:   标题:JAVAC   命令:F:\JDK\bin\javac.exe   ...
用户230358 2010-09-05 10:32
独立按键扫描
定时器1每20ms扫描一次按键,可处理短按、长按 key.c/* * 文 件 名:key.c * 芯    片:STC12C5A60S2 * 晶    振:12MHz * 创 建 者:冷月 * 创建日...
用户230358 2010-09-05 10:23
PWM实现蜂呜器唱歌
PWM用定时器0作时钟源可改变频率,用于输出音符频率,占空比输出音符音长 电路图: BUZZ.C /* * 文 件 名:BUZZ.C * 芯    片:STC12C5A60S2 * 晶    振:12...
EE直播间
更多
我要评论
4
12
关闭 站长推荐上一条 /3 下一条