历史上的今天
返回首页

历史上的今天

今天是:2025年11月04日(星期二)

正在发生

2022年11月04日 | 51单片机入门模板(STC89C52RC)

2022-11-04 来源:csdn

该模板适用于51单片机入门,比较易于理解,包含定时器和串口的操作。

可以在定时器T0中断服务函数和主循环中实现主要功能,在UART中断服务函数(T1定时器)中实现简单的串口通信接收命令的功能。


注:本模板STC89C52RC单片机使用11.0592MHz的晶振,若使用12MHz晶振可修改定时器相关位置


STC89C52RC原理图

来源网络,侵删

模板及分析

1.主要结构

#include


unsigned char T0RH = 0;    //T0重载值高字节

unsigned char T0RL = 0;    //T0重载值低字节

unsigned char RxdByte = 0; //串口接收到的字节


void ConfigTimer0(unsigned int ms);

void ConfigUART(unsigned int baud);


void main()

{

EA = 1; //使能总中断

ConfigTimer0(1);  //配置为1ms

ConfigUART(9600); //配置波特率为9600

while(1)

{

}

}

/*配置并启动T0,ms-T0定时时间*/

void ConfigTimer0(unsigned int ms)

{

}

/*串口配置函数,baud-通信波特率*/

void ConfigUART(unsigned int baud)

{

}


/*T0中断服务函数*/

void InterruptTimer0() interrupt 1

{

}

/*UART中断服务函数*/

void InterruptUART() interrupt 4

{

}


2.配置及实现T0中断

先写配置函数ConfigTimer0。要实现每隔一定时间单片机进入T0中断服务函数执行它的功能,首先要确定多久进入一次中断。


我们输入这个函数的参数是ms,需要在函数中转换成单片机实际的工作方式来计算。

STC89C52RC的1个机器周期等于12个时钟周期。单片机的工作周期要用机器周期计算,每过一个单片机的工作周期,定时器的值就从初值向上增加1,在16位定时器模式下直到65536溢出,触发相应中断,进入相应中断服务函数。

以11.0592MHz的晶振为例,先将时钟周期转换为机器周期,ms转换为s计算出所需的计数值。由于定时器是向上计数溢出的,所以要用溢出值减去计数值得出重载值。(假如定时器是向下计数的就不用这步)


unsigned long tmp;


tmp = 11059200 / 12; //计算所需的计数值

tmp = (tmp * ms) / 1000;

tmp = 65536 - tmp; //计算定时器重载值


T0是个16位定时器,分为TH0高8位和TL0低8位,对应重载值也要分开计算。


unsigned char T0RH = 0;    //T0重载值高字节

unsigned char T0RL = 0;    //T0重载值低字节


T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节

T0RL = tmp;


TCON:

TCON寄存器

TMOD:

TMOD寄存器

IE:

EI寄存器

接下来配置TCON、TMOD和IE这些寄存器。

先把工作模式寄存器TMOD配置为16位定时器模式,然后给TH0、TL0两个8位寄存器赋初值,再配置可位寻址的中断允许寄存器IE,即ET0 = 1,最后配置 定时器/控制器控制寄存器TCON:TR0 = 1 启动T0定时器。


TMOD &= 0xF0;   //清零T0控制位

TMOD |= 0x01;   //配置T0为模式1

TH0 = T0RH;   //加载T0重载值

TL0 = T0RL;

ET0 = 1;   //使能T0中断

TR0 = 1;   //启动T0


最后在T0中断服务函数InterruptTimer0中每次溢出进入中断的时候重新初始化定时器的值,执行功能。


TH0 = T0RH; //重载初值

TL0 = T0RL;

...


3.配置及实现串口中断

串口中断和上面的中断又有所不同。首先,它只能由T1或T2定时器作为“波特率发生器”,T0不可以;其次,定时器的作用是定时检测数据,而不是定时进入中断;再就是串口一般由P3.0(RXD)和P3.1(TXD)担当,因为关于具体通信协议已经由单片机的硬件电路实现了,我们只要懂得如何配置寄存器就可以。


(STC89C52RC只有一个串口,假如要这个单片机既使用串口接收传感器的一些数据,又要把数据通过串口通信传回上位机,一个串口就不够用了,可以用IO口模拟串口,自己写一下串口通信协议的实现,最方便的是用2个串口的单片机)


SCON:(串口控制寄存器)

SCON寄存器

先配置串口为模式1(一字节接收8位),然后配置定时器T1为8位重装载模式,即TL1每次达到256溢出后装载TH1的值.,默认 电源控制器及波特率选择寄存器 PCON = 1, 一个位检测32次,同理,用256减得到T1重载值,也就是控制溢出的时间为约定好波特率时(9600),一个位占用时间的image.png?imageView2/2/w/550


SCON = 0x50; //配置串口为模式1

TMOD &= 0x0F; //清零T1控制位

TMOD |= 0x20;   //配置T1为模式2

TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值

TL1 = TH1; //初始等于重载值


ET1 = 0; //禁止T1中断

ES = 1; //使能串口中断

TR1 = 1; //启动T1


SBUF为串口数据缓冲寄存器,大小为8字节。

