该模板适用于51单片机入门,比较易于理解,包含定时器和串口的操作。
可以在定时器T0中断服务函数和主循环中实现主要功能,在UART中断服务函数(T1定时器)中实现简单的串口通信接收命令的功能。

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

STC89C52RC原理图

模板及分析

1.主要结构

#include <reg52.h>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);  //配置为1msConfigUART(9600); //配置波特率为9600while(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:

TMOD:

IE:

接下来配置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:(串口控制寄存器)

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

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 <reg52.h>/******************************定义引脚*********************************//******************************定义全局变量*****************************//*************************定时器********************************/
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);  //配置为1msConfigUART(9600); //配置波特率为9600while(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为模式1TH0 = T0RH;          //加载T0重载值TL0 = T0RL;ET0 = 1;          //使能T0中断TR0 = 1;           //启动T0
}                               /*串口配置函数,baud-通信波特率*/
void ConfigUART(unsigned int baud)
{SCON = 0x50;  //配置串口为模式1TMOD &= 0x0F;    //清零T1控制位TMOD |= 0x20;   //配置T1为模式2TH1 = 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;   //手动清零发送中断标志位}
}

51单片机入门模板(STC89C52RC)相关推荐

  1. 51单片机入门指南系列:一、前期准备

    51单片机入门指南系列:一.前期准备 51单片机学习步骤 为什么我用的是52单片机,大家也说它是51? 编译环境 单片机入门书籍 购买实物开发板 51单片机学习步骤 51单片机是嵌入式学习的入门级芯片 ...

  2. 51单片机入门——数字时钟

    文章目录 1. 前言 1.1. 设计要求 2. 硬件原理 2.1. 时钟信号(晶振) 2.2. 按键开关 2.3. 数码管显示 3. 原理图 3.1. 仿真原理图 3.2. AD原理图 3.3. PC ...

  3. 51单片机入门教程(6)——外部中断

    51单片机入门教程(6)--外部中断 一.外部中断 1.1 中断 1.2 外部中断 二.中断优先级 一.外部中断 1.1 中断 关于中断的概念在上一篇博客中已经提到了.(传送门:51单片机入门教程(5 ...

  4. 51单片机入门教程(5)——定时器中断

    51单片机入门教程(5)--定时器中断 一.中断的概念 二.定时器中断 2.1 软件延时的不足 2.2 中断寄存器 2.2.1 中断允许控制寄存器 IE 2.2.2 定时器工作方式寄存器 TMOD 2 ...

  5. 51单片机入门教程(1)——点亮一个LED灯

    51单片机入门教程(1)--点亮一个LED灯 一.什么是单片机 单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU.随机存储器 ...

  6. 51单片机入门学习小结(流水灯与数码管)

    51单片机入门学习小结(流水灯与数码管) 对原理图的分析 以下是我所用单片机的原理图 这块51单片机一共有4个I/O口(意思为input/output),也代表着如果我们后续都要用到这四个的话那么功能 ...

  7. 51单片机入门——16路抢答器

    文章目录 设计要求 电路原理图 硬件原理 时钟信号(晶振) 矩阵按键与独立按键 代码解析 设计要求 同时为16支参赛队提供抢答功能,抢答成功后应能通过数码管显示出参赛队号数,同时点亮发光二极管示意抢答 ...

  8. 51单片机入门基础介绍

    51单片机入门基础介绍 文章目录 51单片机入门基础介绍 前言 常用元器件 发光二极管 数码管 LED数码管的显示方式 按键 定时计数器 串行口控制寄存器SCON 中断系统 中断源及中断请求 中断允许 ...

  9. 【51单片机入门】点亮多个LED流水灯

    [51单片机&入门]点亮多个LED流水灯 实验环境 功能实现 PCB原理图 代码 要点 仿真 代码 实验环境 Keil C51 Proteus 8.9 功能实现 LED流水灯依次从右向左亮起, ...

最新文章

  1. GPT-3到来,程序员会被AI取代吗?
  2. java语言适合编写什么_01--Java语言概述与开发环境 最适合入门的Java教程
  3. java安全沙箱(一)之ClassLoader双亲委派机制
  4. 谋定技术加工领域 中国-巴对话(国际)农民丰收节贸易会
  5. ios绘图基本图形之线条
  6. orcale实现自定义优先级排序的SQL
  7. 3、数据库中的字符集和校对集
  8. java.lang.NoClassDefFoundError: javax/wsdl/extensions/ElementExtensible
  9. c语言定义数组中字母怎么输入,c语言数组怎么输入?
  10. 44、网络配线架如何打?超5类线水晶头与6类线水晶头制作方法
  11. 砍价两种种算法(转载)
  12. Matlab滤波器设计——基于filter函数的低通、高通、带通、带阻滤波器
  13. java pdf替换内容_java PDF批量替换关键词
  14. 嘎嘎好用的Vue虚拟键盘simple-keyboard
  15. Chromium网页Layer Tree创建过程分析
  16. python pip 的安装、更新、卸载、降级、和使用 pip 管理包
  17. 将列表(含字典)数据写入Excel
  18. Windows下Openpose试运行环境配置流程
  19. AIX smit设置设置能够输入中文
  20. 用Java实现植物大战僵尸的修改(续)

热门文章

  1. 使用MATLAB画出地球仪图形
  2. 倒立摆的实现 6.定时器中断和其余初始化
  3. vba的change事件
  4. H5 直播的疯狂点赞动画如何通过php直播平台源码实现(附完整源码)
  5. 裴蜀定理(贝祖定理) 证明与应用
  6. 工业螺旋齿轮行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
  7. 唯有硬核,方显本色丨云和恩墨五位数据库专家即将亮相openGauss Developer Day
  8. 小程序关注公众号组件<official-account ></official-account>的使用方法
  9. 手机文件管理android可以删除吗,手机上什么文件可以删除?答案都在这里了
  10. 编译原理 - 词法分析