单片机资料讲解Word格式.docx
《单片机资料讲解Word格式.docx》由会员分享,可在线阅读,更多相关《单片机资料讲解Word格式.docx(17页珍藏版)》请在冰豆网上搜索。
它是时序中的最大单位。
一个指令周期通常含有1,2或4个机器周期。
指令所包含的机器周期数决定了指令的运算速度,机器周期数越少的指令,其执行速度越快。
思考题:
设应用单片机晶振频率为12MHz,问时钟周期、机器周期、指令周期分别为多少?
80C51单片机中,由个振荡周期组成1个机器周期,由个机器周期组成1个指令周期。
可通过测量ALE确定CPU是否工作,ALE有时钟的特点。
指令字节数:
存储该指令所需的ROM单元数
指令机器周期数:
执行该指令所花费的机器周期数
MCS-51/8051共有111条指令,这些指令的字节数和机器周期数各不相同,可分为六类,对应于六种基本时序:
单字节单周期指令
单字节双周期指令
单字节四周期指令
双字节单周期指令
双字节双周期指令
三字节双周期指令
项目2
v计数:
计数是指对外部事件的个数进行计量。
其实质就是对外部输入脉冲的个数进行计量。
v定时:
8051单片机中的定时器和计数器是一个部件,只不过计数器记录的是外界发生的事件,而定时器则是由单片机内部时钟源脉冲进行计数的。
这个计数源是由单片机的晶振经过12分频(即机器周期脉冲)后获得的一个脉冲源。
所以定时器计数脉冲的时间间隔与晶振有关。
工作方式2(M1M0=10,自动重装计数初值的8位加1定时器/计数器)
16位定时器/计数器被拆成两个8位寄存器TH0和TL0,初始化时必须装入相同的定时器/计数器初值。
以TL0作计数器,而TH0作为预置寄存器。
当计数满溢出时,TF0置“1”,同时TH0将计数初值自动装入TL0。
这种工作方式很适合于那些重复计数的应用场合(如串行数据通信的波特率发生器)。
计数器初值的计算
方法:
用最大计数量减去需要的计数次数。
即:
TC=MC
其中:
TC——计数器需要预置的初值;
M——计数器的模值(最大计数值);
方式0时,M=213;
方式1时,M=216;
方式2,3时,M=28;
C——计数器计满回0所需的计数值,即设计任务要求的计数值。
例如:
流水线上一个包装是12盒,要求每到12盒就产生一个动作,用单片机的工作方式0来控制,则应当预置的初值为:
TC=MC=21312=8180=1FF4H
TH、TL分别送什么?
定时器初值的计算
定时时间的计算公式为:
T=(MTC)×
T0(或TC=MT/T0)
其中:
T—定时器的定时时间,即设计任务要求的定时时间;
T0—计数器计数脉冲的周期,即单片机系统主频周期的12倍;
M—计数器的模值;
TC—定时器需要预置的初值。
若设初值TC=0,则定时器定时时间为最大。
若设单片机系统主频为12MHz,则各种工作方式定时器的最大定时时间为:
工作方式0:
Tmax=213×
1s=8.192ms
工作方式1:
Tmax=216×
1s=65.536ms
工作方式2和3:
Tmax=28×
1s=0.256ms
(1)采用查询方式处理的程序
C语言程序:
#include<
reg51.h>
sbitP1_0=P1^0;
voidmain()//主程序
{
chari;
TMOD=0x20;
TH1=0x38;
TL1=0x38;
TR1=1;
for(;
;
)
if(TF1){TF1=0;
P1_0=!
P1_0;
}
//查询计数溢出
}
(2)采用中断处理方式的程序
EA=1;
ET1=1;
while
(1);
voidtime0_int(void)interrupt3//中断服务程序
P1_0=!
P1_0;
若要输出60ms的方波程序该如何修改?
若输出60ms方波,则定时时间为30ms,工作方式选择方式1(16位加1定时器/计数器方式)。
TC=M-T/T计数=216-30ms/1μs=65536-30000=8AD0H
vC51程序如下:
#include<
sbitflash_led=P1^0;
voidmain(void)
{TMOD=0x01;
TH0=0x8A;
TL0=0xD0;
IE=0x82;
TR0=1;
voidtimer0(void)interrupt1
{TH0=0x8A;
flash_led=!
flash_led;
【例】设系统时钟频率为12MHZ,用定时/计数器T0编程实现从P1.0输出周期为1s的方波。
分析:
系统时钟频率为12MHz时,定时器/计数器的最长的定时是方式2(16位加1定时器/计数器)下的65.536ms,500ms的定时无法直接实现,可以结合软件计数器来进行设计。
如:
用定时/可计数器T0产生周期性为10ms的定时,然后用一个寄存器R2对10ms计数50次或用定时/计数器T1对10ms计数50次实现。
初值计算:
TC=MT/T0=216-10ms/1μs=65536-10000=D8F0H
(1)用寄存器R2作计数器软件计数,中断处理方式
//包含特殊功能寄存器库
sbitP1_1=P1^1;
voidmain()
TMOD=0x01;
TH0=0xD8;
TL0=0xf0;
ET0=1;
i=0;
voidtime0_int(void)interrupt1//中断服务程序
i++;
if(i==50){P1_1=!
P1_1;
i=0;
(2)用定时/计数器T1计数实现,定时/计数器T1工作于计数方式时,计数脉冲通过T1(P3.5)输入,设定时/计数器T0定时时间到对T1(P3.5)取反一次,则T1(P3.5)每20ms产生一个计数脉冲,那么定时500ms只须计数25次,设定时/计数器T1工作于方式2,初值X=256-25=231=11100111B=E7H,TH1=TL1=E7H。
因为定时/计数器T0工作于方式1,定时,则这时方式控制字为01100001B(61H)。
定时/计数器T0和T1都采用中断方式工作。
C语言程序如下:
sbitP3_5=P3^5;
{TMOD=0x61;
TH1=0xE7;
TL1=0xE7;
voidtime0_int(void)interrupt1//T0中断服务程序
{TH0=0xD8;
P3_5=!
P3_5;
voidtime1_int(void)interrupt3//T1中断服务程序
{P1_1=!
定时器的应用:
扩展外部中断
【例】利用定时器T0扩展一个外部中断
解:
P3.4(T0)作为外部中断的输入引脚,设定T0工作方式2(自动重装初值的8位计数方式),同时计数初值设为0FFH,这样,只要P3.4输入一个负脉冲,计数器加1,产生溢出中断请求。
v初始化程序:
v定时器的应用:
PWM信号输出
vPWM(PulseWideModulation)即脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术,广泛应用在从测量、通信到功率控制与变换及LED照明等许多领域中。
v随着电子技术的发展,出现了多种PWM技术:
相电压控制PWM、脉宽PWM法、随机PWM、SPWM法、线电压控制PWM等。
v有的单片机有PWM输出功能,8051单片机没有PWM输出功能,可利用定时器产生PWM信号。
v在单片机应用中,PWM信号通常用于LED调光、直流电机调速等。
v例:
在P1.0引脚输出固定周期(50ms)的PWM信号,占空比10%、50%、90%可变,用一个按键调节占空比。
v解:
设置一个变量,取值范围0~2,对应占空比10%、50%、90%。
在中断服务函数中根据该变量为高电平或低电平的定时赋不同的初值(设定时器T0工作方式1):
v10%:
高电平5ms,初值0xec78,低电平45ms,初值0x5038;
v50%:
高电平25ms,低电平25ms,初值0x9e58;
v90%:
高电平45ms,低电平5ms
1.MCS-51的中断源
1)2个外部中断源(中断标志为IE0和IE1)
由(P3.2)端口线引入,低电平或下降沿引起。
由(P3.3)端口线引入,低电平或下降沿引起。
2)2个定时器中断(中断标志为TF0、TF1)
T0:
定时/计数器0中断,由T0回零溢出引起。
T1:
定时/计数器1中断,由T1回零溢出引起。
3)串行口中断(中断标志为SCON的TI/RI位)
串行端口完成一帧字符的发送或接收后自动置位TI或RI标志位,发送中断和接收中断都将向CPU申请串口中断。
5个中断源
信号输入引脚
中断请求标志(TCON、SCON)
中断允许控制(IE)
中断允许总控位EA(IE.7)
中断优先级控制(IP)
中断服务程序入口地址
自然优先级
外部中断0
INT0(P3.2)
IE0(TCON.1)
EX0(IE.0)
PX0(IP.0)
0003H
高
低
定时/计数器0
T0(P3.4)
TF0(TCON.5)
ET0(IE.1)
PT0(IP.1)
000BH
外部中断1
INT1(P3.3)
IE1(TCON.3)
EX1(IE.2)
PX1(IP.2)
0013H
定时/计数器1
T1(P3.5)
TF1(TCON.7)
ET1(IE.3)
PT1(IP.3)
001BH
UART串行口
RXD(P3.0)
TXD(P3.1)
RI(SCON.0)异或TI(SCON.1)
ES(IE.4)
PS(IP.4)
0023H
中断初始化设置
Ø
在使用中断系统功能之前必须对中断系统进行初始化。
初始化是指对IP、IE、TCON、SCON等与中断系统相关的特殊功能寄存器进行赋值。
初始化内容
1)设定中断源的优先级(IP相应位置1)
2)若为外部中断,还要设定中断触发方式(写TCON的ITx)
3)开相应的中断(IE相应位置1)
例:
设8051外部中断源接引脚INT0,中断触发方式为电平触发,高优先级,试编制8051中断系统的初始化程序。
使用外部中断0和外部中断1,INT0为高优先级,电平触发方式;
INT1为低优先级,下降沿触发方式,写出初始化程序。
项目4
v波特率:
每秒钟传送信号的数量,单位为波特(Baud)。
v比特率:
每秒钟传送二进制数的信号数(即二进制数的位数),单位是bps(bitpersecond)或写成b/s(位/秒)。
v在单片机串行通信中,传送的信号是二进制信号,波特率与比特率数值上相等。
单位采用bps。
v波特率(bps)=字符的位数×
字符/秒(Bps)
v例如,异步串行通信的数据传送的速率是120字符/秒,而每个字符规定包含10位数字,则传输波特率为:
v120字符/秒×
10位/字符=1200位/秒=1200bps
v通常,异步通信的波特率在50~19200bps之间。
波特率的计算
方式0:
B=fosc/12。
方式2:
波特率由PCON中的选择位SMOD来决定,可由下式表示:
B=fosc×
2SMOD/64
方式1和方式3:
波特率是可变的,由定时器T1的溢出率控制。
波特率为:
B=(2SMOD/32)×
定时器T1溢出率
T1溢出率=1/T1定时时间
=1/(计数脉冲周期*计数次数)
=(fosc/12)/(2KTC)
K——定时器T1的位数,定时器T1用作波特率发生器时,通常工作在方式2,所以T1的溢出所需的周期数=28TC。
TC——定时器T1的预置初值。
波特率B=(2SMOD/32)×
fosc/[12×
(28-TC)]
定时器T1的初值:
TC=256-2SMOD×
fosc/(384×
B)
TC=256-2SMOD*fosc/(384*B)
v
(1)初始化编程
v写SCON。
根据工作方式确定SM0、SM1位;
对于方式2和方式3还要确定SM2位;
如果是接收端,则置允许接收位REN为1;
如果方式2和方式3发送数据,则应将发送数据的第9位写入TB8中。
v设置波特率。
写PCON,若波特率可变,则通过对T1(方式2)编程设置波特率。
v写IP、IE。
设置中断优先级,开中断。
v双机通信要求通信双方满足如下约定:
v字符格式相同;
v通信波特率相同;
v电平信号相同。
补充
MCS-51的编程语言常用的有两种,一种是汇编语言,一种是C语言(C51)。
汇编语言的特点:
机器代码生成效率很高,可读性差,可移植性差,编程难度大。
C51与ASM-51(汇编语言)相比,有如下优点:
①编程员无须深入了解单片机的指令系统和硬件,只需初步了解其存储器结构。
②良好的模块化结构,便于改进和扩充。
③寄存器分配、存储器的寻址及数据类型,中断服务程序的现场保护和恢复,中断向量表的填写都由C51编译器处理。
④丰富的库函数。
⑤能方便地管理内部寄存器的分配、不同存储器的寻址和数据类型等细节问题。
⑥头文件中允许定义宏、说明复杂数据类型和函数原型,有利于程序的移植和支持单片机的系列化产品的开发。
⑦可方便地接受多种实用程序的服务,有专门的实用程序自动生成;
有实时多任务操作系统,可调度多道任务,简化用户编程,提高运行的安全性等。
C51缺点:
可控性差,对硬件的控制有限,而汇编语言可以完全控制硬件资源;
精确度低;
代码效率低,在小应用程序中产生的代码量大,执行速度慢,但在较大的程序中代码效率仅比汇编程序低10~20%。
C语言本身没有输入输出语句。
输入和输出是通过输入输出函数scanf()和printf()来实现的。
输入输出函数是通过标准库函数形式提供给用户
数据类型
长度(位)
取值范围
char
字符型
signedchar
8
-128~127
unsignedchar
0~255
int
整型
signedint
16
-32768~32767
unsignedint
0~65535
long
长整型
signedlong
32
-21474883648~21474883647
unsignedlong
0~4294967295
浮点型
float
±
1.75494E-38~±
3.402823E+38
指针型
*
1-3字节
对象的地址
访问SFR
sfr
sfr16
位型
bit
1
0,1
sbit
当运算符两侧的数据类型不同时,要转换成同种类型。
转换方式有两种情况:
v一是自动转换,是指编译器在编译时自动进行的类型转换。
顺序为:
bit→char→int→long→float,signed→unsigned。
v二是强制类型转换,通过强制类型转换符“()”对数据类型进行人为的强制转换。
(long)a,将a强制转换为long类型。
存储器类型
对应单片机存储器
data
直接寻址的片内RAM低128B,访问速度快
bdata
片内RAM的可位寻址区(20H~2FH),允许字节和位混合访问
idata
间接寻址访问的片内RAM,允许访问全部片内RAM,共256字节。
pdata
用Ri间接分页访问的片外RAM的低256B
(MOVX@Ri)
xdata
用DPTR间接访问的片外RAM,允许访问全部64KB片外RAM
(MOVX@DPTR)
code
程序存储器ROM64k空间
(MOVC@A+DPTR)
特殊功能寄存器变量
v对SFR的操作,只能采用直接寻址方式。
为了能直接访问这些特殊功能寄存器,KeilC51扩充了两个关键字“sfr”、“sfr16”,可以直接对51单片机的特殊寄存器进行定义,这种定义方法与标准C51语言不兼容,只适用于对8051系列单片机C51编程。
v格式:
sfr或sfr16特殊功能寄存器名=地址;
vsfr后面是一个要定义的名字,要符合标识符的命名规则,名字最好有一定的含义
v等号后面必须是整型常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH)。
vsfr是定义8位的特殊功能寄存器,sfr16用来定义16位特殊功能寄存器,如8052的T2定时器,可以定义为:
sfr16T2=0xCC;
//这里定义8052定时器2,地址为T2L=CCH,T2H=CDH
v用sfr16定义16位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上。
注意的是,sfr16适用于所有新的16位SFR,但不能用于定时器0和1的定义。
v对于需要单独访问SFR中的位,C51的扩充关键字‘sbit’可以访问位寻址对象。
位变量
vbit位变量名;
vsbit位变量名=位地址;
bit与sbit的区别:
vbit用于位变量操作,值为0或1,可用于定义变量类型、函数声明、函数返回值(若函数中禁止中断或函数中包含明确的寄存器组切换,则不能定义函数返回值为bit)等,存储于内部RAM的位寻址区,不能定义位指针和位数组。
vsbit用于位变量操作,值为0或1,但使用范围更广泛,可以用于定义任意可位寻址的各个位(包括特殊功能寄存器)。
绝对地址的访问
1.使用C51运行库中的预定义宏
•CBYTE以字节形式对code区寻址
•CWORD以字形式对code区寻址
•DBYTE以字节形式对data区寻址
•DWORD以字形式对data区寻址
•XBYTE以字节形式对xdata区寻址
•XWORD以字形式对xdata区寻址
•PBYTE以字节形式对pdata区寻址
•PWORD以字形式对pdata区寻址
absacc.h>
#definePORTAXBYTE[0xffc0]
#defineNRAMDBYTE[0x40]
2.通过指针访问
例4-8】通过指针实现绝对地址的访问。
#defineucharunsignedchar/*定义符号uchar为unsignedchar*/
#defineuintunsignedint/*定义符号uint为unsignedint*/
voidfunc(void)
uchardatavar1;
ucharpdata*dp1;
/*定义一个指向pdata区uchar型数据的指针dp1*/
uintxdata*dp2;
/*定义一个指向xdata区uint型数据的指针dp2*/
uchardata*dp3;
/*定义一个指向data区的uchar型数据指针dp3*/
dp1=0x30;
/*dp1指针赋值,指向pdata区的30H单元*/
dp2=0x1000;
/*dp2指针赋值,指向xdata区的1000H单元*/
*dp1=0xff;
/*将数据0xff送到片外RAM30H单元*/
*dp2=0x1234;
/*将数据0x1234送到片外RAM1000H单元*/
dp3=&
var1;
/*dp3指针指向data区的var1变量*/
*dp3=0x20;
/*给变量var1赋值0x20*/
3.使用C51扩展关键字_at_
[存储器类型]数据类型说明符变量名_at_地址常数
【例4-9】#defineucharunsignedchar
#defineuintunsignedint
dataucharx1_at_0x40;