当接收一字节数据结束时,RI自动置1,要在中断服务函数中手动归0;TI 同理。然后接收数据,传递执行功能的信息。


/*UART中断服务函数*/

void InterruptUART() interrupt 4

{

if (RI) //接收到字节

{

RI = 0; //手动清零接收中断标志位

RxdByte = SBUF; //接收到的数据(8位)保留在接收字节变量中

SBUF = RxdByte; //接收到的数据直接发回,用以提示输入信息是否被正确接收

...

}

if (TI) //字节发送完毕

{

TI = 0; //手动清零发送中断标志位

}

}


完整模板代码

/***********************************************************************

*                中断的4个寄存器(都为8位)

*  中断允许   中断优先级 定时器/计数器工作模式   定时器/计数器控制

* IE   IP        TMOD TCON

* 位寻址      固定   不可位寻址 位寻址

* EA|ET1|ES1  ----         T1|T0 TR0|TR1

* 串口控制寄存器  SCON  不可位寻址  置0x50

* 中断优先级(0~5):INT0  T0  INT1  T1  TX/RX  T2

*

* 具体的可转入reg52.h头文件中查看

************************************************************************/


#include


/******************************定义引脚*********************************/



/******************************定义全局变量*****************************/



/*************************定时器********************************/

unsigned char T0RH = 0;    //T0重载值高字节

unsigned char T0RL = 0;    //T0重载值低字节


/************************串口通信*******************************/

unsigned char RxdByte = 0; //串口接收到的字节


/****************************函数声明***********************************/

void ConfigTimer0(unsigned int ms);

void ConfigUART(unsigned int baud);


/*主函数*/

void main()

{

EA = 1; //使能总中断

ConfigTimer0(1);  //配置为1ms

ConfigUART(9600); //配置波特率为9600

while(1)

{

}

}


/*配置并启动T0,ms-T0定时时间*/

void ConfigTimer0(unsigned int ms)

{

unsigned long tmp;


tmp = 11059200 / 12; //计算所需的计数值(ms换算成s)

tmp = (tmp * ms) / 1000;

tmp = 65536 - tmp; //计算定时器重载值

//tmp = tmp + 13; //补偿中断响应延时造成的误差

T0RH = (unsigned char)(tmp>>8); //定时器重载值拆分为高低字节

T0RL = (unsigned char)tmp;

TMOD &= 0xF0; //清零T0控制位

TMOD |= 0x01; //配置T0为模式1

TH0 = T0RH; //加载T0重载值

TL0 = T0RL;

ET0 = 1; //使能T0中断

TR0 = 1; //启动T0

}


/*串口配置函数,baud-通信波特率*/

void ConfigUART(unsigned int baud)

{

SCON = 0x50; //配置串口为模式1

TMOD &= 0x0F; //清零T1控制位

TMOD |= 0x20;   //配置T1为模式2

TH1 = 256 - (11059200/12/32)/baud; //计算T1重载值(32:PCON配置为1,一个数据监测32次,保证准确性)

TL1 = TH1; //初始等于重载值

ET1 = 0; //禁止T1中断

ES = 1; //使能串口中断

TR1 = 1; //启动T1

}


/******************************自定义函数*******************************/





/******************************自定义函数END****************************/

/*T0中断服务函数*/

void InterruptTimer0() interrupt 1

{

TH0 = T0RH; //重载初值

TL0 = T0RL;

/**************************定时器0功能实现***************************/





/*******************************END**********************************/

}


/*UART中断服务函数*/

void InterruptUART() interrupt 4

{

if (RI) //接收到字节

{

RI = 0; //手动清零接收中断标志位

RxdByte = SBUF; //接收到的数据(8位)保留在接收字节变量中

SBUF = RxdByte; //接收到的数据直接发回

//用以提示输入信息是否被正确接收

/**************************串口通信功能实现***************************/





/********************************END**********************************/

}

if (TI) //字节发送完毕

{

TI = 0; //手动清零发送中断标志位

}

}

推荐阅读

史海拾趣

DBS Microwave Inc公司的发展小趣事

DBS Microwave始终将产品质量放在首位。公司建立了一套严格的质量管理体系,从原材料采购到产品生产的每一个环节都进行严格的质量控制。此外,公司还注重员工的培训和技能提升,确保每一位员工都能够熟练掌握生产技能和质量要求。这些措施使得DBS Microwave的产品质量得到了客户的高度认可。

德芯半导体(Doeshare)公司的发展小趣事

德芯半导体在发展过程中,积极拓展合作伙伴关系。公司与国内外多家知名企业建立了长期稳定的合作关系,共同开展技术研发和市场推广。这些合作伙伴不仅为公司提供了技术支持和市场渠道,还为公司带来了更多的商业机会和发展空间。通过与合作伙伴的紧密合作,德芯半导体在半导体行业中树立了良好的口碑和形象。

Fairchild Imaging公司的发展小趣事

Fairchild Imaging非常重视与行业领先企业的合作。通过与这些企业的紧密合作,Fairchild Imaging能够不断吸收先进的技术和管理经验,提升自身的研发和生产能力。同时,这种合作也有助于Fairchild Imaging将其技术成果更快地推向市场,满足客户的多样化需求。

