单片机工作时,会从ROM中一条一条的取出指令,然后一步一步的执行,单片机访问内存的时间叫机器周期,也就是一个时间基准,一个机器周期由12个时钟周期组成,如果单片机选用12MHz晶振,那么它的时钟周期就是1/12us,机器周期就是12×(1/12)us,也就是1us。
在MCS-51单片机的所有指令中,有的完成得比较快,只需要一个机器周期,有的完成得比较慢,需要两个机器周期,有的甚至需要4个机器周期。为了衡量指令执行时间的长短,引入了一个新的概念:指令周期。所谓指令周期,就是指执行一条指令所花费的时间。例如当需要计算完成DJNZ指令所需要的时间时,首先要知道晶振的频率,如果采用的晶振是12MHz,那么一个机器周期就是1us。DJNZ指令是双周期指令,所以执行一次需要2us,如果该指令需要执行500次,那么正好是1000us,也就是1ms。
机器周期不仅对指令执行很重要,也是单片机定时器和计数器的时间基准。例如,如果单片机选择了12MHz的晶振,那么当定时器的值增加1时,实际经过的时间就是1us。这就是单片机的计时原理。
简单来说,没有晶振就没有时钟周期,没有时钟周期程序代码就无法执行,单片机就无法工作。
5.格雷码到二进制的转换方法
二进制码第n位=二进制码第(n+1)位+格雷码第n位。由于二进制码和格雷码的位数相同,所以从最高位左边取0即可计算出二进制码。(注意:遇到1+1时,结果视为0)
例如:格雷码0111为4位数字,那么它转换成的二进制码也一定是4位数字。因此,转换后的二进制码第五位可以取为0,即0 b3 b2 b1 b0。
0+0=0,所以 b3=0
0+1=1,所以b2=1
1+1 等于 0,所以 b1=0
0+1 等于 1,所以 b0=1
因此转换后的二进制码为0101
格雷码转换的快速方法
(假设二进制值0作为格雷码的0)
G:格雷码 B:二进制码
G(N) = B(n+1)异或B(n)
单片机广泛应用于工业控制、家电、消费电子、医疗电子、仪器测量等领域。为了满足初级电子工程师/单片机爱好者的需求,电子爱好者网隆重策划,整合推出《单片机基础关键技术详解》系列技术文章,后续还将陆续推出其他章节,敬请广大工程师朋友继续关注。为响应广大工程师网友对前三章的热烈反响,电子爱好者网将继续推出更多技术精品系列文章,供各位工程师网友欣赏。
阅读相关系列章节
单片机关键技术基础详解(上)
单片机关键技术基础详解(下)
单片机关键技术基础详解(三)
1.C51单片机在电子电路设计中的常见问题
我在工作中用过AT89C2051、AT89C51、AT89C52等51单片机,后来用过***新茂、华邦等厂家的51单片机,在实践中遇到很多书上没有的问题。在我的印象里书上的知识只有一页插图,就是CPU时序图。最开始是直接用汇编写程序,后来用C51嵌套汇编。编译器用的是威孚系列的编译器,后来用过Keil等,感觉这些编译器都差不多,需要熟练的C语言基础,再加上单片机应用的特殊性。
本文总结了51单片机应用中的一些常见问题,这些都是我实际遇到过的,由于文章篇幅有限,这些问题还远远不足以表达单片机的常见问题,希望对初学者有所帮助,文章中不完善之处还请大家指出,谢谢!
1:C51编译器如何区分位地址和字节地址?
它是通过预先定义来实现的,例如:sfr P0 = 0x80;sbit P0_0 = 0x80;前者声明了P0口的地址在0x80处,后者声明了P0口的bit0也就是P0.0在位地址空间中位于0x80处。这两个0x80具有完全不同的含义,通过关键字sfr和sbit来区分。这样,在编译程序时,编译器就会据此将其编译成相应的汇编语言。例如:
C51语句:P0 = 1;
P0声明为sfr,因此编译成:mov 80h,01h,将会把0x01个数据送入0x80单元,由于0x80单元物理上对应的是P0口,所以P0.0引脚会输出高电平(实际是高阻状态,这是P0口特有的),其它.1-.7引脚都会输出低电平。
C51语句:P0_0 = 1;
P0_0声明为sbit,所以编译成:setb 80h,会把位地址空间中0x80地址处的位的值设置为1,这个位正是P0端口的bit0,执行之后P0.0会输出高阻。P0.1-.7不会发生变化。
2:C51为什么需要嵌套汇编?
51单片机的一个显著优点就是指令执行时间固定,因此可以适应对时序要求严格的场合。比如对符合ISO7816协议的CPU卡的读写,就有严格的时序要求,其实就是用IO引脚做成的同步半双工串口。支持CPU卡的程序一般比较大,需要使用C51来组织,但是由于C汇编的不确定性,底层程序必须封装成汇编语言模块嵌入到工程中。这样就带来几个问题:如何声明函数,如何传递参数等,限于篇幅,不能详细讲解,下面举个例子:
汇编程序保存在单独的文件中,并添加到项目中。功能如下:
_proc_a:
移动 a, r7
增加
mov r7, a
保留
在.h文件中使用C语言声明:extern unsigned char proc_a(unsigned char val);
调用形式如下:retvalue = proc_a(0x11);
阐明:
a:如果汇编程序有参数,则需要在汇编程序前添加下划线,但在声明的地方不用添加(这是威孚编译器的要求)。
b:函数的第一个参数在R7中传递,函数的返回值在R7中返回,这个是C51的通用规范,其他参数都有相应的规定。函数可以返回一个位,就是在psw的c位中返回。
c:以上语句的执行顺序是将0x11赋给R7,然后跳转到子程序,将其加1后返回。
d:当函数跳转到汇编程序时,此区域中的寄存器R0-R7、A、B、PSW、DPTR等可供子程序使用,无需考虑调用后是否恢复这些常规资源。上例中A的值已被函数使用,程序员无需恢复调用前的值。
3:51单片机P0口的特殊功能
很多新手都会遇到这个问题,其实很简单,涉及到芯片的io引脚是怎么弄的,这个对于硬件工程师来说很重要,TTL io引脚模型:
P1、P2、P3口都可以理解为左图,注意vcc下面有一个电阻,所以可以理解为:该引脚输出1的能力弱。地那边没有电阻,可以理解为该引脚吸收电流的能力强。至于P0口可以理解为右图,这个是集电极开路输出,也叫OC输出,可以看出当ctr=1的时候,三极管导通,引脚接地;ctr=0的时候,三极管截止,引脚悬空,也叫三态。做这个口的目的是考虑到P0口负责读写数据和地址复用,这个关系需要仔细理解CPU时序图,所以P0口要加合适的上拉电阻,千万不要加下拉电阻,上拉电阻的选择要根据外部的负载来决定。
4:如何输入输出P1-3端口
从上一节的左图可以看出。输出的时候ctr=1输出强信号0,ctr=0输出弱信号1。io引脚作为输入的时候应该设置ctr=0,这样三极管截止。如果外部信号是1,上拉电阻会加强这个1,单片机就会读到1。当外部信号为0的时候,请注意必须完全抵消上拉电阻的上拉作用,才能让引脚上得到0。
所以对于程序来说,设置io引脚为1代表是接收状态,当然也是输出1状态。程序把io口设置成1,读出的信号是否为1取决于外部电路,如果外部电路没有“吃掉”上拉电阻的电流,读出来的就会是1。反之,虽然程序把io引脚设置成1,读出来的就会是0。
所以如果用io引脚的高电平去驱动外部电路,一定要小心外部电路会“吃掉”这个1,输出不了1。作为输入时,0电平的外设必须有足够的能力把io引脚拉低。所以用io引脚直接点亮LED时,最好用反逻辑,也就是输出0,让LED亮起来。这样可以保证驱动能力。也就是io引脚接LED的负端,LED的正端通过电阻接VCC。
所以当io引脚输出1的时候,外部电路强制将其接地是可以的,但是当io引脚输出0的时候,外部电路如果强制连接到电源,会损坏io引脚。所以程序上电后,一般把所有io口都写成1:MOV P0,0FFH。
P3口引脚是复用的,必须所有引脚都处于输出1状态。比如RXD引脚输出0的话,将无法读出任何数据。我曾经花了一整天时间调试,发现串口收不到数据,就是因为RXD引脚没有置1,把时间都浪费在了外围上,当时很是尴尬。
5:关于晶振
单片机的晶振内部可以简化成一个反相器,当晶振输入脚XI刚过阈值电压被认为是1时,输出脚XO输出0,这个0会驱动晶振使XI电压下降,当下降到阈值电压被认为是0时,输出脚XO输出1,如此循环重复。
因此,用示波器观察正常工作的晶振输入脚XI时,得到的是一条大致水平的线,而XO则是一条幅度较大的正弦波。测量晶振输入脚XI时,应将示波器探头置于X10位置,否则探头会使晶振停振。
所以在布线时,晶振输入脚XI要尽量靠近晶振,而XO脚可以稍远一些。同时XO具有一定的驱动能力,有些芯片可以用它去驱动其他时序电路(不建议这么做,因为会降低系统的可靠性)。
写到这里,意识到51单片机的问题实在是太多了,本文也只是沧海一粟,以后我会另起一篇文章进行补充。
2.实验单片机开发板介绍
开发板集成了单片机系统最常用、最关键的功能单元,包括字符液晶显示、图片/汉字显示、数码管显示、实时时钟、步进电机控制、继电器控制、ADC转换、E2PROM操作、串口通信等,并提供了完整的C51例程。
基本配置
1、STC89C51单片机支持通过串口在线下载程序,也就是说你不用再购买单片机烧录器,可以随时把程序烧录到你的单片机里,并且随时观察你修改的程序的运行情况。
2、4位8段数码管显示(可用于计数器、计时器、频率计、流水灯、电子钟等各种显示实验)
3、MAX232芯片RS232通讯接口(可作为与电脑通讯的接口,也可作为给STC单片机下载程序的接口)
4、独立+5V直流供电(避免因USB口供电而烧毁电脑主板的隐患)
5、蜂鸣器(可以使单片机发声、唱歌,让单片机变成电子钢琴)。
6、模数转换芯片ADC0832(两路可调的AD输入,串行接口控制,转换效率高,是我们常用的模数转换器件)。
7、ULN2003步进电机驱动控制,可以控制继电器,驱动步进电机(这是迈向工业自动化的第一步,步进电机的操作是学习单片机必须要面对的,必须掌握的,机械的精确定位需要用到步进电机,数码相机调焦,扫描仪等设备都大量使用步进电机)
8、SPI串行实时时钟电路(DS1302)及后备电源(熟悉SPI总线,可以用DS1302制作万年历电子钟,待机电流很小,纽扣电池后备电源可以保证时钟芯片工作数年,断电时间继续,与定时器制作的时钟相比,它走时更准确,不需要计算,自动产生闰年,再次通电时数据不会乱掉)。还必须掌握同类时钟芯片的操作。
9、继电器控制,学会用弱电来控制强电,在电气安全控制、远程控制方面非常有用。
10、AT24C02外置EEPROM芯片(IIC总线组件实验)。此芯片FLASH中存储的数据可保证10年不丢失。
11、字符液晶1602LCD接口。(采用插拔式接头,插拔方便,可显示两行,每行16个字符,共32个任意ASCII码字符。其功能应用比数码管丰富得多,显示的信息量也大。可设计为仪器、设备控制面板的人机交互模块)。
12、图形点阵液晶12864LCD接口(采用插拔方式,方便插拔,可以显示任意汉字及图形,是单片机图形显示最常用的显示设备。本实验板支持带字库的12846液晶,让程序开发更加方便。12846液晶不随板赠送)。
13、4*4矩阵键盘(熟悉矩阵键盘编码、解码及扫描原理,可作为人机交互信息输入界面)。
14、单片机的32个IO口全部引出,方便用户自由扩展,增加新功能。
15.可加装锁定装置,方便主芯片的安装和拆卸
16、大部分元器件采用SMD封装,有效节省系统空间。功能模块电源切换由软件控制,无需跳线连接,系统综合控制功能强。
17、光盘内含本实验板全部例程,还附赠破解版KEIL编译、调试、仿真软件,STC单片机程序下载软件,电路板设计软件PROTEL 99SE、PROTEL 2004DXP等,以及所有电路图,实验板详细使用教程等。
标准组件
MCU开发板标准配置
1.主机开发板一套(含板上所有元器件)
2、串行通讯线一条(兼作程序下载线)
3. 一个1602字符LCD
4.DVD一张(开发板全套资料)
电路板及电子元器件单独出售,用户可以自行焊接、调试。
3. IC解密:单片机运算指令
单片机算术指令汇总,单片机无进位加法指令
ADD A, #DATA; 例如:ADD A, #10H
ADD A,直接;例如:ADD A,10H
ADD A,Rn;例如:ADD A,R7
ADD A, @Ri;例如:ADD A, @R0
目的:将A中的值与其后面的值相加,最终结果返回给A。
例如:MOV A,#30H
添加 A, #10H
执行该指令后,A中的值为40H。
自行练习以下问题
MOV 34H,#10H
MOV R0,#13H
MOV A,34H
添加A,R0
MOV R1,#34H
添加 A,@R1
带进位的加法指令
直流母线电压A,Rn
ADDC A,直接
ADDC A,@Ri
ADDC A,#数据
目的:将A中的值与其后的值相加,并将进位位置C的值相加。
注意:由于51单片机是8位机,所以只能做8位数值运算,但是8位运算的范围只有0-255,实际工作中不够用,所以需要进行扩展。一般把两个8位数值运算组合成一个16位运算。这样,能表达的数值范围就能达到0-65535。怎么组合呢?其实很简单,我们来看一个十进制数例程:
66+78。
我们不关心这两个数相加的过程,但实际上我们是这样做的:先做 6+8(低位),再做 6+7(高位)。我们做了两次加法,但是我们在做的时候并没有刻意把它分成两次加法,或者我们没有意识到我们做了两次加法。之所以分成两次加法,是因为这两个数超出了单个数字(0-9)可以表达的范围。
做低位加法的时候会产生进位,我们做的时候在相应的位置点一下,做高位加法的时候再把这个点加进去。在计算机里做16位加法也是一样,先做低8位。如果两个数相加产生了进位,我们也需要“点一下”做一个标记,这个标记就是PSW里的进位位C,做高位加法的时候就把这个C加上去。例:1067H+10A0H,先做67H+A0H=107H,而107H显然超过了0FFH,所以最后A里存的数值是7,而1就放到PSW里的CY位上,也就是说CY相当于100H。再做10H+10H+CY,结果是21H,所以最后结果就是2107H。
MCU 带借位减法指令
亚基A,Rn
SUBB A,直接
SUBB A,@Ri
SUBB A,#数据
假设(R2)=55H,CY=1,执行指令SUBB A,R2后,A中的值为73H。
注意:微控制器没有无借位减法指令。如果需要执行无借位减法指令(执行第一次减法时),只需清除 CY。
乘法指令
穆尔公司
该单片机指令功能是将A、B中两个8位无符号数相乘。两个数相乘的结果一般很大,所以最后结果以16位数表示,高8位放在B中,低8位放在A中。当乘积大于FFFFFH(65535)时,将0V设置为1(溢出),否则OV为0,CY始终为0。
例如:(A)= 4EH,(B)= 5DH,执行指令
MUL AB 后乘积为 1C56H,因此将 1CH 放入 B 中,将 56H 放入 A 中。
部门指令
AB 类
该单片机指令功能是将A中的8位无符号数除以B中的8位无符号数(A/B)。除法的结果通常为小数,但计算机中无法直接表示小数。它利用了我们小学时还未接触小数时的商和余数的概念,例如13/5,商为2,余数为3。除法后商放在A,余数放在B。CY和OV均为0。如果除法前B中的值为00H,即除数为0,则0V=1。
添加 1 条指令
增加
增加 Rn
INC 直接
INC@Ri
增加DPTR
目的很简单,就是将目标中的值加1。例:(A) = 12H,(R0) = 33H,(21H) = 32H,(34H) = 22H,DPTR = 1234H。执行以下指令:
增加 A (A) = 13H
增加R2(R0)=34H
INC 21H(21H)= 33H
INC @R0(34H)= 23H
增加DPTR(DPTR)= 1235H
注意:从结果来看,INC A 和 ADD A,#1 类似,但 INC A 是单字节单周期指令,而 ADD #1 是双字节双周期指令,且 INC A 不会影响 PSW 位,如 INC A (A) = 00H 后 (A) = 0FFH,CY 保持不变。如果是 ADD A,#1,则 (A) = 00H,CY 一定为 1。因此加 1 指令不适合用于加法,其实主要用于计数、地址增加等,另外加法指令都是以 A 为中心。