简介
- 51单片机总共有P0、P1、P2、P3四个8位双向输入输出端口,每个端口都有锁存器、输出驱动器和输入缓冲器。4个I/O端口都能作输入输出口用,其中P0和P2通常用于对外部存储器的访问
- 将CPU芯片、存储器芯片、I/O接口芯片和简单的I/O设备(小键盘、LED显示器)等装配在一块印刷电路板上,再配上监控程序(固化在ROM中),就构成了一台单板微型计算机(简称单板机)在一片集成电路芯片上集成微处理器、存储器、I/O接口电路,从而构成了单芯片微型计算机,即单片机
- 定义单片机为TTL电平:
高 +5V 低 0V
RS232电平:计算机的串口
高 -12V 低+12V - CPU:由运算和控制逻辑组成,同时还包括中断系统和部分外部特殊功能寄存器;
RAM:用以存放可以读写的数据,如运算的中间结果、最终结果以及欲显示的数据;
ROM:用以存放程序、一些原始数据和表格;
I/O口:四个8位并行I/O口,既可用作输入,也可用作输出;
T/C:两个定时/记数器,既可以工作在定时模式,也可以工作在记数模式;
在无片外扩展存储器的系统中,这4个端口的每一位都可以作为准双向通用I/O端口使用。在具有片外扩展存储器的系统中,P2口作为高8位地址线,P0口分时作为低8位地址线和双向数据总线
ISP,IAP
内部的存储器可以由上位机的软件通过串口来进行改写。对于单片机来讲可以通过SPI或其它的串行接口接收上位机传来的数据并写入存储器中。例如STC单片机支持串口ISP下载。
在实现IAP功能时, 单片机内部一定要有两块存储区,一般一块被称为BOOT区,另外一块被称为存储区。单片机上电运行在BOOT区,如果有外部改写程序的条件满足,则对存储区的程序进行改写操作。如果外部改写程序的条件不满足,程序指针跳到存储区,开始执行放在存储区的程序,这样便实现了IAP功能。
一般ISP由单片机厂家实现,IAP由用户应用实现
https://blog.csdn.net/shenye1141664884/article/details/8514433
sfr:特殊功能寄存器声明
sfr 变量名=地址值;
*特殊功能寄存器在reg51.H这个头文件里面都帮我们定义好了,所以平时我们就不要自己去定义寄存器的名字。
sbit:特殊功能位声明
sbit 变量名=地址值;
*在给某个引脚取名的时候经常会用到。
bit:位变量声明
*用来定义位数据变量
例:sfr SCON = 0X98;
sbit LED = P0^2;
bit flags
#define GPIO_LED P2
sbit LED = P0^2;
_crol_循环移动函数需要#include<intrins.h>
- 电容符号cap 电解电容 cap -elec 电阻res 晶振crystal 二极管DIODE 按钮 button
respack上拉电阻 7seg数码管 - General Purpose Input Output (通用输入/输出)简称为GPIO,或总线扩展器,
Dispose处理 peripherals外围设备startup启动configuretion配置布局option选项pick挑选
定时器对内部机器脉冲计数,计数器对输入的外部脉冲计数。 - ISP (在系统可编程)/IAP (在应用可编程),无需专用编程器 / 仿真器
可通过串口(P3.0/P3.1)直接下载用户程序,8K 程序 3 秒即可完成一片
冷启动
stc的程序分引导区和程序区。引导区的代码主要负责ISP在线烧录。而stc的冷启动顺序就是先从引导区然后启动到程序区的。而热启动就是普通的51启动方式,只能从程序区头部开始重新执行。所以你必须冷启动。另外STC提供了一个特殊的寄存器地址,通过设置他能通过软件实现硬复位的功能直接跳转到引导区。这个你可以看STC的芯片说明书 IAP_CONTR 寄存器
STC单片机里面有一段出厂时固化的程序,这段程序的作用是检测串口是否要下载程序,不需要则执行单片机内的用户程序。每次启动时运行这端程序,这就是为什么每次下载时要冷启动。而复位后单片机是从地址0000H处开始执行,地址0000H又会指向主程序入口,即主函数处,即片内下载的用户程序而不会执行前面已经固化的检测串口那段程序。这就是为什么单片机每次下载要冷启动,而复位不行。注意,程序前面的宏定义什么的东西不占用系统时间,所以主程序即主函数处。
https://www.cnblogs.com/jikexianfeng/p/9047000.html
周期
在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。完成一个基本操作所需要的时间称为机器周期。一般情况下,8051单片机的机器周期由6个状态周期组成,也就是说一个机器周期=6个状态周期=12个时钟周期。
有些单片机,例如 STC 1T 系列的单片机,可以通过对特殊寄存器设置,运行于 1T 模式,一个机器周期=6个时钟周期,相当于快了一倍。
1个机器周期等于12个振荡周期,振荡周期也叫时钟周期,时钟周期即晶振的单位时间发出的脉冲数,如12MHZ=12×10的6次方,即每秒发出12000000个脉冲信号,那么发出一个脉冲的时间就是时钟周期,即1/12微秒;如11.0592MHZ=11.0592×10的6次方,即每秒发出11059200个脉冲信号,那么发出一个脉冲的时间就是时钟周期,即1/11.0592微秒)。
当80C51单片机晶振频率为12MHz时,时钟周期为(1/12)微秒,机械周期为1微秒。
时钟周期:一个时钟脉冲所需要的时间。在计算机组成原理中又叫T周期或节拍脉冲。是CPU和其他单片机的基本时间单位。它可以表示为时钟晶振频率(1秒钟的时钟脉冲数)的倒数(也就是1s/时钟脉冲数,比如1/12MHz),对CPU来说,在一个时钟周期内,CPU仅完成一个最基本的动作。
机器周期:通常用从内存中读取一个指令字的最短时间来规定CPU周期(机器周期),也即CPU完成一个基本操作所需的时间。通常一个机器周期包含12个时钟周期,在8051系列单片机的一个机器周期由6个S周期(状态周期)组成
时钟周期是计算机中最基本的、最小的时间单位。在一个时钟周期内,CPU仅完成一个最基本的动作。即:时钟周期为1/12us。
在51单片机中,1个机器周期等于12个振荡周期,则在计算定时时间t时:
计数值N乘以机器周期Tcy就是定时时间t 。
普中PPT
机器周期也就是CPU完成一个基本操作所需要的时间。
机器周期=1/单片机的时钟频率
51单片机内部时钟频率是外部时钟的12分频。也就是说当外部晶振的频率输入到单片机里面的时候要进行12分频。比如说你用的是12MHZ的晶振,那么单片机内部的时钟频率就是12/12MHZ,当你使用12MHZ的外部晶振的时候。机器周期=1/1M=1us
而我们定时1ms的初值是多少呢,1ms/1us=1000。也就是要计数1000个数,初值=65535-1000+1(因为实际上计数器计数到66636才溢出)=64536=FC18H
因为是16位计数器所以计数值65535
因为是加1计数器,所以用最大值减掉999(-1000+1)得到装载值
手册
外部时钟频率降一半,6T 模式: 传统的 8051 为每个机器周期 12 时钟,如将 STC 的增强型 8051 单片机在 ISP 烧录程序时设为双倍速(即 6T 模式,每个机器周期 6 时钟),则可将单片机外部时钟频率降低一半,有效的降低单片机时钟对外界的辐射
晶振电路使用的电容电阻,手册中有个表
特殊功能寄存器映像 SFR Mapping
addressable 可设定地址的; 可访问;
中断
void 函数名() interrupt 中断号 using 工作组,
中断号是指单片机中几个中断源的序号,"using 工作组"是指这个中断函数使用单片机内存中4组工作寄存器中的哪一组,C51编译器在编译程序时会自动分配工作组,所以最后这句话通常省略不写
- 80c51提供有5个中断源,分别为:2个外部中断,2个定时/计数器中断,1个串口发送/接收中断。并且具有2个中断优先级,可以实现2级中断服务程序嵌套。
TCON定时器计数器控制寄存器
reg51.h摘取如下
sfr TCON = 0x88;
/* TCON */
sbit TF1 = 0x8F;
sbit TR1 = 0x8E;
sbit TF0 = 0x8D;
sbit TR0 = 0x8C;
sbit IE1 = 0x8B;
sbit IT1 = 0x8A;
sbit IE0 = 0x89;
sbit IT0 = 0x88;
IE中断允许寄存器
IP中断优先级寄存器
上图不是TE1应该是IE1
void 函数名() interrupt 中断编号
void Int0() interrupt 0 //外部中断0的中断函数
定时器中断
80c51单片机内有两个可编程的定时/计数器T0、T1。它们是一个16位计数器,分别由一个高8位和一个低8位的寄存器组成的。TMOD是定时/计数器的工作方式寄存器,确定工作方式和功能;TCON是控制寄存器,控制T0、T1的启动和停止及设置溢出标志
定时/计数器实质上是一个加1计数器。它随着计数器的输入脉冲进行自加1,也就是每来一个脉冲,计数器就自动加1,,当加到计数器为全1时,再输入一个脉冲就使计数器回零,且计数器的溢出使相应的中断标志位置1,向CPU发出中断请求(定时/计数器中断允许时)。如果定时/计数器工作于定时模式,则表示定时时间已到;如果工作于计数模式,则表示计数值已满。可见,由溢出时计数器的值减去计数初值才是加1计数器的计数值
TMOD工作方式寄存器
M1,M0
方式0为13位计数,由TL0的低5位(高3位未用)和TH0的8位组成。TL0的低5位溢出时向TH0进位,TH0溢出时,置位TCON中的TF0标志,向CPU发出中断请求
方式1的计数位数是16位,由TL0作为低8位、TH0作为高8位,组成了16位加1计数器 。
计数个数与计数初值的关系为: X=216-N
- 方式2为自动重装初值的8位计数方式
X=28-N
工作方式2特别适合于用作较精确的脉冲信号发生器。
方式3只适用于定时/计数器T0,定时器T1处于方式3时相当于TR1=0,停止计数。
工作方式3将T0分成为两个独立的8位计数器TL0和TH0 。
串口
有两个物理上独立的接收、发送缓冲器SBUF,它们占用同一地址99H ;接收器是双缓冲结构 ;发送缓冲器,因为发送时CPU是主动的,不会产生重叠错误
异步通信的特点:不要求收发双方时钟的严格一致,实现容易,设备开销较小,但每个字符要附加2~3位用于起止位,各帧之间还有间隔,因此传输效率不高。
SCON串行控制寄存器
因为多级通信是在工作方式2和工作方式3下进行的,因此
SM2主要用在工作方式2和工作方式3。
当SM2=0时:不论接收的第9位是0还是1,都接收数据,产
生中断。当SM2=1时:只有在接收到的第9位为1时,才接收
数据,并产生中断;而如果接收到的第9位为0时,则将接收
到的数据丢弃,不产生中断。
电源管理寄存器PCON
POF :上电复位标志位,单片机停电后,上电复位标志位为 1 ,可由软件清 0 。
实际应用:要判断是上电复位(冷启动),还是外部复位脚输入复位信号产生的复位,还是内部看门狗复位,
可通过如下方法来判断:
P D:将其置 1 时,进入 Power Down 模式,可由外部中断低电平触发或下降沿触发中断模式唤醒。
进入掉电模式时,外部时钟停振,CPU 、定时器、串行口全部停止工作,只有外部中断继续工作。
IDL:将其置 1 时,进入 IDLE 模式(空闲),除 CPU 不工作外,其余仍继续工作,可由任何一个中断唤醒。
串行口的波特率是用定时器T1(手册的定时器2有TCLK,RCLK设置)作为波特率发生器的,这是定时器自动设置在工作方式2(可自动重装初值)。
波特率=((2SMOD)/32)定时器T1的溢出率
定时器T1的溢出率=单片机内部时钟频率/(256-X)
X是定时器的初值
波特率=(2SMOD)/32(单片机内部时钟频率/(256-X))
void UsartConfiguration()
{
SCON=0X50; //设置为工作方式1
TMOD=0X20; //设置计数器工作方式2
PCON=0X80; //SMOD=1,波特率加倍
TH1=0XF3; //计数器初始值设置,注意波特率是4800的
TL1=0XF3;
ES=1; //打开接收中断
EA=1; //打开总中断
TR1=1; //打开计数器
}
计算:
波特率=((2SMOD)/32)*定时器T1的溢出率
=(21/32)X溢出率
溢出率=单片机内部时钟频率/(256-X)=(1x106)/(256-243)
最终波特率=4800左右
内部时钟频率是外部时钟的12分频,实际是11.0592M,用12M计算的
定时器1的工作方式2,是8位,所以TH,TL填的是一样的
串口中断服务函数
void Usart() interrupt 4
{
unsigned char receiveData;
receiveData=SBUF;//出去接收到的数据
RI = 0;//清除接收中断标志位
SBUF=receiveData;//将接收到的数据放入到发送寄存器
while(!TI); //等待发送数据完成
TI=0; //清除发送完成标志位
}
实验例程
- 数码管段选指的共阳共地那一端,位选控制显示数字
- 共阴极公共端接地,所以位选是低电平有效,段选是高电平有效
- Vss负极 VDD正极 Vcc正极
定时器对内部机器脉冲计数,计数器对输入的外部脉冲计数。
显示RAM区每个字节对应屏上点的排列方式为:纵向排列,低位在上,高位在下
十进制 D 或不加 二进制B 八进制 O
十六进制加H
COB(板上芯片直装)
PORT是数据的输出寄存器
TMOD工作方式寄存器
TCON定时器控制寄存器
IE中断允许寄存器
IP中断优先级寄存器
SCON串行控制寄存器 字节地址0x98
PCON电源管理寄存器 字节地址0x87
typedef unsigned char u8; (加分号)
#define AREA 3.14 (不加分号)
crol(a,b)循环左移
cror(a,b)循环右移
Output enable and reset 输出使能和复位
MSB最高位
仿真调试
51不能硬件仿真
- 已经固化仿真程序的仿真芯片,如SST89E58、SST89E516 2、带有串口资源的目
标板,如开发板
硬件链接步骤:
1、将仿真芯片直接插到目标板上,代替原有单片机的位置。
2、连接电脑的串口和目标板的串口端子,没有串口的电脑使用usb 转串口线
3、连接好电源,打开电源开关
KEIL4设置好以后,点击仿真调试,出现
说明通讯异常请按一下目标板复位键或者重新启动电源,然后点击
“Try Again”即可,如果多次尝试仍不能进入仿真界面,请点击“Settings”检测
端口和波特率是 否正确。然后重复操作
开发板可直接安 装在线仿 真芯片SST89E16RD,将仿真芯片安装在开发板上后便可直接进行在线单步、全速调试等。仿真芯片的作用:仿真芯片可以实现计算机与开发板之间的真正在线调试,用KEIL 软件连接好仿真器后可以在软件调试模式下进行单步的执行指令、全速执行指令、设置断点等。每执行一条指令都可看见开发板的运行状态,并且可随时查看各个变量的值,对初学者非常有帮助。如果不使用仿真芯片而直接使用板上单片机调试程序只能全速执行指令,通过观察开发板现象来重新修改程序,然后再次下载。TX-1C 系列学习板使用仿真功能时只需要把原来板上的单片机取下,安装仿真芯片按照光盘里的仿真说明教程即可实现仿真调试
摘录
8051片内有4kB的程序存储单元,其地址为0000H—0FFFH,单片机启动复位后,程序计数器的内容为0000H,所以系统将从0000H单元开始执行程序。但在程序存储中有些特殊的单元,这在使用中应加以注意:
其中一组特殊是0000H—0002H单元,系统复位后,PC为0000H,单片机从0000H单元开始执行程序,如果程序不是从0000H单元开始,则应在这三个单元中存放一条无条件转移指令,让CPU直接去执行用户指定的程序。
另一组特殊单元是0003H—002AH,这40个单元各有用途,它们被均匀地分为五段,它们的定义如下:
0003H—000AH 外部中断0中断地址区。
000BH—0012H 定时/计数器0中断地址区。
0013H—001AH 外部中断1中断地址区。
001BH—0022H 定时/计数器1中断地址区。
0023H—002AH 串行中断地址区。
可见以上的40个单元是专门用于存放中断处理程序的地址单元,中断响应后,按中断的类型,自动转到各自的中断区去执行程序。因此以上地址单元不能用于存放程序的其他内容,只能存放中断服务程序。但是通常情况下,每段只有8个地址单元是不能存下完整的中断服务程序的,因而一般也在中断响应的地址区安放一条无条件转移指令,指向程序存储器的其它真正存放中断服务程序的空间去执行,这样中断响应后,CPU读到这条转移指令,便转向其他地方去继续执行中断服务程序
程序状态字寄存器(PSW)
累加器ACC(Accumulator)
累加器A是一个最常用的专用寄存器,大部分单操作指令的一个操作数取自累加器,很多双操作数指令中的一个操作数也取自累加器。加、减、乘、除法运算的指令,运算结果都存放于累加器A或AB累加器对中。大部分的数据操作都会通过累加器A进行,它形象于一个交通要道,在程序比较复杂的运算中,累加器成了制约软件效率的“瓶颈”,它的功能较多,地位也十分重要。以至于后来发展的单片机,有的集成了多累加器结构,或者使用寄存器阵列来代替累加器,即赋予更多寄存器以累加器的功能,目的是解决累加器的“交通堵塞”问题。提高单片机的软件效率。
寄存器B
在乘除法指令中,乘法指令中的两个操作数分别取自累加器A和寄存器B,其结果存放于AB寄存器对中。除法指令中,被除数取自累加器A,除数取自寄存器B,结果商存放于累加器A,余数存放于寄存器B中。
PSW.7(CY) 进位标志位,此位有两个功能:一是存放执行某写算数运算时,存放进位标志,可被硬件或软件置位或清零。二是在位操作中作累加位使用。
PSW.6(AC) 辅助进位标志位,当进行加、减运算时当有低4位向高4位进位或借位时,AC置位,否则被清零。AC辅助进位位也常用于十进制调整。
PSW.5(F0) 用户标志位,供用户设置的标志位。
PSW.4、PSW.3(RS1和 RS0) 寄存器组选择位。可参见本章的图2定义。
PSW.2(OV) 溢出标志。带符号加减运算中,超出了累加器A所能表示的符号数有效范围(-128—+127)时,即产生溢出,OV=1。表明运算运算结果错误。如果OV=0,表明运算结果正确。
执行加法指令ADD时,当位6向位7进位,而位7不向C进位时,OV=1。或者位6不向位7进位,而位7向C进位时,同样OV=1。
除法指令,乘积超过255时,OV=1。表面乘积在AB寄存器对中。若OV=0,则说明乘积没有超过255,乘积只在累加器A中。
除法指令,OV=1,表示除数为0,运算不被执行。否则OV=0。
PSW.0(P) 奇偶校验位。声明累加器A的奇偶性,每个指令周期都由硬件来置位或清零,若值为1的位数奇数,则P置位,否则清零
WARNING ERROR(转载)
WARNING L15: MULTIPLE CALL TO SEGMENT这个问题!
其实这个问题应该是引起注意的,有可能引起程序冲突,但是一般时候程序运行不会有问题,但是如果出来问题,那将会是很讨厌的问题.
分析一下 产生这一警告的一个根源是:例如在主循环里调用了一个函数,而在中断服务中,你又一次调用了同样的函数。这样当主循环运行到该函数中时, 一旦产生中断,则在中断里又再次调用该函数!而使得该子函数发生了重入,这时,经管概率很低,但是很可能出错!这样,编译器就给出了警告!告诉你*** WARNING L15: MULTIPLE CALL TO SEGMENT ,表达的意思是发生了重入
想要避免这种情况的方法
一.用reentrant使函数重入
关于reentrant的说明:
1,重入函数不能传递bit类型的参数和变量;
2,重入函数建立的是模拟堆栈区,所以不使用一般函数位于存储模式默认空间的可覆盖式堆栈,而是在同一空间从顶端另行分配一个非覆盖式的重入堆栈。
small 默认空间是 data;
compact 默认空间是 pdata;
largr 默认空间是 xdata;
3,由于要保存参数和局部变量,所以会消耗很大的栈空间;尽量少用这种模式;
4、 在同一程序中可以定义和使用不同存储器模式的重入函数,任意模式的重入函数不能调用不同存储器模式的重入函数,但可以调用普通函数。
5、 实际参数可以传递给间接调用的重入函数。无重入属性的间接调用函数不能包含调用参数。
二.如果空间多的话,可以定义两个同功能的函数,分别在中断和中断外调用
别的方法没研究出来,嘿嘿~对了 我建议用第二种方法好点,第一种有些限制,不爽
三.主程序调用该函数时禁止中断。
可以在该函数被调用时用#pragma disable语句来实现禁止中断的目的。必须使用OVERLAY指令将该函数从覆盖分析中除去。
也可以用EA=1,EA=0来开关中断
最后,WARNING L15: MULTIPLE CALL TO SEGMENT
这个问题必须注意,可能引起程序冲突,假设你用于自动化领域,则可能导致信号产生尖峰。 产生这一警告的一个根源是:你在主循环 里调用了一个函数(如aaa),而在中断服务函数里,你用调用了这个函数(如aaa)。这样当主循环运行到该函数中 是,一旦产生中断,则在中断里又再次调用该函数!这时,很可能出错! 避免这种情况的方法很多:如,在进中断的时候置需调用该函数的标志,而在主循环中调用该函数
其实,80并口全称为8080并口协议是有因特尔公司提出的,除8080接口协议外还有摩托罗拉的6800接口协议,其不同在于控制器,如下
8080是通过“读使能(RE)”和“写使能(WE)”两条控制线进行读写操作 6800是通过“总使能(E)”和“读写选择(W/R)”两条控制线进行
8080是通过“读使能(RE)”和“写使能(WE)”两条控制线进行读写操作 6800是通过“总使能(E)”和“读写选择(W/R)”两条控制线进行
1)8080模式。
这类模式通常有下列接口信号:
/RES(复位线),DB0~DB7(双向数据线),D/I(数据/指令选择线,1:数据读写,0
命令读写),CS(片选信号线,如果有多片组合,可有多条片选信号线),/WR(MPU向LCD写入数据控制线),/RD(MPU从LCD读入数据控制线);
2)6800模式。
在这种模式下,/RES、DB0~DB7、D/I的功能同模式(1),其他信号线为:R/W读写控制(1:MPU读, 0:MPU写)。
E,允许信号(多片组合时,可有多条允许信号线)。
M68是摩托罗拉的标准接口,I80是英特尔的标准接口 Lcd控制和传输数据所需管脚列表