原创 STC单片机之串口(转)

2011-4-18 22:51 2231 0 分类: EDA/ IP/ 设计与制造

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

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

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

下面转用别人写的串口模块,方便以后用

有关STC12C5A60S2串口的寄存器

 

 

 

 

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;      //缓存清零
   }
  }
 }
}

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

设置如下

实验结果:

 

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
我要评论
0
0
关闭 站长推荐上一条 /3 下一条