历史上的今天
返回首页

历史上的今天

今天是:2025年01月26日(星期日)

2019年01月26日 | STC12C5A60S2之串口

2019-01-26 来源:eefocus

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


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


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


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



有关STC12C5A60S2串口的寄存器


 

 

 

UART.C

/*

 * 文 件 名:UART.C

 * 芯    片:STC12C5A60S2

 * 晶    振:12MHz

 * 创 建 者:冷月

 * 创建日期:2010.8.16

 * 修 改 者:

 * 修改日期:

 * 功能描述:STC12C5A系列单片机串口模块,包括串口1和串口2,方式1,使用独立波特率发生器

 * 功能:1.发送一个字符;2.发送一个字符串;3.接收一个字符。

 */


#include

#include

#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

main.c

/*

 * 文 件 名:UART.C

 * 芯    片:STC12C5A60S2

 * 晶    振:12MHz

 * 创 建 者:冷月

 * 创建日期:2010.8.16

 * 修 改 者:

 * 修改日期:

 * 功能描述:单片机通过串口与PC机通讯,通过PC机控制与单片机IO相连的LED灯亮灭

 * 串口1和串口2使用独立波特率发生器,波特率默认设置为9600,波特率不加倍,1T模式

 */


#include

#include

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

}

}

}

}


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


设置如下

实验结果:


推荐阅读

史海拾趣

E-Z-HOOK公司的发展小趣事

随着全球化进程的加速推进,E-Z-HOOK公司开始积极拓展国际市场。他们通过参加国际展会、建立海外销售网络等方式,将产品推向全球各地。同时,公司还积极寻求与国际知名企业的合作机会,共同开发新技术和新产品。这些努力使得E-Z-HOOK公司的品牌影响力逐渐扩大,在全球范围内树立了良好的声誉和形象。

格莱尔(GLE)公司的发展小趣事

在稳步发展国内市场的同时,格莱尔也积极拓展海外市场。公司凭借优质的产品和服务,成功吸引了众多国际客户的关注与合作。格莱尔的产品广泛应用于液晶显示屏、笔记本计算机、手机、数码相机等多个领域,与众多知名企业建立了长期稳定的合作关系。此外,格莱尔还注重品牌建设,通过参加国际展会、发布新品等方式提升品牌知名度和影响力。

Brite-Led Optoelectronics Inc公司的发展小趣事

在国内市场取得一定成绩后,Brite-Led开始将目光投向海外市场。公司制定了一系列市场拓展策略,包括参加国际展会、建立海外销售网络、与当地企业合作等。经过几年的努力,Brite-Led的产品逐渐打入国际市场,赢得了众多海外客户的青睐。同时,公司也在全球范围内建立了多个研发中心和生产基地,以更好地服务全球客户。

Densitron公司的发展小趣事

人才是企业发展的关键因素。Densitron公司非常重视人才的培养和团队建设。公司建立了一套完善的人才培养机制,通过内部培训、外部学习等方式,不断提升员工的技能水平和综合素质。同时,公司还注重团队文化建设,鼓励员工之间的协作与交流。这些举措使得Densitron公司拥有一支高素质、高效率的团队,为公司的持续发展提供了有力保障。

Fortiming Corporation公司的发展小趣事

背景:随着电子技术的快速发展,客户对频率控制产品的要求越来越高。

发展:Fortiming不断投入研发资源,进行技术创新和产品升级。公司成功开发出了一系列高精度、高稳定性的晶振产品,满足了市场对高品质频率控制产品的需求。同时,Fortiming还积极探索新的应用领域,如通信、汽车电子、物联网等,不断拓展市场边界。

富满电子(FM)公司的发展小趣事

背景:在电子行业,成本控制和供应链管理是企业竞争力的重要体现。

发展:Fortiming不断优化供应链管理流程,与上游供应商建立长期稳定的合作关系,确保原材料的稳定供应和质量可靠。同时,公司还通过技术创新和工艺改进,降低生产成本,提高产品竞争力。这些措施使得Fortiming在激烈的市场竞争中保持了良好的盈利能力。

问答坊 | AI 解惑

美国战斗机械狗研制成功

核心提示:近日美国官方公布了一段关于军用机械狗的录像,视频中机械狗展示了它惊人的活动能力和适应性,一举在互联网上造成轰动。研发公司称经过测试,该机械狗能在战场上为士兵运送弹药、食物和其他物品。 这个形似机械狗的四足机器人被命名为“ ...…

查看全部问答>

总结一下启动文件编写

文档中我对两个启动文件进行了对比,发现了编写启动文件的方法。愿对大家有所帮助!…

查看全部问答>

关于“CTRL+Z”输入问题

串口发送数据时怎样输入“CTRL+Z”,谢谢!,有点急!!!…

查看全部问答>

sd卡的寿命问题

网上搜索得知SD卡的寿命为擦写10万次以上,它的具体含义是什么 1、是不是我如果只对其中一片区域(非0扇区)进行擦写10万次,那么这片区域就有可能损坏,而其他区域还可以正常使用呢? 2、一般的文件系统对写操作如FWRITE(FILE *fp,W)是怎么处 ...…

查看全部问答>

wince 6.0 电源管理驱动

wince 6.0 下电源管理的驱动部分在什么地方。 初始化在什么地方。 找了半天也没有找到…

查看全部问答>

急!!!wince模拟器,掉电再上电,保存的问题!

如题。用PB自己定制的模拟器,希望关掉模拟器以后,再开模拟器能文件还存在。模拟器能带这个功能吗?需要加什么组件?着急···!!!…

查看全部问答>

门吊下降速度突然加快是什么原因?

门吊起升高度40米,当下降到15米时下降速度突然加快 ,请问是什么原因?是采用电阻调速的。…

查看全部问答>

12864流动显示 供新手参考

12864显示 供新手参考 …

查看全部问答>

求购闲置飞思卡尔智能车s128最小系统、B型车模、摄像头

有哪位前辈有意出售的吗?现在我们急需这些,为明年的比赛做准备,谢谢各位了,有闲置的也有意出售的请联系qq362313998,谢谢…

查看全部问答>

易电源心得体会

起初我对电源电路只是有一点了解,只用过几个降压升压的芯片,以为电源也就这么简单,后来才发现不是这么简单,还有很多因素需要考虑,而且发现了电源在整个电路板中的重要地位,让我越发的喜欢易电源的课程,对电源电路有了一定的认识,对以后的应 ...…

查看全部问答>