51单片机入门模板(STC89C52RC)
该模板适用于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)相关推荐
- 51单片机入门指南系列:一、前期准备
51单片机入门指南系列:一.前期准备 51单片机学习步骤 为什么我用的是52单片机,大家也说它是51? 编译环境 单片机入门书籍 购买实物开发板 51单片机学习步骤 51单片机是嵌入式学习的入门级芯片 ...
- 51单片机入门——数字时钟
文章目录 1. 前言 1.1. 设计要求 2. 硬件原理 2.1. 时钟信号(晶振) 2.2. 按键开关 2.3. 数码管显示 3. 原理图 3.1. 仿真原理图 3.2. AD原理图 3.3. PC ...
- 51单片机入门教程(6)——外部中断
51单片机入门教程(6)--外部中断 一.外部中断 1.1 中断 1.2 外部中断 二.中断优先级 一.外部中断 1.1 中断 关于中断的概念在上一篇博客中已经提到了.(传送门:51单片机入门教程(5 ...
- 51单片机入门教程(5)——定时器中断
51单片机入门教程(5)--定时器中断 一.中断的概念 二.定时器中断 2.1 软件延时的不足 2.2 中断寄存器 2.2.1 中断允许控制寄存器 IE 2.2.2 定时器工作方式寄存器 TMOD 2 ...
- 51单片机入门教程(1)——点亮一个LED灯
51单片机入门教程(1)--点亮一个LED灯 一.什么是单片机 单片机(Microcontrollers)是一种集成电路芯片,是采用超大规模集成电路技术把具有数据处理能力的中央处理器CPU.随机存储器 ...
- 51单片机入门学习小结(流水灯与数码管)
51单片机入门学习小结(流水灯与数码管) 对原理图的分析 以下是我所用单片机的原理图 这块51单片机一共有4个I/O口(意思为input/output),也代表着如果我们后续都要用到这四个的话那么功能 ...
- 51单片机入门——16路抢答器
文章目录 设计要求 电路原理图 硬件原理 时钟信号(晶振) 矩阵按键与独立按键 代码解析 设计要求 同时为16支参赛队提供抢答功能,抢答成功后应能通过数码管显示出参赛队号数,同时点亮发光二极管示意抢答 ...
- 51单片机入门基础介绍
51单片机入门基础介绍 文章目录 51单片机入门基础介绍 前言 常用元器件 发光二极管 数码管 LED数码管的显示方式 按键 定时计数器 串行口控制寄存器SCON 中断系统 中断源及中断请求 中断允许 ...
- 【51单片机入门】点亮多个LED流水灯
[51单片机&入门]点亮多个LED流水灯 实验环境 功能实现 PCB原理图 代码 要点 仿真 代码 实验环境 Keil C51 Proteus 8.9 功能实现 LED流水灯依次从右向左亮起, ...
最新文章
- GPT-3到来,程序员会被AI取代吗?
- java语言适合编写什么_01--Java语言概述与开发环境 最适合入门的Java教程
- java安全沙箱(一)之ClassLoader双亲委派机制
- 谋定技术加工领域 中国-巴对话(国际)农民丰收节贸易会
- ios绘图基本图形之线条
- orcale实现自定义优先级排序的SQL
- 3、数据库中的字符集和校对集
- java.lang.NoClassDefFoundError: javax/wsdl/extensions/ElementExtensible
- c语言定义数组中字母怎么输入,c语言数组怎么输入?
- 44、网络配线架如何打?超5类线水晶头与6类线水晶头制作方法
- 砍价两种种算法(转载)
- Matlab滤波器设计——基于filter函数的低通、高通、带通、带阻滤波器
- java pdf替换内容_java PDF批量替换关键词
- 嘎嘎好用的Vue虚拟键盘simple-keyboard
- Chromium网页Layer Tree创建过程分析
- python pip 的安装、更新、卸载、降级、和使用 pip 管理包
- 将列表(含字典)数据写入Excel
- Windows下Openpose试运行环境配置流程
- AIX smit设置设置能够输入中文
- 用Java实现植物大战僵尸的修改(续)
热门文章
- 使用MATLAB画出地球仪图形
- 倒立摆的实现 6.定时器中断和其余初始化
- vba的change事件
- H5 直播的疯狂点赞动画如何通过php直播平台源码实现(附完整源码)
- 裴蜀定理(贝祖定理) 证明与应用
- 工业螺旋齿轮行业调研报告 - 市场现状分析与发展前景预测(2021-2027年)
- 唯有硬核,方显本色丨云和恩墨五位数据库专家即将亮相openGauss Developer Day
- 小程序关注公众号组件<official-account ></official-account>的使用方法
- 手机文件管理android可以删除吗,手机上什么文件可以删除?答案都在这里了
- 编译原理 - 词法分析