9.12学习笔记
1:80C51的引脚封装形式
第一管脚到第八管脚为P1,一个准双向8位I/O口,每个口可以独立控制,内带上拉电阻,这种接口没有高阻态,输入也不能锁存,故不是真正的双向I/O口,之所以称之为准双向,是因为该口在输入之前,要进行写1操作,然后单片机才能正确的读入外部信号,也就是要有一个准备 的过程,对于52单片机,p1.0的第二功能是T2定时器计数器的外部输入,P1.1引脚的第二功能为T2Ex捕捉,重装处罚,即是T2的外部控制端
第九引脚复位引脚RST,复位时当输入连续两个机器周期以上的高电平时完成复位操作(两个机器周期是12个状态周期,是24个振荡周期)在单片机正常工作时,应当接入0.5v的低电平,复位时,把数据指针指到0地址 VPD是该引脚的第二功能,即备用电源的输入端,当VCC掉电时,自动接入该第二功能
第十到第十七引脚为P3,P3拥有第二功能,其定义为 P3.0是串行输入口 P3.1是串行输出口 P3.2外部中断0 P3.3外部中断1 P3.4是定时器/计数器0的外部输入端 P3.5是定时器/计数器1的外部输入端(P3.4,P3.5可以做成一个计数器) P3.6是外部数据存储器写脉冲 P3.7是外部数据存储器读脉冲
18,19管脚是外部晶振的输入端,其中18管脚(XTAL2)片内振荡电路的输出端,19管脚(XTAL1)为片内振荡电路的输入端,8051的时钟有两种方式,一种是片内时钟振荡方式,需要在这两个脚外加石英晶体和振荡电容,振荡电容的值一般是10p到30p,另一种是外部时钟方式,即XTAL1接地,外部时钟信号从XTAL2输入
20管脚是GND管脚,和40管脚一起,为单片机提供闭合回路
21到28管脚是P2口,与其他端口一致,当他没有第二功能
第29管脚是PSEN
第30管脚是ALE/PROG,在单片机扩展外部RAM时,ALE用于控制把P0口的输出低八位送到锁存器锁存起来,以实现低位地址与数据的隔离。在没有访问外部存储器期间,ALE以六分之一的振荡周期输出,即六分频,当访问外部存储器时,ALE会以十二分之一的振荡周期输出,这里可以看到,但系统没有进行扩展时,ALE会以固定的频率输出,这里可以看做是一个外部时钟,也可以用来检测单片机是否正常工作。由于科技的不断进步,芯片内部的RAM不断扩大,导致这一管脚的用处不大
第31管脚是EA/VPP,EA接入高电平时,单片机读取内部程序存储器,当扩展有外部ROM时,读取完内部ROM时自动读取外部ROM,EA接入低电平是,单片机直接读取外部ROM,现在我们使用的单片机都有内部存储器,所以在设计电路时,EA始终接入高电平
第32管脚到39管脚是P0,P0,一个双向8位三态I/O口,每个口可以独立控制,51单片机p0口没有上拉电阻,为高阻态,不能正常的输出高低电平,因此该组I/O口在使用服务时,必须外接入上拉电阻(三态,高电平,低电平,高阻态)
2:单片机相应电路的分析,设计电路要慢慢积累,这个很重要
晶振的电路接法,电容用来给晶振起振,一般接入为30pf,这个电路在以后的最小系统中会用得到
数码管的显示
为了使数码管亮,应当是数码管进行编码,刚好对应I/o的八个引脚,位选和段选,位选控制哪一个数码管亮,段选控制数码管显示什么字形,因为是共阴数码管,所以控制哪个灯亮灭只要给输入端放置0
由于I/O口的电流比较微弱,所以在接入数码管之前要加入上拉电阻,
LED显示器的两种显示方式:动态显示,静态显示
锁存器,高电位随着I/O的变化而变化,低点位锁存上一次的状态,下降沿保存数据,所以开始的时候一定是先直通
电路如图所示:
示例代码:数码管显示静态显示一个数字
#include<reg52.h> sbit dula = P2^6; sbit wela = P2^7; void main() { wela = 1;//连通位选 P0 = 0xfe; wela = 0;//锁存器关闭 dula = 1; P0 = 0x66; dula = 0; while(1); }
示例代码:数码管8个静态显示1到f
#include<reg52.h> #define uint unsigned int #define uchar unsigned char void delay(uint z); sbit dula = P2^6; sbit wela = P2^7; /*编码表的定义与c语言的十分相似,但是多了一个关键字 code,code表示编码的意思,需要注意的是*单片机c语言中定义 数组时是占用内存空间的,而定义编码时这是直接分配到程序空间 间,编译后编码占用的是程序存储空间,而不是内存空间*/ uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void main() { uchar num; wela = 1;//连通位选 P0 = 0x0; wela = 0;//锁存器关闭 while(1) { for(num =0;num<16;num++) { dula = 1; P0 = table[num]; dula = 0; delay(1000); } } while(1); } void delay(uint z) { uint x,y; for(x = z;x>0 ;x--) for(y = 110;y>0;y--); }
这里为什么用P0,虽然p0没有外接上拉电阻,但是他可以通过74hc573芯片,该芯片的输出电流比较大,所以足够点亮一个数码管
80c51的中断系统结构,51单片机具有5个中断源,因此中断可以嵌套,51单片机可以嵌套2个中断,嵌入式系统可以嵌套4到5个不等
中断的概念:cpu在处理某一件事件a时,发生了另一件事件b请求cpu迅速去处理,cpu暂时中断当前工作,转去处理时间b(中断响应和中断服务)待cpu处理完事件b,回到原来事件a的地方继续处理a(中断返回),这个过程称为中断
中断技术可以解决快速主机与慢速I/O设备的数据传送问题,而且还具有一下优点
分时操作:cpu可以分时的为多个I/O设备服务,提高了计算机的利用率
实时响应:cpu能够及时处理应用系统的随机事件,系统的实时性大大增强
可靠性高,cpu具有处理设备故障及掉电等突发性事件的能力,从而使系统的可靠性提高。
80c51单片机的中断优先级别的三条原则
cpu同时接受几个中断时,首先响应优先级别高的中断请求
正在进行的中断过程不能被新的同级别或优先级别低的中断请求打断
正在进行的低优先中断服务,能被高优先级别中断请求所中断
为了实现上述原则,中断系统内部设有两个用户不能寻址的优先级状态触发器,其中一个置1,表示正在响应高优先级别的中断,他讲阻断后来所有的中断请求,另一个置1,表示正在响应低优先级级别的中断,他将阻断后来所有的低优先级别中断
中断响应的条件
(1)中断源有中断请求(2)此中断源的中断允许位为1(3)cpu开中断(即EA=1)
示例中断代码:将上面的代码加入中断
#include<reg52.h> #define uint unsigned int #define uchar unsigned char void delay(uint z); sbit dula = P2^6; sbit wela = P2^7; sbit d1 = P1^0; uchar num; /*编码表的定义与c语言的十分相似,但是多了一个关键字 code,code表示编码的意思,需要注意的是*单片机c语言中定义 数组时是占用内存空间的,而定义编码时这是直接分配到程序空间 间,编译后编码占用的是程序存储空间,而不是内存空间间*/ uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void main() { EA = 1;/*开总中断 所有可以地址 被八整除的寄存器可以进行位寻址,? 是可以直接操作寄存器的某一位 */ EX0 = 1;//开中断0
ITO = 1;//设置为跳变沿触发方式 //或者是 TCON = 0x01;
wela = 1;//连通位选 P0 = 0x0; wela = 0;//锁存器关闭 while(1) { for(num =0;num<16;num++) { d1 = 1; dula = 1; P0 = table[num]; dula = 0; delay(1000); } } while(1); } void delay(uint z) { uint x,y; for(x = z;x>0 ;x--) for(y = 110;y>0;y--); } void exter0() interrupt 0//中断服务子程序 ,还要表明是哪一个中断 { d1 = 0; }
中断的两种方式,跳变沿触发方式和电平触发方式,对应的控制位在TCON寄存器中的,在TCON中可以设置对应中断的触发方式,比如外部中断1的中断请求位IT1,当IT1=0时为电平触发方式(当对应的中断1引脚为P3^3的电平变为低即P3^3的电平变为0)触发中断,一直为0的话,函数一直停留在中断函数中,直到P^3的电平变为1时回到主函数,当IT1等于1时为跳变沿触发方式,即当电平发生变化时,触发中断,之后有会回到主函数继续执行
所有可以地址被八整除的寄存器可以进行位寻址,就是可以直接操作寄存器的某一位
中断服务程序没有返回值void exter0()interrupt 0//interrupt后面跟那一个数字对应哪一个中断,并且中断函数不需要声明
定时器/计数器
实现定时的功能,比较简单的方法有三种:
软件定时:软件定时不占用硬件资源,当占用了cpu的时间,降低了cpu的利用率
采用时基电路定时,例如采用555电路,外接必要的元器件(电容或电阻),即可构成硬件定时电路,但是硬件连接好以后,定时值和定时范围不能有软件进行控制和修改,即不可编程
采用可编程芯片定时这种定时芯片的定时值以及定时范围很容易用软件来确定和修改,此种芯片定时的功能钱啊,使用灵活,在单片机的定时计数器不够用的时候,可以考虑进行扩展
定时器计数器的结构和工作原理
定时器的结构:定时器计数器的实质是加一计数器(16位)由高八位和低八位两个寄存器组成,TMOD是定时器/计数器的工作寄存器,他确定工作的方式和功能。TCON是控制寄存器,控制T0,T1的启动,停止,以及设置溢出标志
加一计数器的脉冲有两个来源,这个室友系统时钟振荡器输出脉冲经12分频后送来,另一个是T0或T1引脚输入的外部脉冲源。每来一个脉冲计数器加一,但计数器全部为1时,再输入一个脉冲就使计数器归零,且计数器的溢出使TCON中的IF0和TF1置1,向cpu发出中断请求
由此可见,由溢出时计数器的值减去计数器初值才是加一计数器计数的值
设置为定时器模式时,计数值N乘以机器周期TCY就是定时时间
定时器计数器的控制
80c51单片机定时器计数器的工作模式有两个特殊功能寄存器控制,TMOD用于设置其工作方式,TCON可以用来控制启动和中断申请
TMOD寄存器:
TMOD低四位用于T0,高四位用于T1,
当GATE = 0只要用软件使TCON中的TR0或TR1为1,就可以启动定时器或者是计数器工作
当GATE = 1;定时器/计数器的启动与停止由TCON寄存器的TRx(x=0,1)和外部中断引脚INT0或者INT1上的电平状态来控制
C/T:是定时器计数器模式的选择位,当C/T = 1,为计数模式,当C/T = 0时为定时器模式
M1M0工作设置位,定时器有四个工作位
TCON定时器控制器寄存器
TCON的低四位用于控制外部中断,TCON 的高四位用于控制课制作定时/计数器的启动和中断的申请,等一下用的是TR0
运用定时器要装初值:高四位为THX = (65535-N)/256;低四位TLX=(65535-N)%256;
代码实现过程呢
对TMOD赋值,以确定T0和T1的工作方式
计算初值,并将其写入TH0,TL0,或TH1,TL1
中断方式时,对IE赋值,开放中断
使TRO或TR1置位,启动定时器,计数器定时或计数
示例代码:
#include<reg52.h> #define uint unsigned int #define uchar unsigned char void delay(uint z); sbit dula = P2^6; sbit wela = P2^7; sbit d1 = P1^0; uchar num,tt; /*编码表的定义与c语言的十分相似,但是多了一个关键字 code,code表示编码的意思,需要注意的是*单片机c语言中定义 数组时是占用内存空间的,而定义编码时这是直接分配到程序空间 间,编译后编码占用的是程序存储空间,而不是内存空间间*?/ uchar code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c, 0x39,0x5e,0x79,0x71}; void main() { TMOD = 0x01;//设置定时器0为工作方式1 TH0 = (65535-50000)/256;//高八位装初值 TL0 = (65535-50000)%256; EA = 1;/*开总中断 所有可以地址 被八整除的寄存器可以进行位寻址,? 是可以直接操作寄存器的某一位 */ ET0 = 1;//开定时器0中断 TR0 =1 ;//启动定时器 //EX0 = 1;//开中断0 // TCON = 0x01; wela = 1;//连通位选 P0 = 0x0; wela = 0;//锁存器关闭 while(1) { if(tt == 20) { tt = 0; num++; d1 = 1; dula = 1; P0 = table[num]; dula = 0; delay(1000); } } while(1); } void delay(uint z) { uint x,y; for(x = z;x>0 ;x--) for(y = 110;y>0;y--); } void exter0() interrupt 1//中断服务子程序 ,还要表明是哪一个中断 { TH0 =(65535-50000)/256; TL0 = (65535-50000)%256; tt++; }
版权所有,转载请注明链接地址:www.cnblog.com/fengdashen