Bomar公司的发展小趣事

在环保意识日益增强的今天,Bomar公司积极响应全球环保号召,开始研发并应用环保材料。公司推出的生物基低聚物产品,完全或部分提取自植物或农作物等可再生原料,不仅降低了对石油产品的依赖,还具有低刺激性和低毒性的优势。这一创新举措不仅有助于提升Bomar公司产品的环保性能,也符合了市场对环保产品的需求趋势,为公司的可持续发展注入了新的动力。

这五个故事只是Bomar公司在电子行业发展过程中的一部分,但它们却展示了公司在技术创新、市场拓展、合作发展以及环保责任等方面的努力和成就。通过这些故事,我们可以看到Bomar公司如何紧跟时代步伐,不断适应和引领电子行业的发展趋势。

Apacer公司的发展小趣事

在各大电子展会上,Apacer宇瞻科技也频繁亮相,展示其最新技术和产品。在某次台北世界贸易中心的展会上,宇瞻科技展示了一款高端DDR3内存,其频率高达1600MHz,带宽达到了惊人的12800MB/s。这一产品吸引了众多观众的关注,也进一步彰显了宇瞻科技在内存模组领域的领先地位。

这五个故事只是Apacer宇瞻科技发展历程中的一部分,但它们足以展现出公司从创立到崛起的艰辛与辉煌。在未来的发展中,相信宇瞻科技将继续凭借其卓越的技术实力和持续的创新精神,为电子行业的发展贡献更多力量。

Control Sciences Inc公司的发展小趣事

为了确保产品质量的稳定和可靠,Control Sciences Inc建立了一套完善的质量管理体系。公司从原材料采购、生产过程到产品出厂,都实行了严格的质量控制。同时,公司还引入了先进的质量检测设备和方法,确保每一台产品都符合客户的要求。这一举措使得Control Sciences Inc的产品在市场上赢得了良好的声誉。

问答坊 | AI 解惑

完整版UCOS-II V2.52源代码

完整版UCOS-II V2.52源代码,需要的朋友赶快下 这个系统包无需改动,嵌入系统即可使用,主要是方便新伙计少走弯路,内容是原版邵贝贝光盘中的系统代码,放心使用! …

查看全部问答>

一个LED的N种玩法(五)----WatchDog Timer

一个LED的N种玩法(五)--WatchDog Timer Author: chenzhufly Email: chenzhufly@126.com 2010-05-02 一.WatchDog Timer 概述 看门狗的目的是当进入错误状态一定时间后复位微控制器。当看门狗使能时,如果用户没有在一定时间内喂狗(看门狗定时 ...…

查看全部问答>

1000VDC转5VDC大家有没有好的方案?

有一个项目,供电电压是1000V直流的,需要转为5V,功率在2W左右.由于电压较高,如用PWM降压常规的器件耐压达不到,不知大家有没有好的方案,不甚感激!…

查看全部问答>

wince 下directshow 截图

代码如下: pmeidacontrol->pause() 视频已经暂停了 m_Graphs->pMC->GetState(2000,(OAFilterState*)&pfs); pfs为State_Paused 暂停状态 hr=m_Graphs->pBV->GetCurrentImage(&bitmapSize,NULL); hr的值为E_INVALIDARG 查了好多资料 还是没找到 ...…

查看全部问答>

wince 6.0 OAL层初始化LOGO显示问题~

eboot显示一个 logo, 但进去系统的中间黑屏,我想继续在 oal中显示 logo, 去掉lcd初始化函数调用, 可看 OEMInit 函数,没见 初始化LCD部分代码, OEMInit 上下文周围也没找到 初始LCD有关的函数. 麻烦给个提示,谢谢 平台是 PXA270+WINCE6.0…

查看全部问答>

推荐ARM开发板

现在急需推荐一款ARM开发板,要求: 可以做触摸屏;操作系统WinCE——可以自己修改源码;应用于大型系统集成;处理数据采集系统;抗干扰能力强;数据运算速度快;扩展口多。哪位大侠给推荐一下,谢谢:)…

查看全部问答>

java 调用DLL 读串口,不久就死了,请帮忙看看什么原因?

经过仔细分析问题出这dll这里,但始终找不到解决办法,请大家帮忙看看,谢谢! dll代码如下: JNIEXPORT jstring JNICALL Java_getGPS (JNIEnv * env, jobject obj) {     char * cIpAddress =compressWideChar((LPCWSTR)L\"empty value! ...…

查看全部问答>

关于格式转换函数sprintf():

关于格式转换函数sprintf(): 我想用sprintf()函数将一个usigned int型变量转换为字符串从串口发送出去 结果调用的时候发现不对 我先定义DeocdeNum=2000;UCHAR *CH 保存转换后的字符串 printf(ch,\"%d\",DeocdeNum); 结果我发现在程序中 Deoc ...…

查看全部问答>

有源滤波器资料

本帖最后由 paulhyde 于 2014-9-15 03:08 编辑 我收集的有源滤波器资料,分享快乐    …

查看全部问答>