大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。
Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺
关于这个复习的资源:扫描二维码:
或者网址:点击
第一章:单片机的基础知识
1.什么是单片机?特点?
将通用微型计算机基本功能部件集成在一块芯片上构成的一种专用微计算机系统(嵌入式系统),用于解决小型被控对象的智能化问题(SCM或MCU)。
特点:
体积小(便于嵌入到小型被控对象中);
扩展性好(便于组成各种应用系统);
可靠性高(集成后外部连线减少,抗干扰能力增强);
价格低廉(便于普及应用)
2.单片机的发展趋势
3.进制之间的转换搞明白点
注意下有符号数还是无符号数
基本逻辑电路图
- 基本逻辑电路图
在逻辑门电路中,输入输出分为二种状态:高电平和低电平。我们常用1表示高电平,0表示低电平
与门:A*B
或门:A+B
扩展一下:这是所有的门电路,如下图所示:
Proteus的使用
1 .Proteus的基本用法——绘制原理图和调试
2 Proteus ——ARES布局
3 Keil4和Protues联调的做法
第一章:课后习题
课后习题汇总(选择+问答题):
(1) 单片机又称为单片微计算机,最初的英文缩写是____。 答案
A.MCP ——- B.CPU
C.DPJ ——– D.SCM
考验单片机定义知识点
将通用微型计算机基本功能部件集成在一块芯片上构成的一种专用微计算机系统(嵌入式系统),用于解决小型被控对象的智能化问题(SCM或MCU)。SCM或者MCU
8位单片机主流
3) 单片机的特点里没有包括在内的是______。答案
A.集成度高 B.功耗低 C.密封性强 D.性价比高
考验知识点单片机的优势:
体积小(便于嵌入到小型被控对象中);
扩展性好(便于组成各种应用系统);
可靠性高(集成后外部连线减少,抗干扰能力增强)
价格低廉(便于普及应用)。
19)下列集成门电路中具有与门功能的是______。答案
A.74LS32 B.74LS06 C.74LS10 D.74LS08
考验知识点逻辑门电路:
如上面图
24)家用电器如冰箱、空调、洗衣机中使用的单片机主要是利用了它的______能力。答案(D)
A.高速运算B.海量存储C.远程通信D.测量控制
问答题
1)什么是单片机?单片机与通用微机相比有何特点?
第一个如上面单片机定义,第二个
两者的比较:(1) 通用微机的CPU主要面向数据处理,其发展主要围绕数据处理功能、计算速度和精度的提高。单片机主要面向控制,数据类型、计算速度和精度都相对低一些;(2) 通用微机中存储器组织结构主要针对增大存储容量和CPU对数据的存取速度。单片机中存储器的组织结构比较简单,寻址空间一般都为64 KB;(3) 通用微机中I/O接口主要面向标准外设(如显示器、键盘、鼠标、打印机等)。单片机的I/O接口是面向用户的特定电路,需要用户掌握接口电路设计技术。
2) 单片机的发展有哪几个阶段?它今后的发展趋势是什么?
1、单片微型计算机阶段,即SCM,代表性产品是Intel公司的8位MCS-51系列单片机;今后的发展趋势如上(高性能,低功耗,集成度高,性价比高,位数越来越高,丰富的产品系列,外设接口内置化
(3) 举例说明单片机的主要应用领域。 编就完事了
主要应用于领域:1、工业自动化控制,如过程控制器、机器人模块、物流计量模块、机电一体化控制系统等;2、智能仪器仪表,如温度仪表、流量仪表、分析仪器、医疗仪器、智能传感器等;3、通信设备,如路由器、标准键盘、打印机、传真机、复印机等;4、汽车电子与航空电子系统,如动力监测系统、自动驾驭系统、运行监视器(黑匣子)等;5、家用电器,如空调、冰箱、洗衣机、微波炉、电视机、音响、电子玩具等。
4)在众多单片机类型中,8位单片机为何不会过时,还占据着单片机应用的主导地位?
51单片机技术成熟、价格低廉,可以满足许多简单工况的应用要求;基于51单片机内核发展的8位高性能单片机已弥补了51单片机的性能不足,并已占有相当的市场份额;51单片机涉及微机原理、电工电路、软件编程等许多技术基础,主流微控制器产品也大都与51机保持兼容,非常适合初学者作为计算机入门知识。综上所述,由于8位单片机在学习和应用方面的独特地位,目前仍然不会过时淘汰。
5)何谓PCB?利用Proteus ARES模块进行PCB设计需要经过哪几个主要步骤? 提示
PCB是印刷电路板Printed circuit board的英文缩写,它是以绝缘板为基材,切成一定尺寸,其上附有用电子印刷术制成的导电图形和孔眼(如元件孔、紧固孔、金属化孔等)的电子元器件安装底板。利用ARES模块进行PCB设计可以从元器件布局、布线、覆铜、形成光绘文件等方面进行考虑。
=====================================================================
第二章:mcs51单片机的结构与原理
—————————————————————————-=====================
C51的内部结构
1. 80C51的内部结构
2.程序PC的基本特点
PC是CPU控制器的一部分
CPU分为控制器和运算器两部分,控制器的作用就是对ROM中的指令进行译码,发出各种操作需要的控制信号,完成指令所规定的功能。
流程为:从ROM中取出指令——译码——执行指令
控制器由: 程序计数器PC,指令寄存器,指令译码
器,数据指针寄存器以及定时控制与条件转移逻辑电路等组成。
3.数据指针寄存器DPTR等
注:可拆分为2个独立的8位寄存器DPL和DPH
4。累加器A的主要特点
累加器A也叫累加器ACC。
属于CPU运算器的一部分
运算器由算术逻辑部件ALU,累加器ACC,程序状态字寄存器PSW及运算调整电路等组成。
作用为:对数据进行算数计算和逻辑处理。
流程:计算缓存器内容——结果暂存——修改运行状态
继续
psw的计算
5.程序状态字寄存器PSW的主要特点
储存程序运行过程中的各种状态信息的寄存器
一个一个来,PSW最后一位是CY进位标志,如果最高位有进位或者借位,CY=1,否则为0;】
例子:
· 10010011
+11110000
—————-
110000011
进位了,CY为1;
然后是辅助进位标志AC:在进行加减运算时候, 如果低4位,向高4位产生借位或者进位时候AC为1,否则清0;看第5位变化。
例子:
01001111
+10100001
————————
11110000
第五位变化了,进一位,所以AC=1;
/F0 是用户标志位,由用户决定0/1;状态标志
/RS1、RS2:工作寄存器组指针,用于选择CPU当前工作的寄存器组。
/OV溢出标志:如果超过8位数所能表示的氛围(-128——127)
则OV=1,否则为0;根据OV状态可以判断累加器A的运算结果是否正确
OV还可以这样算:
OV=C6y异或运算C7y
其中C6y与C7y分别是位6和位7的进位或者借位状态,如果有进位或者借位,为1,否则为0;
例子:
0 1 0 1 0 1 0 0 (+84)
+
0 1 1 0 1 0 0 1 (+105)
—————————————
1 0 1 1 1 1 0 1 (-189)
CY=0;
由于第6位无进位,位7有进位,
OV=1(异或0与1)
证明了:
由于两个正数相加不可能为负数,所有结果肯定为错OV=1;
/F1:也是用户标志位。同F0
/P:奇偶标志位,看含1的个数,如果为奇数个,则为1;
否则为0;
在串行通信中,常用来检验数据传输的正确性。
CY进位标志
AC辅助进位标志
F0 F1 用户标志位
RS1,RS2 工作寄存器组指针
OV 溢出标志
P 奇偶标志位
奇偶校验用吧可能
这个计算还挺容易出的,多看看
MCS-51单片机的引脚
双口:
四端
这40只引脚按功能划分,可分为三类:
- 电源及晶振引脚(共4只)——Vcc、Vss、XTAL1、XTAL2
- 控制引脚(共4只)——ALE/PROG(30)、PSEN(29)、EA/ VPP (31)
- 端口引脚(共32只)——P0.0~P0.7(39~32脚)——P0口 P1.0~P1.7(1~8脚)——P1口 P2.0~P2.7(21~28脚)——P2口 P3.0~P3.7(10~17脚)——P3口
8只/组×4 组= 32 只引脚
下面分别介绍:
电源V及晶振X引脚
控制引脚 RST ALE PSEN EA
端口引脚 P
MCS-51 单片机的存储器结构
ROM RAM
1.存储器的二种结构形式?51单片机的物理储存空间和逻辑存储空间?
51单片机的物理储存空间和逻辑存储空间?
片内片外
mcs-51单片机共有4个储存空间,即片内ROM,片外ROM,片内RAM,片外RAM。
由于片内,片外ROM是统一编址的,因此从逻辑地址看,ROM变为一体,如上图
片外ROM
{片内ROM(EA=1)
片外ROM(EA=0)}
MCS-51单片机的片内ROM地址空间为0000H~0FFFH
片外ROM为0000H~0FFFH 1000H~FFFFH
片内RAM为00H~~FFH,片外RAM为0000H——FFFFH;
他们的组合模式:
4KB=1000H
因为ROM在一个逻辑结构中,所以四个物理存储空间仅当三个逻辑存储空间
ROM有6个特殊存储器单元——用于程序引导
数据存储器 RAM
00H~7FH
80H~FFH
- 高128字节(特殊功能寄存器)片内RAM的特点?
片内RAM分为低128B(普通RAM)地址是00H—7FH,高128B(特殊功能寄存器)为80H—FFH
复位电路
4.单片机复位条件?复位电路?
复位:恢复原始状态
复位条件:
复位方式有二种:上电复位和按键复位(如下图),或者混合复位(如上图)
上电复位:利用阻容充电电路得到,在单片机上电时,RST端的电位与Vcc相同(这时候电压很大)。随着充电电流的减小。RST端的电压降低。
按键复位:利用电阻分压实现的,当按键压下的时候,串联电阻可以使得RST产生高电压,按键抬起时候产生低电压。
实际中,常常采用两者一起使用的做法。
时序
时钟周期、机器周期和指令周期
指令周期:计算机取一条指令至执行完该指令需要的时间称为指令周期。
机器周期:机器周期是单片机的基本操作周期,每个机器周期包含S1.S2.S66个状态,每个状态包含2拍P1和P2,每一拍为一个时钟周期(振荡周期)。因此,一个机器周期包含12个时钟周期。
例如:若晶振频率为12MHz,则MCS-51单片机的4种时序周期的具体值为:
时钟周期=1/12(us)
状态周期=1/6 (us)
机器周期=1(us)
指令周期=1~4(us)
所以一个机器周期=6个状态周期=12个时钟周期
D触发器
I/O口
P1
P3
P0
P2
p0~p3口对比
因为P0~P3口都需要先软件写1,故都是准双向I/0口。
而在分时复用中,P0口读引脚时无需软件写1,故是严格双向口
在通用1/0口方式时,P0口需要外接上拉电阻(漏极开路),而P1~P3口无需外接上拉电阻(已有内置上拉电阻);
在分时复用方式时,P0口无需外接上拉电阻(V管交替导通)。
P0和P2有地址/数据分时复用方式,P3口有第二功能
单片机P3口第二功能,各位定义如下:
P3.0 RXD(串行口输入),接收数据的引脚;
P3.TXD(串行口输出),发送数据的引脚;
P3.2 /INT0(外部中断0输入);
P3.3 /INT1(外部中断1输入);
P3.4 T0(定时器/计数器0的外部输入);
P3.5 T1(定时器/计数器1的外部输入);
P3.6 /WR (片外数据存储器写选通控制输出);
P3.7 /RD(片外数据存储器读选通控制输出);
当P3口用作第二功能情况下输出时,锁存器输出为“1”,打开与非门,第二输出功能端内容通过“与非门”和FET(场效应管)送至端口引脚,实现输出。输入时,端口引脚的第二功能信号通过缓冲器送到输入端。
看表:
首先看下总结:
第二章:课后习题
1) 下列关于程序计数器PC的描述中____是错误的。
A.PC不属于特殊功能寄存器
B.PC中的计数值可被编程指令修改
C.PC可寻址64KB RAM空间
D.PC中存放着下一条指令的首地址
考察:PC的内容知识点
PC不属于特殊功能寄存器
不能寻址RAM空间。
PC为16位寄存器,64KB
(2) MCS-51单片机的复位信号是______有效。 答案
A.下降沿 B.上升沿 C.低电平 D.高电平
考察:MCS51-单片机的复位
51单片机复位的条件是:在RST引脚处出现
时间>=10ms,电压>=3V的高电平状态。
也就是突然高电平有效
(3) 以下选项中第______项不是80C51单片机的基本配置。答案
A.定时/计数器T2
B.128B片内RAM
C.4KB片内ROM
D.全双工异步串行口
考察:单片机的基本结构
51单片机的基本结构
8位CPU
128B RAM存储器
21个专用寄存器(亦称特殊功能寄存器SFR)
4KB ROM存储器
4个8位并行口
1个全双工的串行口
2个16位的定时器/计数器
一个处理能力较强的中断系统。
51单片机内的二个定时器计数器·为 T0和T1
T2是52系列单片机内的,52系列有三个·定时器·计数器·
(5) 在51单片机的下列特殊功能寄存器中,具有16位字长的是______。答案
A.PCON B.TCON C.SCON D.DPTR
考察单片机的特殊功能寄存器
21个SFR、
就认识个DPTR 又是16位的
全部如下图
=
(6) 80C51单片机的ALE引脚是______引脚。
A.地址锁存使能输出端
B.外部程序存储器地址允许输入端
C.串行通信口输出端
D.复位信号输入端
考察单片机各个引脚的功能:
单片机的40个引脚大致可分为4类:电源、时钟、控制和I/O引脚。
⒈ 电源: ⑴ VCC – 芯片电源,接+5V;
⑵ VSS – 接地端;
⒉ 时钟:XTAL1、XTAL2 – 晶体振荡电路反相输入端和输出端。
⒊ 控制线:控制线共有4根,
⑴ ALE/PROG:地址锁存允许/片内EPROM编程脉冲
① ALE功能:用来锁存P0口送出的低8位地址
② PROG功能:片内有EPROM的芯片,在EPROM编程期间,此引脚输入编程脉冲。
⑵ PSEN:外ROM读选通信号。
⑶ RST/VPD:复位/备用电源。
① RST(Reset)功能:复位信号输入端。
② VPD功能:在Vcc掉电情况下,接备用电源。
⑷ EA/Vpp:内外ROM选择/片内EPROM编程电源。
① EA功能:内外ROM选择端。
② Vpp功能:片内有EPROM的芯片,在EPROM编程期间,施加编程电源Vpp。
⒋ I/O线
80C51共有4个8位并行I/O端口:P0、P1、P2、P3口,共32个引脚。P3口还具有第二功能,用于特殊信号输入输出和控制信号(属控制总线)。
80C51单片机的引脚及其功能介绍
如上图所示:
p0,p1,p2,p3四个8位并行口
RST/VPD:复位/备用电源。
RST:复位信号输入端,复位电路
VPD:在Vcc掉电情况下,接备用电源。
RXD/TXD:串口通信;
INTO/INT1:外部中断控制
TO/T1:计时器计数器
WR/RD:一个写wirte 一个读 read
XTAL1/XTAL2:时钟信号 晶体振荡电路反相输入端和输出端。
EA/VPP:内外ROM选择/片内EPROM编程电源。
EA:外部ROM允许控制。当EA=1,CPU开始从片内ROM开始读取指令。当程序计数器PC的值超过4KB地址范围时,将自动转向执行片外ROM的指令。
当EA=0时候,CPU只访问读取片外ROM。
VPP:应接12V电压,在对含有EPROM的单片机进行EPROM编程时候。
PSEN:输出访问片外ROM的读选通信号 (外ROM读选通信号。)
ALE/PROG:
ALE:地址锁存使能输出 (用来锁存P0口送出的低8位地址)
当单片机访问外部储存器时候,外部储存器的16位地址信号由P0口输出低8位,P2口输出高8位,
ALE可用作低8位地址锁存控制信号
PROG:对含有EPROM的单片机,在进行片内EPROM编程的时候需要由此输入编程脉冲
(12)80C51单片机要使用片内RAM,/EA引脚______。答案
A.必须接+5V ——— B.必须接地 ——- C.必须悬空 —— D.没有限定
利用EA引脚可以对片内片外ROM进行选择,并不能选择RAM
当EA引脚接1 EA=1 接高电平时候: 小于等于4KB的地址是在片内ROM,大于4KB的地址在片外ROM中,两者构成64KB空间
当EA引脚接低电平 EA=0时候:片内ROM全部被禁用,全部64KB地址都在片外ROM中
EA引脚接VCC电压,或者悬空都是高电平状态;
18)80C51单片机的/EA引脚接+5V时,程序计数器PC的有效地址范围是(假设系统没有外接ROM)______。
A.1000H~FFFFH
B.0000H~FFFFH
C.0001H~0FFFH
D.0000H~0FFFH
注意题中说明的没有外接ROM即是没有片外ROM
如果用户使用80C51单片机且程序长度不超过4KB,则无需片外ROM,仅使用片内ROM,但必须保持
EA引脚高电平 即EA引脚接VCC电压,或者悬空都是高电平状态;
而片内ROM的范围是0000H~0FFFH
19)当程序状态字寄存器PSW中的R0和R1分别为0和1时,系统选用的工作寄存器组为______。
A.组0 B.组1 C.组2 D.组3
如下:按照二进制记忆
RS1 RS0 | 组号 |
---|---|
0 0 | 0 |
0 1 | 1 |
1 0 | 2 |
1 1 | 3 |
!注意是RS1在前面,RS0在后面
别栽在这上面
(20)80C51单片机的内部RAM中具有位地址的字节地址范围是______。答案(B)
A.0~1FH
B.20H~2FH
C.30H~5FH
D.60H~7FH
片内RAM具有00H~FFH(256B),具有四个区域
如图
片内RAM在最左边:
00H~1FH:工作寄存器区
20H~2FH:位寻址区
30H~7FH:用户RAM区
80H~FFH:特殊功能寄存器区(最上面)
理解点
!21) 若80C51单片机的机器周期为12微秒,则其晶振频率为______MHz。答案(A)
A.1 B.2 C.6 D.12
考察:程序的时序
若晶振频率为12MHz,则MCS-51单片机的4种时序周期的具体值为:
时钟周期=1/12(us)
状态周期=1/6 (us)
机器周期=1(us)
指令周期=1~4(us)
所以一个机器周期=6个状态周期=12个时钟周期
这里先设晶振xmhz
单片机的晶振为xmhz,说明1s产生x个脉冲,那么1个脉冲的时间是1/x,即时钟周期为1/x。—
12个时钟周期=1个机器周期
所以1/x*12=12us,即晶振为1mhz
好家伙注意一下这种变形题,跟上面找组数一样就是变个型
(25)PSW=18H时,则当前工作寄存器是______。答案(D)
A.第0组 B.第1组 C.第2组 D.第3组
PSW的各位都有意义
18H转成二进制是0001 1000
而PSW是一个8位二进制寄存器,它的每位都有对应的意义,
CY AC F0 RS1 RS0.OV F1 P
依次从第7位到第0位
思考题
(1)51单片机内部结构由哪些基本部件组成?各有什么功能?
其中CPU具有解释指令、执行操作、控制时序和处理数据等功能;ROM主要用于存放程序代码及程序中用到的常数;RAM主要用于存放中间运算结果、数据暂存和标志位等信息;定时/计数器可实现定时控制、脉冲计数和波特率发生器功能;可编程I/O口可以实现单片机与外部设备间的数据与信息传输功能;可编程串行口具有单片机与外部串行设备间的数据的收发功能;时钟振荡器具有产生单片机各系统所必需的时钟信号的功能。
2) 单片机的程序状态字寄存器PSW中各位的定义分别是什么? 提示
CY(PSW7)进位标志,AC(PSW6)辅助进位标志,F0(PSW5)用户标志位,RS1、RS0(PSW4、PSW3)工作寄存器组指针,OV(PSW2)溢出标志,F1(PSW1)用户标志位。
P(PSW0)奇偶校验位
51单片机引脚按功能可分为哪几类?各类中包含的引脚名称是什么? 提示
电源及晶振引脚(4只)——VCC、VSS、XTAL1、XTAL2;控制引脚(4只)——/PSEN,ALE、/EA、RST;并行 I/O口引脚(32只)——P0.0~P0.7、P1.0~P1.7、P2.0~P2.7、P3.0~P3.7。
4)51单片机在没接外部存储器时,ALE引脚上输出的脉冲频率是多少? 提示
6分频 晶振频率 6MHZ
(5)计算机存储器地址空间有哪几种结构形式?51单片机属于哪种结构形式? 提示
普林斯顿结构是一种将程序指令存储器和数据存储器合并在一起的存储器结构,即ROM和RAM位于同一存储空间的不同物理位置处。哈佛结构是一种将程序指令存储器和数据存储器分开设置的存储器结构,即ROM和RAM位于不同的存储空间。51系列单片机属于这种结构。
6)如何认识80C51存储空间在物理结构上可划分为4个空间,而在逻辑上又可划分为3个空间?
51系列单片机共有4个存储空间,即片内ROM、片外ROM、片内RAM和片外RAM。由于片内、片外程序存储器是统一编址的,因此从逻辑地址来看只有3个存储器空间,即ROM、片内RAM和片外RAM。
4个物理空间
3个逻辑空间
(7)80C51片内低128B RAM区按功能可分为哪几个组成部分?各部分的主要特点是什么? 提示
可分为3个组成部分:地址00H~1FH的32个数据存储单元可作为工作寄存器使用。这32个单元又分为4组,每组8个单元,按序命名为通用寄存器R0~R7;地址为20H~2FH的16字节单元,既可以像普通RAM单元按字节地址进行存取,又可以按位进行存取。这16字节共有128个二进制位,位地址为00H~7FH;地址为30H~7FH的80字节单元为用户RAM区,这个区只能按字节存取。在此区内用户可以设置堆栈区和存储中间数据。
(8)80C51片内高128B RAM区与低128B RAM区相比有何特点? 提示
高128B RAM区中仅有21个字节单元(称为特殊功能寄存器)可被用户使用,其余为系统保留单元用户不可用,而低128 RAM区的所有单元用户都可使用。
10)什么是复位?单片机复位方式有哪几种?复位条件是什么? 提示
单片机在开机和死机时需要复位,以便使各功能部件处于一个确定的初始状态开始工作。复位可以由两种方式产生,即上电复位方式和按键复位方式。复位的条件是,在RST引脚端出现满足复位时间要求的高电平状态,该时间等于系统时钟振荡周期建立时间再加2个机器周期时间(一般不小于10ms)。
(11) 什么是时钟周期和指令周期?当振荡频率为12MHz时,一个机器周期为多少微秒? 提示
晶振或外加振荡源的振荡周期称为时钟周期,执行一条指令所需要的时间称为指令周期。振荡频率为12MHz时,一个机器周期为1微秒。
12)简述负边沿D触发器的输入端、时钟端和输出端之间的时序关系,解释D触发器的导通、隔离、锁存功能的实现原理。 提示
当时钟端为脉冲下降沿之前时,输入端和输出端之间是断开的,此时两者间为隔离状态;当时钟端为脉冲下降沿时,输入端和输出端之间是导通的,输出端跟随输入端变化;当时钟端为脉冲下降沿之后时,输入端和输出端之间又是断开的,此时输出端的状态不会随输入端变化,即为锁存状态。
(13)如何理解单片机I/O端口与特殊功能寄存器P0~P3的关系? 提示
I/O端口P0~P3对应于并行I/O口的单元电路,特殊功能寄存器P0~P3则可视为并行I/O口中的4个8位的D触发器。
(14) 如何理解通用I/O口的准双向性?怎样确保读引脚所获信息的正确性? 提示
无条件输出和有条件输入的I/O口称为准双向I/O口,读引脚前先写1到I/O口可避免引脚内电位被钳制到0
(15) 80C51中哪个并行I/O口存在漏极开路问题?此时没有外接上拉电阻会有何问题? 提示
P0口工作在通用I/O口方式时,上拉场效应管V2将处于截止状态,由此会产生漏极开路现象,此时若没有外接上拉电阻会造成P0口引脚的电平状态不确定。
(16) P0端口中的地址/数据复用功能是如何实现的? 提示
当希望利用P0口传输CPU地址和数据信息时,需要先使与门A解锁,同时使多路开关MUX与非门X接通,这样内部“地址/数据”端的电平便可传输到引脚P0.n上。与经由锁存器输出的通用I/O口方式不同,这种方式称为地址/数据分时复用方式。不过要使传输到P0.n上的地址和数据信息分开还需要地址/数据锁存接口电路的配合才行。
终于到了第三章,开始敲代码了,要死、
第三章:mcs51单片机的汇编
汇编语言基本语法
汇编语言的格式:
{标号:} 操作码 {操作数} {;注释}
例如:START:MOV A,#12H ;机器码为7412H
这条指令的标号为“START”,操作码为“MOV”,操作数为“A,#12H”
注释内容为机器码为7412H。
START对应机器码’74‘在ROM中的存放地址
就是指令的首字节地址
汇编语言中的标识符,16进制地址和立即数容易混淆:
标识符——标号或汇编符号统称为标识符,由英文字母开头的1~6个字符组成。例如EAH,C6A等;
16进制地址——若储存单元地址的最高位值>9时,应加上前缀”0“以区别于标识符。例如0EAH,5AH等
立即数——出现在指令中的常数叫做立即数,应加前缀”#“以区别于地址。例如#0EAH,#5AH等
简记符号
下面 > 用于描述指令操作数的简记符号一览表:
注意不能越界,因为简记符号都有明确的取值范围,例如,Rn中的n是0~7
举例:
数据转移指令
举例
分析一下上面的二个程序:
片内数据向片外传送
MOV R0, #38H ;把38H传给R0,即R0=#38H
MOV DPTR,#1818H ;把1818H传给DPTR,即DPTR=1818H
MOV A,@R0 ;把R0中的数据地址传给A,间接寻址,即A=RO=#38H
MOVX @DPTR,A ;把A的数据地址传给DPTR,并且MOVX表示传给了片外RAM,即DPTR=A=38H;相当于把一个片内的数据传给片外的DPTR
从ROM中查找数据
MOV DPTR ,#2010H ; 把2010H传给DPTR
MOV A,#30H;把30H传给A
MOVC A ,@A+DPTR ;把A+DPTR传给A,即A=#2010H+#30H,并且MOVC表示传给ROM
MOV 30H,A ;把A的数值地址传给地址30H;即30H=A=2010H+30H
算数运算类指令
MUL AB 乘法 ,高位存B,低位存A 例如17Hx68H=958H ,B=#9 ,A=#58H
DIA AB 除法 ,A=A/B(商——) B=余数;
实例:
解释下A<- #34H+#0E7H
化成二进制为
0011 0100
1110 0111
+
10001 1011
进位1 ,所以cy=1
最终结果为0001 1011
为1B
逻辑运算及移位类指令
实例:
咱把这三个例子分析一下
ANL A,#OFH ;把A与OFH与运算
ANL P1,#OFOH ;把ofoh与P1与运算
ORL P1,A; 把A与P1或运算
累加器A为特殊功能寄存器,字节地址是OEOH
累加器A为特殊功能寄存器,字节地址为0E0H,直接寻址时对0E0H操作就是对累加器A操作,0E0H是由硬件分配的是固定不变的。
列如:ADD A,0E0H;将累加器中的值和A相加后存入A。
直接寻址时候对A操作,对0E0H操作
A不指定就是XXXXxxxx;
控制转移类指令
这是他们的范围
实例:
前面 R7=#200
R6=#125
DJNZ R6 DEL2
r6-1直到0 ,执行125次
DJNZ R7,DEL1
R7-1直到0,执行200次
寻址方式
直接寻址
寄存器寻址
寄存器间接寻址
立即寻址
变址寻址
位寻址
相对寻址
总结:
下面是寻址方式汇总
直接寻址:.指令中含有direct形式的操作数的寻址方式
寄存器寻址:指令中包含通用寄存器形式操作数的寻址方式,Rn A,B,CY和DPTR
注意:B寄存器仅在乘法 除法中属于寄存器寻址,在其他指令属于直接寻址。
寄存器间接寻址:指伞中包含”@句址寄存器 形式操作数的是址方式称为寄存器间接寻址,其中间址寄存器只能由R0,R1或DPTR三个寄存器兼任
立即寻址:指令 包含#data或#data16形式操作数的寻址方式称为立即寻址。
变址导址:指令中包含”@At+基址寄在器”形式操作数的寻址方式称为变址寻址方式,其中基址寄存器只能由DPTR或PC兼任。
位寻址:指令中包含bit形式操作数的寻址方式称为位寻址方式,其中bit形式的位地址可以是片内RAM中的位地址,也可以是SFR中的位地址或位名称。
相对寻址:指令中包含rel形式操作数的寻址方式称为相对寻址方式,其中rel可以是片内RAM或ROM地址偏移量的形式,也可以是标号的形式。
伪指令
ORG 首地址
EQU 数值或汇编符号
DATA 内部RAM
BIT 位
DB 标号
END
第三章:课后习题
(14) 下列指令判断若累加器A的内容不为0就转LP的是______。
A.JB A,LP
B.JNZ A,LP
C.JZ LP
D.DJNZ A,#0,LP
(后缀都是JMP,联想jump,为转移指令
JMP:间接寻址转移
AJMP:绝对转移
SJMP:短跳转
LJMP:长跳转)
ACALL:调用子程序
LCALL:长调用
RET:子程序返回指令 RETI:中断返回指令
JZ rel:累加器A判断0转移指令 (若A=0,则PC=PC+rel,否则顺序执行)
JNZ rel:同上,不过是若A不等于0
重点:
CJNE :比较不等转移
DJNZ:减1不为0转移
答案(B)
—————————————————-
下列指令中,能访问外部数据存储器的正确指令为______。
A.MOV A,@DPTR
B.MOVX A,Ri
C.MOVC A,@A+DPTR
D.MOVX A,@Ri
这个题考察MOVC,MOVX,MOV
注意一点;
MOVX是片外RAM传递但是需要寄存器间接寻址
就是要有@
而MOVC是传递ROM的,要用变址寻址;
答案(D)
—————————————————
16进制的加减乘除——实在不会化为十进制计算
(12)设A=0AFH,(20H)=81H,指令ADDC A,20H执行后的结果是______。答案
A.A=81H
B.A=30H
C.A=0AFH
D.A=20
提个醒:如果是2进制计算,注意溢出没
所以CY=1;OV=1;
还有一个类似题目
已知A=0DBH,R4=73H,CY=1,指令SUBB A,R4执行后的结果是_____。答案
A.A=73H
B.A=0DBH
C.A=67H
D.A=68H
—————————————————-
(18)LJMP跳转空间最大可达______。
A.2KB
B.256B
C.128B
D.64KB
答案D最大的
—————————————————-
欲将P1口的高4位保留不变,低4位取反,可用指令是______。
A.ANL P1,#0F0H
B.ORL P1,#0FH
C.XRL P1,#0FH
D.MOV P1,#0FH
答案©
主要考察了逻辑运算指令
记忆:
ANL:与运算 *
ORL:或运算 +
XRL:异或运算 (相同为0,不同为1)
CPL:累加器取反 A=/A
SETB:置位 (SETB C—— C=1;位置1指令)
CLR:清零
RL:不进位循环左移 相当于x2
RLC:进位循环左移
RR:不进位循环右移 相当于/2
RRC:进位循环右移
—————————————————-
(15)设累加器A中为小于等于7FH的无符号数,B中数为2,下列指令中______的作用与其他几条不同。
A.ADD A,0E0H
B.MUL AB
C.RL A
D.RLC A
答案(D)
分析下这个题目:
这个题目是分析指令的作用,不用计算
A:A+A 累加器A为特殊功能寄存器,字节地址为0E0H所以相当于A+A
B:AxB B为2 ,Ax2
C:RL A A循环左移 相当于Ax2
D:
RL与RLC的区别
RL是左移指令,参加左移的是8个位
RLC是带进位位的左移,参加左移的共有9个位
设A=0100_0001,C=1;
如果执行RL , 则A=1000_0010,C=1(A所有位左移一位,最低位补零,C不参加移位操作,保持原值不变)
如果执行RLC, 则A=1000_0011,C=0 (A的最高位移到C,C原值移到A最低位)
D:RLC A:A进位循环左移:如果A=7FH;01111111
循环左移为11111111
不是Ax2
思考题:
(1)什么是汇编语言和汇编程序?汇编程序需要进行什么预处理才能被单片机执行? 提示
采用约定的英文助记符代替机器码进行编程的计算机语言称为汇编语言,由汇编语言规则编写的程序称为汇编程序。由于单片机不能直接执行汇编程序,必须通过汇编系统软件将其“翻译”成机器码并形成执行文件才能运行,这个“翻译”过程称为汇编程序的编译。
(2) 什么是指令?汇编语言指令一般格式中包含了哪些区段?各区段间的分隔符规则是什么? 提示
所谓指令就是指挥计算机运行的命令。一条汇编语言指令中最多包含4个区段,其中标号区段是当前指令行的符号地址,由英文字母开头的1~6个字符组成,不区分大小写,以英文冒号结尾;操作码区段是指令的操作行为,由操作码助记符表征,它们由2~5个英文字符组成,不区分大小写;操作数区段是指令的操作对象,操作数可以是0~3个,大于1个时,操作数之间要用英文逗号隔开;注释区段是对指令的解释性说明,可以用任何文字描述,以英文分号开始,无须结束符号。
(3) 汇编语言中,如何区分十六进制地址、立即数和标识符? 提示
标识符由英文字母开头的1~6个字符组成,例如EAH,C6A等;
16进制地址由字符0~9和A~F表示,若最高位为A~F时应加前缀“0”以区别于标识符,例如0EAH,5AH等;
立即数需加前缀“#”以区别于地址,例如#0EAH,#5AH等。
(4)51单片机指令系统共有多少条指令?按照基本功能可划分为哪几大类? 提示
MCS-51单片机指令系统共有111条指令,按照基本功能可划分为4大类,即数据传送与交换类、算术运算类、逻辑运算及移位类和控制转移类(或将分散于上述4类之中的位操作类指令汇总作为第5大类指令)。
5)51单片机的PSW程序状态字中没有判零标志,怎样判断某片内RAM单元的内容是否为零? 提示
利用条件转移指令中JZ对累加器A的判零间接实现
(6)子程序调用指令里,ACALL和LCALL的差异在哪里?选用时应考虑哪些因素? 提示
ACALL指令的操作数是addr11,子程序可放在距当前指令2KB的范围内,而LCALL指令的操作数是addr16,子程序可放在距当前指令64KB的范围内。选用前者(双字节指令)有利于缩短代码长度,选用后者(三字节指令)可提高程序布局的灵活性。
(7)根据第3章实例9,简述实现大于、等于和小于三种条件转移的汇编语言编程思路。 提示
先利用CJNE判断双方是否相等,再利用JC判断C标志的状态。
(8)根据第3章实例12,简述利用累加器A将并行数据转为串行数据的汇编语言编程思路。 提示
先利用RLC带进位循环指令将字节数据转为C中的位数据,再利用MOV位传送指令将C传送到I/O端口输出。
(10)51单片机有哪几种寻址方式?分别适用于什么地址空间? 提示
51单片机共有7种寻址方法,其中直接寻址范围是片内RAM低128字节单元和除A、B、C、DPTR外的其他SFR;寄存器寻址范围是通用寄存器Rn和SFR中的A、B(仅限于乘除法)、CY和DPTR;寄存器间接寻址范围是@R0、@R1和@DPTR;立即寻址范围是#data或#data16的立即数;变址寻址范围是@A+DPTR或@A+ PC;位寻址范围是片内RAM(含SFR)中的位地址单元;相对寻址范围是以当前地址与偏移量rel合成后的地址单元。。
(11) 汇总汇编指令分类中各大类指令的操作码助记符。 提示
各类指令操作码助记符如下: 数据传送与交换类指令(8种),即MOV,MOVX,MOVC,XCH,XCHD,SWAP,PUSH和POP; 算术运算类指令(8种),即ADD,ADDC,SUBB,INC,DEC,MUL,DIV和DA; 逻辑运算及移位类指令(10种),即ANL,ORL,XRL,SETB,CLR,CPL,RL,RR,RLC和RRC; 控制转移类指令(18种),即AJMP,SJMP,LJMP,JMP,ACALL,LCALL,RET,RETI,JZ,JNZ,CJNE,DJNZ,JC,JNC,JB,JNB,JBC和NOP。
12)伪指令与汇编指令有何区别?写出至少五种常用的伪指令名称。 提示
伪指令又称汇编系统控制译码指令或指示性指令,仅仅用于指示汇编系统软件要完成的操作,故一般不产生机器代码,汇编指令又称为硬指令,编译后将产生机器码。
ORG,EQU,END,DATA,BIT
13)简述汇编程序的主要设计步骤。 提示
1分析问题,确定算法或解题思路;2通过画流程图表示程序的执行过程或程序的结构;3分别编写各个模块程序,然后汇总成完整程序;4进行语法错误和逻辑错误的调试和修改,直至问题完全排除。
(14) 简述利用Proteus进行汇编程序的仿真开发过程。 提示
电路原理图设计→汇编程序设计→汇编程序编译→仿真运行调试
下面的都是重点章节
/
汇编语言的编程过程
指令系统汇总pdf
第四章:单片机的C51语言
延时函数和基本知识
首先这章开始我要将一个非常重要的函数:延时函数:
void delay(unsigned int time) // time代表需要延时的毫秒数
{
unsigned int j=0;
for(;time>0;time--)
for(j=0;j<125;j++);
}
void delay(unsigned int time) // time代表需要延时的毫秒数
{
unsigned int j=0;
for(;time>0;time–)
for(j=0;j<125;j++);
}
利用二个循环延时
软件消抖:delay(10);
可以用法stc工具直接出来代码,计时器比较精确
自己一个一个算太麻烦了,就是循环嵌套
还有个非常重要的字符数码管表示:0x表示16进制
C51的数据结构
C51与c语言的区别
C51是标准C语言的子集
首先介绍下C51的基本结构
下面通过一个LED灯闪烁的程序介绍C51程序的基本结构:
#include<reg51.h> //51单片机头文件
void delay(); //延时函数声明与C语言相同
sbit p1_0=p1^0; //定义一个变量p_0输出端口p1.0,p1^0表示端口p1.0
int main() //主函数
{
while(1) //无限循环,一直闪烁
{
p1_0=0; //p1.0=0,LED亮
delay();
p1_0=1; //p1.0=1,led灭
delay();
}
}
void delay()
{
unsigned char i; //定义字符型变量i
for(i=200;i>0;i--)
{
}; //循环延时 200ms
}
构建电路,运行效果如下:
C51单片机——闪烁灯
下面进行逐一介绍结构
#include<reg51.h> ,reg51.h是51单片机的头文件,包含了对8051单片机特殊功能寄存器名的集中说明
int main() 是主函数,()不能省略
sbit p1_0=p1^0; 是全局变量定义,它将p1.0端口定义为p1_0变量
unsigned char i ; 其实还是C语言的风格,它说明i是位于片内RAM且长度为8的无符号字符型变量
for(i=200;i>0;i–)
{}; //循环延时 200ms 实现了延时功能
综上所述,与C语言的基本结构类型相似
接着讲C51的数据结构
单片机中使用变量定义格式是:
{储存种类} 数据类型 {储存类型} 变量名;(如下图)
储存种类
存储器是指变量在程序执行过程中的作用范围
四种储存类型 :auto(自动)、extern(外部)、static(静态)、register(寄存器)
与C语言的基本相同,这里不多说,如果还有问题:看下这篇文章:link
数据类型
接着比较重要有三个新出现的变量类型bit 、sfr、sbit
分别举例:bit door=0;//定义一个叫door的位变量且初始值为0
sfr是为了访问片内RAM80H~FFH的特殊功能寄存器
sfr sfr_name=地址常数;
这里的sfr_name是一个特殊功能寄存器名,“=”后面必须是常数,其数值范围必须在80H~FFH内
对于16位的寄存器可以用sfr16
例如:sfr16 DPTR=0x82 //定义DPTR,其DPL=82H,DPH=83H
!这种定义只能适用于DPTR,不能用于T1和T0;
最常用的来了sbit
sbit是为了访问特殊功能寄存器的某些位;
三种方法如上图
位地址表达形式:绝对位地址、相对位地址
这里举列子:
//绝对位地址
//sbit bit_name=位地址常数
>1. sbit CY=0xD7; //将位的绝对地址赋给变量,即0xD7地址赋给变量CY
//相对位地址
//sbit bit_name=sfr字节地址^位位置
>2.sfr PSW=0xD0
sbit CY=PSW^7; //定义CY位为PSW.7,位地址为0xD0
//相对位位置
//sbit bit_name=sfr_name^位位置
>3.sbit CY=0xD0^7;// 将位的相对地址赋给变量
定义CY位地址为0xD0
注意sbit与bit的区别:
bit型变量的位地址是由编译器为其随机分配的,
而且范围实在片内RAM的位寻址区(20H~2FH)
而sbit变量的位地址是由用户指定的,而且范围是sfr区域
!sfr型变量和sbit型变量都是全局变量,需要放在在最前面
因为REG.h头文件中已经包含有sfr/sfr16和sbit的变量,所以无需定义直接用
存储空间
如果在定义变量时候缺少存储类型说明符,C51编译器会自动认定默认的存储类型
变量名
数据结构定义举例
C51的指针
C51一般指针的格式是:
数据类型 【存储类型1】*【存储类型2】 指针变量名
下面举几个例子:
char xdata a =‘A’;
char *ptr=&a;
在这个例子中,ptr是一个指向char型变量的指针变量,它本身位于Small编译模式默认的data中,但是它的值是xdata中的char a变量的地址
char xdata a=‘A’;
char *ptr=&a;
char idata b=‘B’;
ptr=&b;
前两句与上面相同,但是ptr最终又为idata 中的char b 变量的地址
以char*ptr形式定义的指针变量,既可指向位于xdata存储区的char型变量a的地址,也可指向位于idata存储区的char型变量b的地址。
char xdatd a=‘A’;
char xdata *idata ptr=&a;
此时变量ptr是a的地址,ptr是位于xdata区域中的char型a变量的地址
char xdatd a=‘A’;
char xdata * ptr=&a;
ptr是位于xdata区域中a变量的地址
关于混合编程
在C51中调用汇编程序
举例:
1)程序的寻址问题
2)参数传递问题
3)返回值传递问题
编译运行
C51中嵌入汇编
嵌入式时候keil软件需要进行一定的配置
单片机51keil编程流程
!C51的I/O端口
- 低电平驱动:R小,电流大,低电平驱动,I/O端口输出”0″电平可使点亮
- 高电平驱动:R大,电流小,高电平驱动,I/O端口输出“1”电平可使点亮
常用低电平驱动
发光二极管限流电阻通常为100~200
实例1:独立按键识别
这个问题的参考代码如下:
#include<reg51.h>
void main(){
char key=0; //定义按键变量
while(1){
key =P0&0x0f; //按键P0的高4位清零
if(key!=0x0f)P2=key; //有按键动作,P0状态值送P2端口
}
}
解析:先看这个电路,P2端口这里初始是VCC,二极管是低电阻,端口处是高电压(分的电压多),这是P2端口的初始
P1这里,按下按键前不接地,电压都是一样的,1.25V大概,按下按键后,接地,必然会分压,其中低4位中某一位变成低0。这里就是看P0后面的低4位变化否来判断是否按下
使key等于
key =P0&0x0f; //按键P0的高4位清零
这里屏蔽了高四位,这样就看后四位够了,课本上说为了使输入的端口P0.4 ~ P0.7的端口强制为0,而P0.0 ~ P0.3的输入不受影响。对读取的端口进行与操作,屏蔽P0的高四位。
然后
if(key!=0x0f)P2=key;
然后只要按键按下了,就把这个值传输到P2端口
按键按下,低4位变化,这样key值不等于0,有一位电压变低
这样传过去,对应哪个端口,那个端口电压变化,这里是低电平驱动,发光(如下图)
视频:
单片机C51-独立按键识别
参考文章:c51
案例2:键控流水灯
- run=1:开始(自下而上)
- run=0:结束
- dir=0:自下而上
- dir=1:自上而下
switch(P0 & 0x0f){
case 0x0e:run=1;break,
case 0x0d:run=0,dir=0;break,
case 0x0b: dir=1,break,
case 0x07: dir=0;break,
}
这里解释下:
这里因为使用的是发光二极管那是低电平驱动,所以“0”发光
参考代码:
#include "reg51.h"
unsigned char led[]={
0xfe,0xfd,0xfb,0xf7};//LED灯的亮灯数据
void delay(unsigned char time){
//延时函数
unsigned int j=15000;
for(;time>0;time--)
for(;j>0;j--);
}
void main(){
bit dir=0,run=0; //标志位定义及初始化
char i;
while(1){
switch (P0 & 0x0f){
//读取键值
case 0x0e:run=1;break; //K1动作,设run=1
case 0x0d:run=0,dir=0;break;//K2动作,设run=dir=0
case 0x0b:dir=1;break; //K3动作,设dir=1
case 0x07:dir=0;break; //K4动作,设dir=0
}
if (run) //若run=dir=1, 自上而下流动
if(dir)
for(i=0;i<=3;i++){
P2=led[i];
delay(200);
}
else //若run=1,dir=0, 自下而上流动
for(i=3;i>=0;i--){
P2=led[i];
delay(200);
}
else P2=0xff; //若run=0,灯全灭
}
}
视频:
单片机C51-键控流水灯
实例3:混合编程实现实例2的delay
c51部分基本跟上面相同
在其中定义delay函数但是不实现
void delay(unsigned char time);
在delay.asm中实现delay函数
;延时处理函数(汇编语言)
PUBLIC _DELAY
DE SEGMENT CODE
RSEG DE
_DELAY:MOV R0,#225
DEL2: DJNZ R0,DEL2
DJNZ R7,_DELAY
RET
END
其实也可以直接c51中嵌入汇编程序
例如这里
void delay(unsigned char time)
{
#pragma asm
MOV R0,#225
DJNZ R0,DEL2
DJNZ R7,_DELAY
#pragma endasm
}
LED数码管原理与编程
LED的类型分为上图的四种:字段式、点式、点阵式、光柱式
最常用的是七段式LED数码管: 由七个条形发光二极管(a~g)和一个小圆点发光二极管。
这种显示器分 共阴极和共阳极二种
- 共阳极:所有发光二极管的所有阳极接在一起,低电平有效
- 共阴极:所有发光二极管的所有阴极接在一起,高电平有效
- 其中com是公共端
LED的显示字符于数码管的类型有关,也是不同类型的LED段码不同
这个图是共阴极的,共阳极与共阴极的段选码互为补码,所以上面的方法也是相反:
详情参考:LED编码表与段码表
参考这个文档有完整的段码图;
实例4:LED数码管显示
就是加个数组然后好显示;
参考代码:
//实例4 LED数码管显示
#include <reg51.h> //包括一个51标准内核的头文件
char led_mod[]={
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//LED显示字模0~9
void delay(unsigned int time){
unsigned int j = 0;
for(;time>0;time--)
for(j=0;j<125;j++);
}
void main(void) {
char i = 0;
while(1){
for(i=0;i<=9;i++) {
P0=led_mod[i];
delay(500);
}
}
}
项目源程序:
视频:
实例5:计数显示器
需要解决上面二个问题:
参考代码:
#include <reg51.H>
sbit P3_7=P3^7; //定义计数器端口
unsigned char count =0; //定义计数器
unsigned char code table[]=
{
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void main(void) {
P0=P2=table[0]; //显示初值00
while(1) {
if(P3_7==0){
//检测按键是否压下
count++; //计数器增1
if(count==100) count=0; //判断循环是否超限
P0=table[count/10]; //十位输出显示
P2=table[count%10]; //个位输出显示
while(P3_7==0); //等待按键抬起,防止连续计数
}
}
}
显然用的是第一种方法,更新后处理连击
while(P3_7==0); //等待按键抬起,防止连续计数
只有P3_7 ==1后抬起才能继续下一步
程序运行视频如下:
C51单片机——计数显示器
!C51的I/O端口进阶
数码管动态显示原理与编程
解释:
动态显示的特点是将所有数码管的段选线并联在一起,由位选线控制是哪一位数码管有效。选亮数码管采用动态扫描显示。所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。动态显示的亮度比静态显示要差一些,所以在选择限流电阻时应略小于静态显示电路中的。
实例6:数码管动态显示
看右边的流程图,先将位码0x02和0x01先后送入P3口使能数码管
然后赋值P2端口,0x38是L,共阴极。0x5b是2。
你看哪个流程图
先给2晶体管,赋值为led_mod[0] 是L
再给1晶体管,赋值为led_mod[1]是2
参考代码:
#include <REG51.H>
char led_mod[] = {
0x38,0x5B}; //LED字模“L2”
void delay(unsigned int time);
void main()
{
char led_point = 0; //定义一个变量为0
while (1)
{
P3 = 2 - led_point; //输出LED位码
//位码的意思就是哪个数码管,
//比如数码管显示12的话就先选择第一个数码管然后传送段码1再关闭第一个数码管,
//接下来打开第二个数码管传送段码2后关闭第二个数码管。动态显示是两个数码管轮流着显示.
//但由于这两个数码管变换的速度快于我们的视觉能辨别的最快速度,所以看起来是两个都是一起显示的。
//说白了就是二个数码管轮流显示,题中2个
P2 = led_mod[led_point]; //输出字模
led_point = 1 - led_point; //刷新LED位码
delay(30);
}
}
void delay(unsigned int time)
{
unsigned int j = 0;
for(;time>0;time--)
for(j=0;j<125;j++);
}
电路视频如下:
C51单片机——数码管动态显示
行列式键盘原理与编程
每个I/O口连接一个1按键
所以提出了行列式键盘
原理:
要先扫描
这里解释下:行线P20~P23是输出,列线P24 ~P27是输入
先将行线全部设置为1,此时读入列线数据,因为没有按键按下时候列线都是1
这时候如果有按键按下,列线有低电平0
这里轮流清0
这时候扫描出来输出码
再把它写入P2
这里解释下:行线电压原本全为1,按键按下后
行线端口电平反转
读取P2,这时候如果发现其低4位为f,没有按键按下
如果有一位变化,就说明有按键按下
这里解释下:
这里要找是哪个按键按下,前面说了键值数组是按键闭合时从引脚读出来的数值
就是用这个查询是哪个按键按下
实例7:行列式键盘(共阴极数码管)
算是跟前面的数码管也结合在一起了
参考代码:
#include <reg51.h>
char led_mod[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //led显示码0~f
0x7f,0x6f,0x77,0x7c,0x58,0x5e,0x79,0x71};
char key_buf[] = {
0xee, 0xde, 0xbe, 0x7e,0xed, 0xdd, 0xbd, 0x7d,//键值
0xeb, 0xdb, 0xbb, 0x7b,0xe7, 0xd7, 0xb7, 0x77};
char getKey()
{
char key_scan[] = {
0xef, 0xdf, 0xbf, 0x7f}; //键扫描码
char i = 0, j = 0;
for (i = 0; i < 4 ; i++) {
P2 = key_scan[i]; //P2送出键扫描码
if ((P2 & 0x0f) != 0x0f) {
//判断有无键闭合
for (j = 0 ; j < 16 ;j++)
{
if (key_buf[j]==P2) return j; //查找闭合键键号
}
}
}
return -1; //无键闭合
}
void main()
{
char key = 0;
P0 = 0x00; //开机黑屏
while(1)
{
key = getKey(); //获得闭合键号
if (key != -1) P0 = led_mod[key]; //显示闭合键号
}
}
流程图帮助理解过程:
简化过的不要getkey的
代码:
#include <reg51.h>
char led_mod[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //led显示码0~f
0x7f,0x6f,0x77,0x7c,0x58,0x5e,0x79,0x71};
char key_buf[] = {
0xee, 0xde, 0xbe, 0x7e,0xed, 0xdd, 0xbd, 0x7d,//键值
0xeb, 0xdb, 0xbb, 0x7b,0xe7, 0xd7, 0xb7, 0x77};
char key_scan[]={
0xef,0xdf,0xbf,0x7f};//键扫描码
int main()
{
char i = 0,j=0;
P0 = 0x00; //开机黑屏
while(1)
{
for(i=0;i<4;i++)
{
P3=key_scan[i];
if((P3&0x0f)!=0x0f) //判断是否按键闭合
{
for(j=0;j<16;j++)
{
if(P3==key_buf[j])
{
P2=led_mod[j]; //查找闭合按键
break;
}}}}}}
实验视频如下:
单片机C51-行列式键盘
按键消抖
就是检测有按键按下时候,先延时10ms,然后再重新检测是否真的是按键按下而不是弹簧变形的电压波动
当然,检测到按键释放时候,也要做同样的处理
本章小结
第四章:课后习题
(7)将aa定义为片外RAM区的无符号字符型变量的正确写法是______。
A.unsigned char data aa;
B.signed char xdata aa;
C.extern signed char data aa;
D.unsigned char xdata aa;
片外RAM只有xdata ,data是片内RAM低128B
考察存储类型
片外RAM :xdata (Large编程模式下)
片内RAM:data (small编程模式下)
idata :在特殊功能寄存器区域(Compact模式下)
答案(D)
(13) 已知P0口第0位的位地址是0x90,将其定义为位变量P1_0的正确命令是_____。
A.bit P1_0 = 0x90;
B.sbit P1_0 = 0x90;
C.sfr P1_0 = 0x90;
D.sfr16 P1_0 = 0x90;
sbit和bit的区别我介绍过;
因为bit的定义的变量的地址不能指定,而sbit可以定义位地址变量
所以sbit选择
一般sbit比较万能,选择sbit可能性大。
答案(B)
(16)下列关于LED数码管动态显示的描述中______是正确的。
A.一个并行口只接一个数码管,显示数据送入并行口后就不再需要CPU干预
B.动态显示只能使用共阴极型数码管,不能使用共阳极型数码管
C.一个并行口可并列接n个数码管,显示数据送入并行口后还需要CPU控制相应数码管导通
D.动态显示具有占用CPU机时少,发光亮度稳定的特点
考察动态显示ming
铭记动态显示的定义:所有数码管的段码线对应并联接在一个8位并行口上,而每数码管的公共端分别由一位I/O 线控制,效果稳定;
但是记住它的缺点,一直需要CPU刷新,占用机时多
答案©
(20)在xdata存储区里定义一个指向char类型变量的指针变量px的下列语句中,______是正确的(默认为SMALL编译模式)。
A.char * xdata px;
B.char xdata * px;
C.char xdata * data px;
D.char * px xdata;
这个考察了指针
char xdatd a=‘A’;
char xdata *idata ptr=&a;
在这里,*后面的iata才是ptr的变量地址区域,
前面的xdata代表的是 char型的变量a的存储区域
如这题:char
要xdata是变量的区域
就是char *xdta px;
没有其他变量赋值,所以可以不用写
答案(A)
思考题:
(1)C51与汇编语言相比有哪些优势?怎样实现两者的互补? 提示
C51语言具有结构化语言特点和机器级控制能力,代码紧凑,效率可与汇编语言媲美。由于接近真实语言,程序的可读性强,易于调试维护,编程工作量小,产品开发周期短。C51语言与汇编指令无关,易于掌握。但对于有较高程序代码执行速度要求的场合,如I/O 接口地址处理、中断向量地址安排,汇编语言仍有一定优势。可以采用在C51中调用汇编程序和在C51中嵌入汇编代码的方法实现两种语言优势互补。
(2) 在C51中为何要尽量采用无符号的字节变量或位变量? 提示
这两种变量占用内存少,代码长度短,执行效率高。有符号的字节变量虽然也只占用1字节,但CPU需要进行额外的操作来测试代码的符号位,这会降低代码效率。使用浮点型的变量时,编译系统还将调用相应的库函数来保证运算精度,这会明显增加运算时间和代码长度。
(3) 为了加快程序的运行速度,C51中频繁操作的变量应定义在哪个存储区? 提示
由于片内存储器的数据传送多为单周期指令,而片外存储器多为双周期指令,CPU处理前者数据的速度要快于后者,因此频繁操作的变量应尽量定义在片内存储器中,选择如data,bdata或idata等存储类型的变量。
重点
(4)C51的变量定义包含哪些要素?其中哪些是不能省略的? 提示
变量定义中包含着存储种类、数据类型、存储类型和变量名4项要素,其中数据类型和变量名在变量定义时是不能省略的,存储种类和存储类型在变量定义时可以采用相应缺省值。
5)C51数据类型中的关键词sbit和bit都可用于位变量的声明,但二者有何不同之处? 提示
bit型变量的位地址是由编译器为其随机分配的(定义时不能由用户指定),位地址是在片内RAM的可位寻址区(bdata区)中;而sbit型变量的位地址则是由用户指定的,位地址是在可位寻址的SFR单元内(但利用bdata限定变量存储类型后,可将位地址范围扩大到bdata区)。
6)C51中调用汇编语言程序需要解决的3个基本问题是什么?具体规则有哪些? 提示
①程序的寻址问题——通过在汇编文件中定义与C51同名的“函数”来实现的;②参数传递问题——通过使用指定的寄存器来实现的;③返回值传递问题——通过使用指定的寄存器来实现的。
7)C51中嵌入汇编代码的具体做法是什么?有什么需要关注的地方? 提示
①将嵌有汇编代码的C51源文件加入当前工程文件中;②根据采用的编译模式,将相应的库文件加入当前工程文件中。此后便可采用一般编译方法进行程序编译。需要注意的是,汇编代码必须放在两条预处理命令#pragma asm和#pragma endasm之间,预处理命令必须用小写字母,汇编代码则大小写字母不限。
8)集成开发环境µVision3的软件界面由哪些组成部分?简述创建一个C51程序的基本方法。 提示
软件界面包括4大组成部分:菜单工具栏(标准的Windows风格,共有11个下拉菜单)、工程管理窗口(用于管理工程文件目录,由5个子窗口组成)、文件窗口(用于显示打开的程序文件,通过文件标签进行切换)和输出窗口(用于输出编译过程中的信息,由3个子窗口组成)。 创建C51程序基本方法:1、打开工程文件窗口,保存为*.uv2文件;2、选择一款51单片机,如80C51BH;3、打开空白的文本框,输入C51源程序,保存为*.c文件;4、将*.c文件添加到工程文件中;5、设置或核查工程配置选项;6、编译当前工程文件,排除语法错误后保存为*.hex文件;7、仿真调试hex文件,排除逻辑错误后结束创建工作。
(11) 独立式按键的组成原理与编程思路是什么? 提示
组成原理是,按键的一端接地,另一端与一个I/O口线连接。若按键接在P0口需外接上拉电阻,而接在P1~P3口无需要上拉电阻。编程思路是,当按键或开关闭合时,对应口线的电平就会发生反转,CPU通过读端口电平即可识别是哪个按键或开关发生了闭合。
(12)七段LED数码管的工作原理是什么?简述数码管静态显示与动态显示的特点及实现方法。 提示
工作原理是,七段LED数码管由7个条形LED组成字符笔段,1个圆形LED作为小数点。其中所有LED阳极连接在一起作为公共端引脚,所有LED阴极单独接出作为段位引脚(共阳极数码管)。反之,共阴极数码管则相反。利用发光二极管正向连接时点亮,反向连接时熄灭的特性,改变笔段的组合电平就能形成不同的字形。 静态显示接口采用一个并行I/O口接一个七段数码管的段位引脚,公共端接地或Vcc。这种接法的优点是电路简单,数码管显示亮度稳定。但该方法占用I/O口资源较多。动态显示接口是将n个七段数码管的相同段码引脚并联起来接在一位I/O口线上,每个数码管的位码引脚则分别由一位I/O口线控制。动态显示接口的特点是占用I/O口资源较少,但占用CPU机时较多。 静态显示采用CPU单独控制显示的做法,即将被显示字符的段码值送入相应I/O口的锁存器中就能使数码管恒定显示,每位显示字符的段码值只需CPU输出一次即可。动态显示采用CUP分时控制显示的做法,即CPU需要轮流输出待显示字符串中某位字符的段码和位码,每一时刻只有一只数码管为显示状态其他数码管都为黑屏。当段码值和位码值的循环刷新速度很快时,由于视觉暂留特性,人眼不会感到显示值在闪烁,而是看到稳定显示的字符串。
13)行列式键盘的组成原理与编程思路是什么? 提示
行列式键盘组成原理是:将I/O口分为行线和列线,按键设置在跨接行线和列线的交点上,列线通过上拉电阻接正电源。采用软件扫描查询法的编程原理是,根据按键压下前后,所在行线的端口电平是否出现翻转,判断有无按键闭合动作。
14)独立式键盘与行列式键盘的特点和不足是什么? 提示
独立式键盘的特点是电路简单,软件处理工作量小,但占用的I/O口线较多。
行列式键盘的特点是占用I/O口线较少但软件处理工作量较大。
第五章:中断系统
理解中断
中断就是突发事件发生时候中止当前工作,处理后恢复到当前工作
中断函数与一般函数的区别
中断函数的不同之处:1.程序事先安排好的
2.主函数与中断函数平行关系
3.中断函数需要软件,硬件配合
中断函数实现功能
实例1:单片机开关状态检测
有二种方法:
查询法
先讲查询法:
就是先把那二个端口定义了
这里看D1灯那,正进负出,它的负极接地,那它正极要接高电压亮
这里有个附加条件,按键按下后D1亮灭,所以
这里定义刚开始P1_0=0,是灭的
再判断按键
while(1)
{
if(P3_2==0) 事件;
}
这里为啥是0?
因为电路图:
你看原来按键没按下,端口处还是高电压水平,但是按下后接地,低电压水平,所以应该是0判断按下
按下后D1灯端口处电压反转,
P1_0=!P1_0;
这样就亮了
然后再按下按键就会又反转了,大致这样循环着
中断法
先定义sbit p1_0=P1^0端口
这里就要写中断处理函数了,就是灯端口电平反转
再来主函数:
main(){
IT0=1;
EX0=1;
EA=1;
while(1);
}
这里进行中断初始化
IT0=1;
EX0=1;
EA=1;
这几句留到后面解释下,这里不好大篇幅去讲
补一下:
IT0=1; //IN0=1,默认脉冲,INT0非 结果送到IE0
//程序电路中P3_2端口处原来电压为1(高),IE0=0无中断
//按键按下后,电压为0(低),IE0=1中断标志位为1,中断发生
//相当于INT0中断初始化
EX0=1; //EX0=1,默认中断总允许打开
EA=1; //EA=1,默认INT0的中断会得到CPU的响应
while(1);
看后面会懂的
项目源程序:
视频:
单片机c51-开关状态检测中断
中断控制系统
中断系统的结构
这里介绍中断的几种元素
1 中断源
中断源是要处理的突发事件。比如上面的按键按下,P3_2电平反转
原来不同芯片的中断源不同,中断源越多能处理的事件越多
表中INT0和INT1都是以单片机外部特定引脚上的电平或脉冲状态为中断事件的,统称为外部中断;
其余3个中断源都是以单片机内部某个标志位的电平状态为中断事件的,统称为内部中断;
2 中断向量
中断事件出现后,系统要调用相对应的中断函数进行中断处理。
汇编语言中规定了5个特殊的ROM单元用于引导中断程序的调用,这些单元的地址叫做中断向量。
3 中断号
汇编程序时候,需要设置一个指向中断程序入口地址的跳转语句,以便引导中断程序的执行
对于C51语言,调用中断函数时候不用中断变量,而是要用到与中断源相对应的中断号。
这个在中断服务函数声明中要声明
中断请求标志
定义
当发生中断后,某些特殊功能寄存器的特殊标志位将被硬件方式自动修改
这些特殊标志位称为中断请求标志。
CPU通过定期查看中断请求标志就知道是否有无中断请求
80C51单片机 0~3 中断源中断请求标志位有一个,4号中断源对应有2个中断请求标志
中断请求标志清0比较复杂,后面中断撤销中讲
这里先介绍下中断请求标志的工作原理:
中断请求标志的置1原理
外部中断源INT0/INT1
INT0信号通过P3.2引脚输入,INT1通过P3.3引脚输入
输入的信号可有电平和脉冲二种
INT0/1中断请求原理如图
解释一下:
- 若IT0=0,则INT0非信号经过非门到达IE0,这时候,如果若INT0非是高电平,则IE0清0
- 若IT0=1,则INT0非信号经过施密特触发器到达IE0,这时候,如果若INT0非正跳变脉冲,则IE0清0;若为负跳变脉冲,则IE0=1
可见先通过ITx的控制,再通过INTx的信号判断清0还是置1
内部中断源(T0和T1)
51单片机内部有二个完全相同的定时/计数器T0和定时/计数器T1。
工作原理如下:
在T0或T1中装入初值并闭合逻辑开关,T0或T1会自动累加注入的脉冲信号。
当T0被充满溢出后,可向位寄存器TF0“进位”,置1
TF0在系统响应中断请求后才会被硬件清0,否则一直保持溢出时的高电平状态
内部中断源(TX和RX)
51单片机具有内部发送控制器和接受控制器,可以对串行数据进行收发控制
与前面4种中断源不同的是,系统响应中断后,RI和TI都不会硬件清0,而是需要由软件方式清0
中断控制
用户对单片机中断系统的操作是通过控制寄存器实现的
80C51设置了4个控制寄存器:
- TCON寄存器
- SCON寄存器
- IE寄存器
- IP寄存器
这四个寄存器都是特殊功能寄存器
他们的组成的中断系统如下图:
中断信号的传送分别沿着5条水平路径由左向右进行的
下面分别介绍
1 TCON寄存器
共8个,6位与中断有关,二位与定时/计数器有关
由图5.9可知,与中断有关的位寄存器分别是:
- INTO的中断请求标志位 IEO(TCON^1)
- TO的中断请求标志位TFO(TCON^5)
- INTI的中断请求标志位IE1(TCON^3)
- T1 的中断请求标志位TF1(TCON^7)
- INTO的中断触发方式选择位 ITO(TCON^O)
- INT1的中断触发方式选择位IT1(TCON^2)
本章实例1:IT0=1; EX0=1; EA=1; while(1);
的ITO=1语句,就是令INTO为脉冲触发方式的中断初始化设置。
ITO=1,脉冲模式,INTO非 到 IEO
相当于初始化
2 SCON寄存器
SCON寄存器二位与中断有关:
- 接收中断请求标志位RI (SCON^0)
- 发送中断请求标志位TI(SCON^1)
它们二个特殊, 中断响应后,软件清0
通过SCON之后或电路合成一个信息,统一中断管理
3 IE寄存器
中断请求标志置1后,能否得到CPU中断响应取决于CPU是否允许中断。
允许中断称为中断开放,不允许中断称为中断屏蔽
从图中可以看出,中断请求标志要受两级“开关”的串联控制,即5个源允许和1个总允许
。
- 当(总允许位寄存器)EA=0时,所有的中断请求都被屏蔽;
- 当EA=1时,CPU开放总中断。
每个源允许位寄存器对中断请求的控制作用都是单项的,可以根据需要分别使其处于开放(=1)或屏蔽(=0)状态。
单片机复位后,IE 的初值为0,因此默认为是整体中断屏蔽。
若要在程序中使用中断,必须通过软件方式进行中断初始化。
实例1中
IT0=1; EX0=1; EA=1; while(1);
EX0=1;EA=1;就是令EA和EX0置1,其余位寄存器保持0的中断初始化状态
这样EA=1; 总中断允许
EX0=1; INT0的中断允许
这样就知道前面的程序的意义了
IT0=1; //IN0=1,默认脉冲,INT0非 结果送到IE0
//程序电路中P3_2端口处原来电压为1(高),IE0=0无中断
//按键按下后,电压为0(低),IE0=1中断标志位为1,中断发生
//相当于INT0中断初始化
EX0=1; //EX0=1,默认中断总允许打开
EA=1; //EA=1,默认INT0的中断会得到CPU的响应
while(1);
IN0=1,默认脉冲,INT0非 结果送到IE0
程序电路中P3_2端口处原来电压为1(高),IE0=0无中断
按键按下后,电压为0(低),IE0=1中断标志位为1,中断发生
相当于INT0中断初始化
–
EX0=1; //EX0=1,默认中断总允许打开
EA=1; //EA=1,默认INT0的中断会得到CPU的响应
4 IP寄存器
如上图,单片机的每个中断源都能被设置为高优先级中断(=1) 或 低优先级中断(=0)。
其中,运行中的低优先级中断函数可以被高优先级打断(实现中断嵌套)
但是,运行中的高优先级不能被低优先级中断请求打断
此外,同级的中断请求不能打断正在运行的同级中断函数
同时提出请求时候按自然优先级响应
为了实现上述中断系统优先级功能,51单片机的中断系统有两个不可寻址的优先级状态触发器。
- 其中一个指出CPU是否正在执行高优先级中断服务程序,如果该触发器置1时,所有后来的中断均被阻止;
- 另一个指出CPU是否正在执行低优先级中断服务程序,该触发器置1时所有同级的中断都被阻止,但不阻止高优先级的中断。
根据设置IP寄存器,每个中断请求都可以被划分到高级中断请求或低级中断请求的队列。每个队列又能根据自然优先级排队。
如此一来,用户可以根据需要设置中断源的重要程序响应
51单片机复位时候、默认时候都是IP=0,默认全为低级中断。上面的按键状态实例就是这样的(没定义高级中断)
实例4:中断嵌套演示
根据下原理图,编程验证二级外部中断嵌套效果。其中K0定为低优先级中断源,K1为高优先级中断源。此外,利用发光二极管D1验证外部中断请求标志IE0在脉冲触发中断时候的硬件置位与撤销过程
- 先实现LED0:是用这3个晶体管实现1~9的循环计数,其中主函数采用无限计数显示,K0和K1的中断函数采用单圈计数显示(一次1 ~ 9)
- K0接INT0引脚,K1接INT1引脚,K1高级中断,优先级要设置高,即
PX1=1 ,PX0=0; - 高级中断运行时,若有低级中断请求,则D1点亮;高级中断结束后,低级中断才能运行。
一步一步写
先定义好字模和D1和延时函数
#include "reg51.h"
char led_mod[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //led字模
0x7f,0x6f}; //显示字模
sbit D1=P3^0; //原理图D1接P3_0
void delay(unsigned int time){
//延时
unsigned char j=255;
for(;time>0;time--)
for(;j>0;j--);
}
先写主函数:
void main(){
unsigned char i;
TCON = 0x05; //脉冲触发方式
0x05是0000 0101 ——对应TCON寄存器的位
这样IT1和IT0为1,脉冲触发
上面说的
K0接INT0引脚,K1接INT1引脚,K1高级中断,优先级要设置高,即
PX1=1 ,PX0=0;
PX0=0;PX1=1; //INT1优先
然后继续
D1=1;P1=P2=0x40; //输出初值
D1=1 刚开始时候这样电平,D1灯是灭的,等于初始化
P1=P2=0x40;
这里用的 晶体管竟然还是共阴极的动态数码管
由他们各自连接的端口控制
0x40=0100 0000
这样就是P0和P2等于0 100 0000
显示是-
对应LED1 2
LED0开始端口P0为高电压
继续写:
IE=0x85; //开中断
这里是IE寄存器 为1000 0101
EA=1;EX1=1;EX0=1;
总中断允许;INT1中断允许;INT0允许
继续写:
while(1){
for(i=0;i<=9;i++){
//字符0-9无限循环
P0=led_mod[i];
delay(35000);
}
}
}
主函数中的循环, P0=led_mod[i]; led_mode是共阴极数码管0~9
所以LED0从0到9无限循环
主函数代码:
void main(){
unsigned char i;
TCON = 0x05; //脉冲触发方式
PX0=0;PX1=1; //INT1优先
D1=1;P1=P2=0x40; //输出初值
IE=0x85; //开中断
while(1){
for(i=0;i<=9;i++){
//字符0-9无限循环
P0=led_mod[i];
delay(35000);
}
}
}
下面写中断函数
key0() interrupt 0 {
//K0中断函数
unsigned char i;
D1=!IE0; //IE0状态输出
for(i=0;i<=9;i++){
//字符0-9循环1圈
P2=led_mod[i];
delay(35000);
}P2=0x40; //结束符“-”
}
key0() interrupt 0 { //K0中断函数
定义中断服务函数
这里的0是中断号
这样才能对应是哪个中断
unsigned char i;
D1=!IE0; //IE0状态输出
for(i=0;i<=9;i++){
//字符0-9循环1圈
P2=led_mod[i];
delay(35000);
}P2=0x40; //结束符“-”
D1=!IE0; D1初始值为1,D1对应着INT0的中断请求标志IE0的非
这里为啥取非?
因为D1对应的灯D1端口为0时候亮
所以IE0=1中断开始,D1亮可以作为一个判断v
然后单圈灯
for(i=0;i<=9;i++){
//字符0-9循环1圈
P2=led_mod[i];
delay(35000);
}P2=0x40; //结束符“-”
就亮了循环一圈
!!!
总体看:
按下K0后
INT0端口变为低电压,传给INT0非为低电压
这里要看IE0是哪种模式(脉冲还是电平)
TCON = 0x05; //脉冲触发方式
所以为1变0为负跳变脉冲所以为1变0为负跳变脉冲
IE0置1,中断开始
中断服务函数
流程图:
如果错误请指出,大致总结下
K1也是这样,但是K1是优先级为高在这个例子中
因为项目总代码:
#include "reg51.h"
char led_mod[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //led字模
0x7f,0x6f}; //显示字模
sbit D1=P3^0;
void delay(unsigned int time){
//延时
unsigned char j=255;
for(;time>0;time--)
for(;j>0;j--);
}
key0() interrupt 0 {
//K0中断函数
unsigned char i;
D1=!IE0; //IE0状态输出
for(i=0;i<=9;i++){
//字符0-9循环1圈
P2=led_mod[i];
delay(35000);
}P2=0x40; //结束符“-”
}
key1() interrupt 2 {
//K1中断函数
unsigned char i;
for(i=0;i<=9;i++){
//字符0-9循环1圈
D1=!IE0; //IE0状态输出
P1=led_mod[i];
delay(35000);
}P1=0x40; //结束符“-”
}
void main(){
unsigned char i;
TCON = 0x05; //脉冲触发方式
PX0=0;PX1=1; //INT1优先
D1=1;P1=P2=0x40; //输出初值
IE=0x85; //开中断
while(1){
for(i=0;i<=9;i++){
//字符0-9无限循环
P0=led_mod[i];
delay(35000);
}
}
}
现象:
LED0无限循环
按下K0,INT0中断开始,进入中断函数key0,len1循环一圈
按下K1,INT1中断开始,进入中断函数key1,len2循环一圈
因为K1的定义的中断优先级高,所以如果K0中断运行的时候
点击K1,K1中断优先,等K1结束才能到K0中断
最终,中断时候中断函数下面的LED0的循环亮暂时没到中止
观察D1的信息
D1开始为1.灭的
中断函数中定义D1=!IE0
IE0是INT0的中断标志,当INT0中断运行时候
IE0=1
所以D1=0; 亮
在K1中断中也有这个
但是它是在for内部
D1一直在变
视频:
这里还是有些地方不太明白,先看着大致理解以后理解深了在看看
中断处理过程
中断处理包括中断请求、中断响应、中断服务等环节。
中断响应
首先,中断响应需要满足的条件:
- 有中断源发出中断请求
- EA=1;即CPU开中断
- 申请中断的中断源的中断允许位为1,即没有被屏蔽
CPU响应后,由硬件自动执行下列操作:
1.中断优先级查询:对后来的同级和低级中断请求不予响应
2.保护断点,即把程序计数器PC的内容压入堆栈
3.清除可清除的中断请求标志位
4.调用中断函数开始运行
5.返回断点继续主函数
除了中断函数运行是软件外,其他中断处理过程都是硬件自动完成的
响应时间
中断服务函数
中断编程及其应用
中断的编程和应用举例
实例2 将实例7行列式键盘实例改用中断方式实现
实例3是行列式键盘
当各列电平都为0,无论按下哪个按键,与门的输出端都可以形成INT0非的中断请求信号
这样把按键的扫描查询工作放在中断函数中,从而就能达到快速响应按键。
解释一下:U3的4个输入端与行线像并联 (20-23)行线初始为1,输入端为1
设置列电平刚开始为0,如果有按键按下其中一个行线变为0
那么与U3进行与传给INT0非,1*0=0
脉冲触发
然后为1变为0,负跳变脉冲,可以中断IE0=1
这里主要讲解一下不一样的地方:
主函数
void main(void) {
P0 = 0x00; //开机黑屏
IT0=1; //脉冲触发
EX0=1; //INT0允许
EA=1; //总中断允许
P2 = 0x0f; //为首次中断做准备,列线全为0,行线全为1
while(1); //模拟其他程序功能
}
这里P2=0x0f
P2是跟按键连接起来的
这样0x0f=0000 1111
高4位为0;
27-24是列线为0,行线全为1
再写中断函数:
void getKey () interrupt 0{
//中断函数
char key_scan[] = {
0xef, 0xdf, 0xbf, 0x7f}; //键扫描码
char i = 0, j = 0;
for (i = 0; i < 4 ; i++) {
P2= key_scan[i]; //输出扫描码
for (j = 0 ; j < 16 ;j++) {
if (key_buf[j]== P2){
//读键值,并判断键号
P0= led_mod[j]; //显示闭合键键号
break;
}}}
P2=0x0f; //为下次中断做准备
}
前面的都是行列式键盘的通用
需要注意的是
这里不需要判断行电压是否变换
if ((P2 & 0x0f) != 0x0f)
是因为:
一旦行线变化就是按键按下,中断就会发生,不需要判断,加上也行
注意最后结束后
P2=0x0f; //为下次中断做准备
这里P2=0x0f
P2是跟按键连接起来的
这样0x0f=0000 1111
高4位为0;
27-24是列线为0,行线全为1
总代码:
#include <reg51.h>
char led_mod[] = {
0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, //led字模
0x7f,0x6f,0x77,0x7c,0x58,0x5e,0x79,0x71};
char key_buf[] = {
0xee, 0xde, 0xbe, 0x7e,0xed, 0xdd, 0xbd, 0x7d,//键值
0xeb, 0xdb, 0xbb, 0x7b,0xe7, 0xd7, 0xb7, 0x77};
void getKey () interrupt 0{
//中断函数
char key_scan[] = {
0xef, 0xdf, 0xbf, 0x7f}; //键扫描码
char i = 0, j = 0;
for (i = 0; i < 4 ; i++) {
P2= key_scan[i]; //输出扫描码
for (j = 0 ; j < 16 ;j++) {
if (key_buf[j]== P2){
//读键值,并判断键号
P0= led_mod[j]; //显示闭合键键号
break;
}
}
}
P2=0x0f; //为下次中断做准备
}
void main(void) {
P0 = 0x00; //开机黑屏
IT0=1; //脉冲触发
EX0=1; //INT0允许
EA=1; //总中断允许
P2 = 0x0f; //为首次中断做准备,列线全为0,行线全为1
while(1); //模拟其他程序功能
}
实例3 将第四章实例2键控流水灯改用中断方式
问题是这样的:由于查询法 -按键查询、标志位修改及彩灯循环几个环节是串联关系,当CPU运行于彩灯时,将因不能及时检测按键状态,而使按键操作效果不灵敏
解决这一问题的方法:利用外部中断检测按键的状态, 一旦有按键动作发生,系统可立即更新标志位。
这样就保证系统及时按新标志位值控制彩灯运行。
为此需要对电路进行改造,加装一个4输入与门电路(输入端与p0并联),这样就能将按键闭合电平装化为INT0中断信号。
就是A0~A3相当于P0.0 ~ P0.3 对应按键的端口
如果按键按下,那么端口电压变低=0,传给并联的A
四个按键的电压通过与门,*0=0 传给INT0非端口
现在开始写代码:
延迟函数和led亮灯数
#include "reg51.h"
char led[]={
0xfe,0xfd,0xfb,0xf7};//LED花样数据
bit dir=0,run=0; //全局变量 dir方向标志 run亮灯标志
void delay(unsigned int time);
//延时函数
void delay(unsigned int time){
unsigned int j = 0;
for(;time>0;time--)
for(j=0;j<125;j++);
}
先写主函数:
void main(){
char i;
IT0=1;EX0=1;EA=1;//边沿触发、INT0允许、总中断允许
脉冲触发,中断允许
按下按键
按下按键就进入中断了
下面写主函数剩余部分:
void main(){
char i;
IT0=1;EX0=1;EA=1;//边沿触发、INT0允许、总中断允许
while(1){
if (run)
if(dir) //若run=dir=1,自上而下流动
for(i=0;i<=3;i++){
P2=led[i];
delay(200);
}
else //若run=1,dir=0,自下而上流动
for(i=3;i>=0;i--){
P2=led[i];
delay(200);
}
else P2=0xff; //若run=0,灯全灭
}}
写中断函数(判断标志位)
key() interrupt 0{
//键控中断函数 0表示是INT0中断
switch (P0 & 0x0f){
//修改标志位状态 保留低四位 判断哪个按键按下
case 0x0e:run=1;break;
case 0x0d:run=0,dir=0;break;
case 0x0b:dir=1;break;
case 0x07:dir=0;break;
}}
switch (P0 & 0x0f) 这个可以保留低四位p0电压,然后,对比,就知道哪个按键按下
比如: 0x0e 就想当与0000 1110
P0.0是0,变化了,说明按键K1按下,K1按下是流水灯 run=1
扩展外部中断源(后面会讲,简单了解先)
MCS-51单片机设置了二个外部中断源INT0、INT1,所以如果有要用到二个以上的外部中断源时候,就要进行外部中断源的扩展
定时器扩展外部中断源:
后面第六章还会介绍
本章总结
中断触发方式:外部引脚上出现低电平或负跳变脉冲(INTO和INT1)
计数器中接受的脉冲数达到溢出程度(T0和T1)。
完成一帧串行数据的发送或接收(TX/RX)
第五章练习题
(1) 外部中断0允许中断的C51语句为____。
A.RI=1; ——B.TR0=1;——C.IT0=1;——D.EX0=1;
注意混淆IT0=1与EX0=1;
IT0=1;是开中断INT0;而不是运行语句
EX0=1;
答案(D)
(3) 当CPU响应定时器T1中断请求时,程序计数器PC里自动装入的地址是______。
A.0003H
B.000BH
C.0013H
D.001BH
中断向量就是中断源在PC的地址,就是地址
答案(D)
7)在80C51单片机中断自然优先级里,级别正数第二的中断源是______。
A.外部中断1
B.定时器T0
C.定时器T1
D.串口TX/RX
考察中断优先级INTO,TO,INT1,TI、TXIRX顺序
中断优先级原则为:
①高级中断请求可以打断执行中的低级中断,同级中断请求不能打断执行中的同级或高级中断;
②多个同级中断源同时提由中断请求时,CPU将依据自然优先级查询中断请求:
③INTO,TO,INT1,TI、TXIRX的自然优先级依次降低:
4.单片机复位时,所有中断源都默认为低优先级中断。
答案(B)
(19)下列关于TX/RX的描述中______是不正确的。
A.51单片机的内部发送控制器和接收控制器都可对串行数据进行收发控制
B.若待接收数据被送入“接收SUBF”单元后,接收控制器可使RI位硬件置1
C.若“发送SUBF”单元中的数据被发送出去后,发送控制器可使TI位硬件置1
D.系统响应中断后,RI和TI都会被硬件自动清0,无需软件方式干预
CPU响应串行口中断后,TI和RI需要在中断服务程序中用软件清零
软件清零
答案(D)
13) 80C51单片机定时器T0的溢出标志TF0,当计数满在CPU响应中断后_____。
A.由硬件清零
B.由软件清零
C.软硬件清零均可
D.随机状态
记忆
答案(A)
思考题
2)简述中断、中断源、中断优先级和中断嵌套的概念。 提示
中断:在突发事件到来时先中止当前正在进行的工作,转而去处理突发事件。待处理完成后,再返回到原先被中止的工作处继续进行随后的工作。 中断源:中断管理系统能够处理的突发事件。 中断优先级:为使CPU能优先处理紧急突发事件,中断源被分成两类优先级,即自然优先级和设定优先级。CUP会优先响应高优先级的中断请求,而在同等优先级中又会按自然优先级的顺序选择响应。
3)简述51单片机各种中断源的中断请求原理。 提示
/INT0和/INT1:若该引脚处为低电平信号,则经过非门转换后可使中断请求标志位IE0或IE1硬件置1。若该引脚处为负跳变脉冲信号,则经过施密特触发器转换后也可使IE0或IE1硬件置1。IE0或IE1置1表示有/INT0或/INT1中断请求发生; T0和T1:当T0或T1中累加注入的脉冲信号被充满溢出后,可使中断请求标志位TF0或TF1硬件置1。TF0或TF1置1表示有T0或T1中断请求发生; TX和RX:若来自引脚RXD的一帧数据被送入SBUF接收单元后,可使中断请求标志位RI硬件置1。若来自SBUF发送单元的一帧数据经过输出门发送完毕后,也可使中断请求标志位TI硬件置1。RI或TI置1表示有TX或RX中断请求发生。
6)何为中断响应?51单片机的中断响应条件是什么? 提示
中断响应是指CPU从发现中断请求,到开始执行中断程序的过程。中断响应的条件为:1、有中断源发出中断请求;2、中断总允许位为1;3、中断源的中断允许位为1。此外,如遇CPU正在处理同级或更高优先级的中断,即使满足上述条件中断响应还会被阻止。
7)何为中断撤销?简述51单片机中断请求标志撤销的做法。 提示
中断请求标志清0的操作称为中断撤销。对于定时/计数器中断,可由硬件自动对TF0和TF1清0;对于脉冲触发的外部中断请求,也由硬件自动对IE0和IE1清0;对于电平触发的外部中断请求,需要先撤销/INT0和/INT1引脚上的低电平,然后要用软件方法才能使IE0和IE1清0;对于串口中断,TI和RI不能硬件自动清0,需要通过软件方法使TI和RI清0。
重点
9)80C51只有两个外部中断源,若要扩充外部中断源,可以采用的方法有哪些? 提示
扩充外部中断源的方法有,
1、利用定时器扩展外部中断源,其思路是;当T0或T1工作在计数器方式时,只要使其在一个外部脉冲到来时就溢出并产生中断请求,就能起到扩充外部中断源的作用。
2、利用查询法扩展外部中断源,其思路是:将多个扩充中断源通过“线或”电路连接/INT0或/INT1引脚,同时也将其接到输入口线作为中断源识别线。这样无论哪个扩展中断源有中断请求都会使/INT0或/INT1引脚发出中断请求信号。CPU响应中断后再通过程序查询各识别线的逻辑电平,便可确定是哪个扩展中断源发出中断请求了。。
12)为提高中断响应的实时性,中断函数可采用哪些措施以使函数更加简洁? 提示
首先应尽量使函数简短。其次应尽量使用简单变量类型及简单算术运算。还可采用,在中断函数中仅刷新标志变量状态,而在主函数或其他函数中根据该标志变量值再做相应处理的做法。
第六章:单片机的定时/计数器
在单片机系统中,有时候需要定时控制的需要,如定时输出,定时检测等
MCS-51单片机内集成了二个可编程定时/计数器模块T0和T1,它们既可以用于定时控制,也可以用于脉冲计数,还可以作为串行口的波特率发生器。
定时/计数器的基本原理
在前面我们已经初步认识了T0和T1
为了更全面的认识,从基础讲起
如图是一个由加1计数器组成的计数单元。
如图,当逻辑开关闭合后,脉冲信号将对加1计数器充值。若计数器的容量为2^n(n为整数).则当数值达到最大值后产生溢出,使中断请求标志TFx进位为1,同时加法器清0
如果在启动计数之前将TFx清零,并将一个称为计数初值a的整数先置入加1计数器,则当观察到TFx为1时表明已经加入了(最大值(2^n))-a个脉冲,如此便能计算出脉冲的到达数量
根据脉冲信号可以分辨使外部信号还是内部时钟信号:
- 脉冲信号是单片机的外部信号:
计数统计,即可作为计数器
- 脉冲信号是单片机的内部的时钟信号:由于单片机的振荡周期非常精准,可以通过计算溢出的脉冲数换算为
定时时间,可作为定时器使用
可见,上述定时器和计数器的实质都是计数器,差别仅在于脉冲信号的来源不同.
通过逻辑切换可以实现两者的统一。这就是单片机中将定时器和计数器统称为定时/计数器的原因。
单片机的定时/计数器工作原理图如图所示。
T0和T1两个定时计数器
基本原理:
如图,开关闭合后,脉冲信号将对加1计数器充值.
若计数器的容量为2的n次方,
则达到满计数值的时候会产生溢出;使得TFX(中断请求标志)进位为1,同时加1计数器清零
如图上左边,当输入的脉冲信号来源于振荡电路时候fosc(c/T=0),可作为定时器
当来源于单片机外部信号(C/T=1),可作为计数器
实质都是计数器,差别在于脉冲信号的来源不同,
可通过逻辑切换实现两者的统一,这就是定时/计数器的由来
定时器方式下(C/T=0):
定时时间:t=(2^n-a) x 12/fosc
计数初值a=2^n-t x fosc/12;
同理,计数器(c/T=1) 1方式下的计数值N为
N=2^n-a;
如图:16位定时器T0=(TH0(8CH) TL0(8AH) )
T1=(TH1(8DH 8BH)
两个定时器分别由高8位,低8位两个特殊功能寄存器组成,
是由这2个特殊功能寄存器控制的.
其中TMOD是定时计数器的工作方式控制寄存器,确定工作方式和功能(89H)
TCON是定时计数器的控制寄存器,用来控制T0和T1的开启,关闭,中断,溢出(88H)
外部引脚P3.4 P3.5用来接收外部脉冲
===============================================================
先看TMOD
89H
低四位控制T0,高四位控制T1
下面
C/T {
当为0时候为定时器
为1时候为计数器}
GATE:门控位
GATE=0-允许TR1启动计数器(
(当GATE=0时候,只要TR0=1就能使T0启动,TR0=0就能使T0停止)
GATE=1-允许INT0启动计数器
(当GATE=1时候,TR0=1和INT0引脚为高电平时候,启动T0)
M1,M0:工作方式定义位
00→方式0→13位的定时计数器
01→方式1→16位的定时计数器
10→方式2→8位自动重载定时计数器
11→方式3→3种定时计数器关系
然后是TCON
88H
TR1和TR0:T1和T0的启动控制位
===============================================================
M1M0决定的四种工作方式
方式一:
由高8位THX和低8位TLX组成16位的加1计数器
计数值为N=2^16-a;
如果为12MHZ
方式一的计数范围为1~65536
方式2:
8位TLx作为加1计数器,满计数值为2^8
另外一个高THx作为存放8位初值
若TLx种的计数溢出,重新装载把THx种的值装入TLx,不改变THx的值
N=2^8-a;
===============================================================
方式0:
采用5位TLx和高8位THx组成13位加1计数器
实例1
分析一下:
1.先看工作方式,是T1定时方式1
所以T1是高四位 M1为0,M0为1
00010000= 0x10;
所以TMOD的值为TMOD=0x10;
2.计算计数初值
用公式求出初值
本题种 —-a=2^16-tfosc/12= 2的16次方-100012/12=64536=0xfc18
3.确定编程方法
查询法或者中断法
为下次计数做准备(TFx复位+重载计数初值):
中断法会自动复位,如果是查询,需要软件复位TFx
代码:
查询法:
#include <reg51.h>
sbit P2_0=P2^0;
void main (void) {
TMOD = 0x01; //T0定时方式1
TR0=1; //启动T0
for( ; ; ){
TH0 = 0xfc; //装载计数初值
TL0 = 0x18;
do{
} while(!TF0); //查询等待TF0复位
P2_0 =!P2_0; //定时时间到P1.0反相
TF0 = 0; //软件清TF0
}
}
中断法:
代码:
#include <reg51.h>
sbit P2_0=P2^0;
void timer0 (void) interrupt 1 {
P2_0 = !P2_0; //P1.0取反
TH0 = 0xfc; //计数初值重装载
TL0 = 0x18;
}
void main (void) {
TMOD = 0x01; //T0定时方式1
P2_0=0;
TH0=0xfc; //预置计数初值
TL0=0x18;
EA=1;
ET0=1;
TR0=1;
while (1);
}
视频如下:
===============================================================
第6章总结
===============================================================
第7章:串行口及其应用
全双工通信:系统的每端都有接收端和发送端,可以任意通信
目前常用的是串口通信—半双工通信
SMOD:波特率选择位,–用于决定串口通信的波特率是否加倍
通信时钟波特律=fosc/(12*(2^n-a)) *2smod/32
实例2
接收端:
/*接收程序*/
#include<reg51.h>
#define uchar unsigned char
char code map[]={
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//'0'~'9'
void main(void){
uchar receiv; //定义接收缓冲
TMOD=0x20; //T1定时方式2
TH1=TL1=0xf4; //2400b/s
PCON=0; //波特率不加倍
SCON=0x50; //串口方式1,TI和RI清零,允许接收;
TR1=1; //启动T1
while(1){
while(RI==1){
//等待接收完成
RI = 0; //清RI标志位
receiv = SBUF; //取得接收值
SBUF = receiv; //结果返送主机
while(TI==0); //等待发送结束
TI = 0; //清TI标志位
P2 = map[receiv];//显示接收值
}
}
}
===============================================================
课后练习题目:
3) 80C51的串口工作方式中适合多机通信的是______。答案(D)
A.工作方式0
B.工作方式1
C.工作方式2
D.工作方式3
4)80C51串行口接收数据的次序是下述的顺序______。答案(B)
①接收完一帧数据后,硬件自动将SCON的RI置1
②用软件将RI清零
③接收到的数据由SBUF读出
④置SCON的REN为1,外部数据由RXD(P3.0)输入
A.①②③④B.④①②③C.④③①②D.③④①②
5) 80C51串行口发送数据的次序是下述的顺序______。答案(A)
①待发数据送SBUF
②硬件自动将SCON的TI置1
③经TXD(P3.1)串行发送一帧数据完毕
④用软件将SCON的TI清零
A.①③②④B.①②③④C.④③①②D.③④①②
7)在用接口传送信息时,如果用一帧来表示一个字符,且每帧中有一个起始位、一个结束位和若干个数据位,该传送属于______。答案(A)
A.异步串行传送 B.异步并行传送 C.同步串行传送 D.同步并行传送
8) 80C51的串口工作方式中适合点对点通信的是______。答案(B)
A.工作方式0
B.工作方式1
C.工作方式2
D.工作方式3
11)80C51串口发送控制器的作用描述中_____是不正确的。答案(D)
A.作用一是将待发送的并行数据转为串行数据
B.作用二是在串行数据上自动添加起始位、可编程位和停止
C.作用三是在数据转换结束后使中断请求标志位TI自动置1
D.作用四是在中断被响应后使中断请求标志位TI自动清零
18)下列关于串行主从式通信系统的描述中______是错误的。答案(B)
A.主从式通信系统由1个主机和若干个从机组成
B.每个从机都要有相同的通信地址
C.从机的RXD端并联接在主机的TXD端,从机的TXD端并联接在主机的RXD端
D.从机之间不能直接传递信息,只能通过主机间接实现
===============================================================
===============================================================
发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/196698.html原文链接:https://javaforall.cn
【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛
【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...