单片机原理及应用
单片机结构原理
指令系统
详解
思维导图
小结
51系列单片机的中断系统
详解
思维导图
中断处理过程示意图:
程序存储器ROM中中断源位置
- 由于各中断入口间只有8个字节,一般情况下不够安排一个完整的中断服务程序。因此,通常总是在中断入口地址处放置一条无条件转移指令,使程序转向真正存放中断服务程序的地址
- 中断服务程序编程注意点:
- 根据需要保护现场
- 及时清除不能被硬件自动清除的中断请求标志
- 中断服务程序中的压栈和出栈指令必须成对使用,以避免堆栈数据出错
- 串口中断提出申请, 且主程序累加器A需保护,编程注意:
- 在 0000H放一条跳转到主程序的跳转指令, 这是因为 MCS-51单片机复位后, PC的内容变为 0000H, 程序从 0000H 开始执行, 紧接着 0023H是中断程序入口地址, 故在此中间只能插入一条转移指令
- 响应中断时, 先自动执行一条隐指令“LCALL 0023H”, 而 0023H至 002BH(串行口中断入口地址)之间可利用的存储单元不够, 故放一条无条件转移指令
- 对串行口中断标志位硬件不能自动清除,所以一定要在中断服务程序中要有清标志位RI和TI的指令CLR RI和CLR TI
- 在中断服务程序的末尾, 必须安排一条中断返回指令RETI, 使程序自动返回主程序
应用
题目一
P1.4~P1.7接有四个发光二极管,P1.0~P1.3接四个开关,消抖电路产生中断请求信号,当消抖电路的开关来回拔动一次产生一个下降沿信号,通过INT0 向CPU申请中断,初时发光二极管全灭,每中断一次,P1.0~P1.3所接的开关状态反映到发光二极管上,且要求开关断开的对应发光二极管亮
SJMP $:
跳转到本指令的起始位置开始执行,如果系统的中断是开放的,那么SJMP $指令实际上是在等待中断,当有中断申请后,CPU 转至执行中断服务程序
中断返回时,仍然返回到这条死循环指令,继续等待中断,而不是返回到该指令的下一条指令。这是因为执行该指令后,PC 仍指向这条指令,中断的断点就是这条指令的首字节地址汇编语言
1 | ORG 0000H |
- C语言(C51编译器)
编译器在规定的中断源的矢量地址中放入无条件转移指令,使CPU响应中断后自动地从矢量地址跳转到中断服务程序的实际地址,而无需用户去安排
中断服务程序定义为函数,函数的完整定义如下:
返回值 函数名([参数]) interrupt n[using m]
interrupt n:将函数声明为中断服务函数,n为中断源编号,0~31间的整数,编译器从8n+3处产生中断向量地址,n不允许是带运算符的表达式
using m:函数使用的工作寄存器组,m的取值范围为0~3,可缺省- 影响:函数入口处将当前寄存器保存,使用m指定的寄存器组,函数退出时原寄存器组恢复。选不同的工作寄存器组,可方便实现寄存器组的现场保护
1 |
|
题目二
AT89S51的P1口接一个共阴极的数码管,利用消抖开关产生中断请求信号,每来回拔动一次开关,产生一次中断,用数码管显示中断的次数(最多15次,十六进制数显示)
汇编语言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24ORG 0000H
AJMP MAIN
ORG 0013H ;INT1中断入口
AJMP INT1 ;转中断服务程序
ORG 0030H ;主程序
MAIN: SETB IT1 ;边沿触发中断
SETB EX1 ;允许INT1中断
SETB EA ;开中断开关
MOV R0,#0 ;计数初值为0
MOV A,#3FH ;“0”的字形码送A
MOV DPTR,#TAB ;指向数码表
WAIT: SJMP WAIT ;等待中断
INT1: INC R0 ;中断次数加1
MOV A, R0
MOVC A, @A+DPTR ;查表
MOV P1,A
CJNE R0,#0FH RE
MOV R0,#0
RE: RETI ;AL1地址→PC,返主程序AL处
TAB: DB 3FH,06H,5BH,4FH,66H,6DH
DB 7DH,07H,7FH,6FH,77H,7CH
DB 39H,5EH,79H,71H ;字形码表
END
- C语言(在中断服务程序中控制中断次数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
char i;
code char tab[16]= {0x3f,0x06,0x5b,0x4F0x66,0x6d,0x7d,
0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
int() interrupt 2
{
i++
if (i<16) P1=tab[i];
else{i=0;P1=0x3f;}
}
main()
{
EA=1;
EX1=1;
IT1=1;
P1=0x3f;
while(1); /*等待中断*/
}
MCS - 51单片机定时/计数器
详解
定时/计数器用途:
- 输出一定频率、一定占空比的波形
- 测量脉冲宽度
- 对外部信号计数
- 扩展外部中断
初始化编程:
- 方式选择、定时或计数的选择(1计数,0定时)、是否使用门控信号反映在TMOD中
- 计算计数值,填写在TL0、TH0或TL1、TH1中
- 如果使用定时中断,则需要进行中断的初始化,包括IE(开放中断EA=1, 定时器Tx 中断允许ETx=1 )、IP寄存器的设定
- 启动定时器工作,设置TCON中的TR0或TR1
T0/T1对外部时钟计数(外部脉冲的下降沿触发计数)时,外时钟的最大频率振荡频率的1/24
计数器在每个机器周期S5P2(第5个状态周期的P2节拍)期间采样,若一个机器周期采样值为1,下一个机器周期采样值为0,则计数器加1
因此 ,外部计数脉冲一个周期最少两个机器周期,即24个振荡周期JBC指令:判断可位寻址区域内指定位是否为1,为1则跳转到指定位置,并同时清除该位(置0)
CPL指令:直接寻址位取反
系统复位后,SP的初始值为07H,使得堆栈实际上是从08H开始的。但我们从RAM的结构分布中可知,08H—1FH隶属1—3工作寄存器区,若编程时需要用到这些数据单元,必须对堆栈指针SP进行初始化,原则上设在任何一个区域均可,但一般设在30H—1FH之间较为适宜。
在8051单片机中,入栈SP+2,出栈SP-2通常T1用作串行接口的波特率发生器时,T0工作在方式3
方式 0 的应用
题目:利用定时器T1定时,在P1.0输出周期为 1 ms的方波, 设单片机晶振频率为 6 MHz
分析:
- 每隔 0.5ms对 P1.0 取反一次即可得到这个方波
- 计算计数初值:
机器周期=12÷6 MHz= 2 μs
需要计数次数N:N=0.5ms÷2 μs =250
初值X=M-N=8 192-250=7 942=1F06H 0001 1111 000 | 0 0110
13 位计数器,TL1 使用了低5位 00110(06H),TH1用8位(6~13位)1111 1000(F8H)
TMOD初始化: TMOD=0000 0000B=00H
TCON初始化: 启动TR1=1
IE初始化: 开放中断EA=1, 定时器T1 中断允许ET1=1
汇编语言(直接查溢出标志位)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15ORG 0000H
AJMP START ; 复位入口
ORG 0030H
START: MOV SP, #60H ; 数据缓冲区(30H~7FH),用于堆栈
MOV TH1, #0F8H ; T1赋初值
MOV TL1, #06H
MOV TMOD, #00H
SETB TR1 ; 启动T1
LP1: JBC TF1, LP2 ;查询定时器1溢出标志位是否置1,为1转到LP2
AJMP LP1
LP2: MOV TH1, #0F8H ; T1赋初值
MOV TL1, #06H
CPL P1.0 ;P1.0位取反
AJMP LP1C语言
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
sbit p10=p1^0;
main()
{
TMOD=0;
TH1=0xf8;
TL1-0x06;
TR1=1;
While(1)
{
do { } while(TF1==0);
P10=~p10;
TH1=0xf8;
TL1-0x06;
TF1=0;
}
}汇编语言(采用中断)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19ORG 0000H
AJMP START ; 复位入口
ORG 001BH
AJMP T1INT ; T1中断入口
ORG 0030H
START: MOV SP, #60H ; 初始化程序
MOV TH1, #0F8H ; T0赋初值
MOV TL1, #06H
MOV TMOD, #00H
SETB TR1 ; 启动T1
SETB ET1 ; 开T1中断
SETB EA ; 开总允许中断
MAIN: AJMP MAIN ; 主程序,等待中断
T1INT: CPL P1.0
MOV TL1, #06H
MOV TH1, #0F8H
RETI
单片机串行口及应用
详解
- 在串行异步传送中,CPU与外设之间事先必须约定:
- 字符格式:用ASCII码通信,有效数据为7位,加1个奇偶校验位、1个起始位(”0”)和1个停止位(”1”)共10位。停止位也可大于1位
- 波特率(Baudrate):波特率是数据的传送速率,即每秒钟传送的二进制位数,单位为位/秒。它与字符的传送速率(字符/秒)之间存在如下关系
波特率=位/字符×字符/秒=位/秒
发送端与接收端的波特率必须一致
这里的波特率相当于通原中的传信率bit/s,传码率(符号/s)
波特率是可变的, 它取决于定时器 T1 的溢出速率及SMOD的状态
- 与方式1不同, 方式2和3中装入RB8的是第9位数据, 而不是停止位。所接收的停止位的值与SBUF、 RB8 和 RI都没有关系, 这一特点可用于多机通信
串行口的初始化编程:
- 按选定的串口工作方式设定SCON的SM0、SM1位
- 对于工作方式 2 或 3, 应根据需要在TB8中写入待发送的第9位数据
- 若选定的不是方式 0,还需设定接收/发送的波特率
- 设定SMOD(在PCON的最高位)的状态, 以控制波特率是否加倍
- 若选定工作方式1或3, 则应对定时器T1进行初始化以设定其溢出率
四种工作方式:
方式1为8位通信, 波特率可变
方式2为9位通信,波特率为两种可选
方式3为9位通信, 波特率可变方式1和方式3波特率与T1溢出率有关,
通常T1工作在方式2,对机器周期计数,
计算溢出率 时,如果T1工作在0,1方式,则会产生误差定时器T1作为波特率发生器, 通常选用定时方式2(8 位重装载初值方式),此时禁止 T1 中断
波特率设计:
- 方式0:波特率(固定)=fosc(晶振频率)/12
- 方式2:波特率(两种情况)
- SMOD=0,fosc/64
- SMOD=1,fosc/32
- 方式1(传10位,8位数据位)和方式3(传11位,有个用户定义位,一般是奇偶校验位)
- 总结:
- SCON(串行接口控制寄存器,可位寻址):串口工作方式选择,是否允许接收,查询有无发送/接收中断
- PCON(电源控制寄存器,不可位寻址):D7位SMOD,为“1”,波特率加倍,为“0”,波特率不加倍
- 若用到定时器T1
TR1置1,定时器启动
TMOD(定时器/计数器方式寄存器,不可位寻址):控制定时器的工作方式,T1在方式2
设置计数初值:TH1,TL1
应用
题一
设某单片机系统需通过串行口与一微机系统双向通信,采用1位起 始位、8位数据和1位停止位的协议,波特率为2400。单片机上电复位后,首先向微机发送一个55H。编写单片机的初始化程序
- 分析:
单片机串行口应工作于方式1,允许接收,SCON=01010000B;
采用Timer1作波特率发生器,T1工作于方式2,定时方式,TMOD=20H
T1初值为F4H
1 | MOV SCON, #01010000B ;初始化串口 |
题二
设有两个单片机系统甲和乙。两系统均工作于全双工中断方式,串行口工作于方式3,第9位数据为奇偶校验位,CPU 时钟为11.0592MHz。定时器T1工作于方式2,波特率2400, SMOD=0,将系统乙内外部数据存储器7C00H~7CC7H共200个字节的数据传送到系统甲中外部数据存储器7E00H~7EC7H中;将系统甲内外部数据存储器7C00H~7CC7H共200个字节的数据传送到系统乙中外部数据存储器7E00H~7EC7H中。编写两个系统的程序
分析:
源数据均在7C00H~7CC7H,共200个字节,目的数据区首址为7E00H
SCON=11010000B=D0H ,
PCON=00H ,
TMOD=00100000B=20H
2400=(20/32) x(11.0592/12(28-Z)) , Z=F4H位传送时需通过累加器C
奇偶标志位P位于PSW(程序状态寄存器),观测累加器A中“1”的个数,P=0,1有偶数个;P=1,1有奇数个
1 | ADDR1H EQU 30H ;源数据指针 |