c51单片机晶振频率怎么测一些简单设计中,晶振的频率应该怎么选?

C51单片机应用与C语言程序设计(精简版)doc下载_爱问共享资料
C51单片机应用与C语言程序设计(精简版).doc
C51单片机应用与C语言程序设计(精简版).doc
C51单片机应用与C语言程序设计(精简版).doc
简介:本文档为《C51单片机应用与C语言程序设计(精简版)doc》,可适用于IT/计算机领域,主题内容包含高等职业教育创新实践教材高等职业教育创新实践教材工程对象教学法系列教材C单片机应用与C语言程序设计基于机器人工程对象的项目实践秦志强等编著电子工业出符等。
侵权或盗版
*若权利人发现爱问平台上用户上传内容侵犯了其作品的信息网络传播权等合法权益时,请按照平台要求书面通知爱问!
赌博犯罪类
13人已下载
在此可输入您对该资料的评论~
添加成功至
资料评价:  二、电路原理    电路如附图所示。频率测试电路的核心逻辑控制由89C51担任,完成计数、数转十六进制数、数码管扫描信号及测试信号产生、不同时间闸门定时控制信号产生等功能。CD4513将十六进制数译成BCD码送共阴极数码管段驱动显示。采用动态方式显示,扫描信号由89C51的P24~P26输出,经74LS138译成8位扫描信号,7407驱动数码管的位显示。由于89C51片内计数器只有16位,所以扩展了一片74LS393将计数增至24位,这样89C51可计频率最大值为2的24次方=16.777216M,显示为10MHz频率时信号分辨率为1Hz。闸门定时控制信号由89C51内部定时产生,由13脚输出至8的13脚进行定时闸门控制计数。    被测信号放大电路分L挡和H挡。    L挡放大电路输入级T3采用以提高电路、减轻对被测试电路影响,后两级T4、T5采用简单放大电路。H挡放大电路还包括(10MHz~1000MHz)除以64,电路,由IC1完成。其内部包含高频信号放大电路,灵敏度可达lOOmV。    本电路还预留了一级,由Tl贴片式微波三极管进行放大,可进行加装实验,以提高测试灵敏度。晶振测试电路由IC8的两个组成,工作为500kHz~30MHz。经实际测试频率在2MHz~200MHz范围内的晶振(一般大于20MHz的晶振多数为泛音晶振)大多数都能顺利起振,甚至两端455、465、450等标称陶瓷器、三端10.7MHz陶瓷滤波器、三端晶体滤波器中的多数也能顺利起振。对于泛音晶振,本电路显示的是基频值,从中可推算出是几次泛音。因振荡频率范围较宽,无法统一校准晶振频率,所以显示值与标称值有一定偏差。另外振子本身也有一定偏差.所以可测量其一致性或与比较准确的振子进行对照测试。整机工作小于200mA。
  三、使用及注意事项    1.电源为直流7.5V&9V(不能超过+12V)。    2.信号输入端口的交直流电压应小于20V,超过IMHz信号电压应小于1V,10MHz~1000MHz信号最好采用感应法,即用一小段电线(长短视频率而定)或并联一(电感圈数由频率或自行实验测试掌握)进行与被测信号感应耦合测试,距离视被测试信号功率大小而定。    3.因本仪器无外壳,所以要注意板上焊盘、元器件不能短路。    4.晶振测试插座不能作为信号输入或输出端口用,以防止因不匹配造成本电路或被测试电路上的元器件损坏。    5.不可以将大功率的仪器、发射设备、电器的信号直接送至输入口。需要测量时,应外加相应衰减器,将其衰减至正常测试电平信。    6.频率计只适合测试稳定频率,非稳定频率值测试无意义。例如已的AM、、FSK等信号就不能准确测量。对于调制度小的信号可用快速取样F挡测试,但不一定都能正常测量显示,应根据实验取得大量数据经验再定量测试。    7.闸门控制取样时间选择由被测试电路稳定度决定。晶体振荡电路或电路可选择S挡。RC和LC振荡电路可造择F挡。    8.本电路小于10MHz频率的灵敏度是在输入占空比为50%的方波下测定的,对于正弦波、三角波、锯齿波等,灵敏度则相对要降低。    9.在测量3MHz以下的晶振时,有可能显示为标称值频率的整倍数,这并不是晶振有问题,只要能稳定显示频率数值,电可判定其好坏。    10.测试晶振时,最好去掉输入信号。    11.测试晶振时,K1必须切换至L挡,并配合K2使用。测试500kHz~10MHz晶振时,K1切换至L挡、K2切换至S挡。测试大于10MHz晶振时,K1切换至L挡,K2切换至F挡。
&&&&&往下看有更多相关资料
本网站试开通微、小企业商家广告业务;维修点推荐项目。收费实惠有效果!欢迎在QQ或邮箱联系!
试试再找找您想看的资料
资料搜索:
查看相关资料 & & &
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款
copyright & &广电电器(中国梧州) -all right reserved& 若您有什么意见或建议请mail: & &
地址: 电话:(86)774-2826670& & &&)最近做比赛,需要写程序做一个智能小车。C语言的基础和编程的能力我是有的,但是我对单片机等硬件不是很了解,特意进行了一番学习。估计以后也用不了多少,特此写一篇笔记,方便后人参考学习。
我不喜欢翻着教材或视频一节一节地学习,我的学习方式是问题启发式学习:直接切入正题,遇到不会的问题就找度娘,学会之后再次进入正题,遇到问题再查阅资料,循环往复,直到走通为止~整个学习下来,虽然可能会有些漏洞,但是已经基本进入状态了。
由于我是业余的,所以难免会有错解或不妥之处,还请读者能以挑剔的眼光为我指出。
一、C语言相关
Q1:sbit与sfr代表是什么?有什么作用?
A1:sfr用来声明特殊功能的寄存器,sbit用来声明特殊功能位。
sfr占用一个内存单元(8位,取值范围为0 ~ 255 = 2^8-1。对于I/O端口来说,刚好每一位对应一个引脚),例如 sfr P0& = 0x80; 这一句定义了P0端口与地址0x90对应。特殊功能的寄存器一般在开发工具(Keil)中自带的头文件,例如reg52.H中声明好了,只需要在程序中引入该头文件就好了;
w用法:sfr 变量名 = 地址值;
w需要注意的一点是,例如P0对应的是一个&8&字型的数码管,若要显示3,则可对P0口赋值:P0 = 0x0D,若要将其熄灭,只需对其赋值:P0=0xFF。这里的值并不代表地址,而是一个16进制的数(值的前两位0x代表16进制,后两位。刚好FF代表十进制的255)。
wsfr16也是用来声明特殊功能寄存器,所不同的是它用于操作占两个字节(取值范围为0~65535)的寄存器,比如定时器T0和T1。
sbit只占用一个位,也就是说用它定义的变量只能取0和1两个值。一般用来给引脚取别名,例如sbit P1_0 = P0^1; 就是定义用符号P1_0来表示P1.0引脚。 需要注意的是,一单用了sbit定义某个变量,这个变量的地址就是确定的了(不能修改了);
w对于引脚来说,这个0和1是有物理意义的:0代表低电平,1代表高电平。而机器是不懂代码只能识别高低电平。(脑补:这样我们就打通了从代码/软件通往硬件的大路~) 高电平就是5伏正电压,低电平就是0伏,这个是理想值,实际上它也有一个范围......(参考自)
w用法1:sbit 位变量名 = 地址值;
w用法2:sbit 位变量名 = SFR名称^地址值;
w用法3:sbit 位变量名 = SFR地址值^变量位地址值;
w3种用法参考自:
关于8051单片机特殊功能寄存器的说明,可以查阅:
为防止链接失效,这里给出文件名:《8051,STC89C52单片机特殊功能寄存器》
Q2:#define OSC_FREQ& L这句宏命令里的&L&是什么意思?
A2:长整型数字在数字的后面加字母L,如104L,034L等。总结如下:
w十进制:直接用一般数字来表示,例如123,111,-999等;
w十六进制:以0x开头,如0xFF,0x01等;
w长整型:在数字后面加字母L,如104L,034L等
w浮点型:分为十进制形式和指数形式两种,统一格式为 [&](数)(.数){e[&]数},其中[ ]为可选项,( )表示二者必有其一,{ }十进制不填,指数必填。例如:3.14,-.1,+2;.3e-3,12e+3,6.66e13
w字符型:用单引号括住括住,例如'a','c'等。对于特殊字符,例如换行符、反斜杠等请参考C语言等教材。
w字符串:略
Q3:我粘贴了别人的代码,怎么发现没有unit这个类型?
A3:别人的代码只给了函数部分,没有给头文件中的预处理命令。可以在自己的头文件中加入:#typed (后面要加分号),这样就可以用uint类型来代表unsigned int类型了。
Q4:为什么好多变量都是char类型?它不是字符类型吗?怎么可以用来计数?
A4:int在8位的51单片机是占用2个字节,char在占用1个字节,所以说char类型占用空间更小。单片机的存储器很小,尽量不要浪费空间,能用小的就用小的,且一般都用无符号的。
至于它为什么可以计数,因为字符本来就是用二进制表示的,所以当你对char类型的变量赋值时(例如 char a = 'A'),它(a)底层仍然是二进制,将二进制转化为十进制,当然可以用来计数。
Q4.1:51单片机中的char,int,long,float,double各占多少个字节,取值范围多大?
表:Keil uVision4面向51单片机的基本数据类型各种属性一览表
Q5:unsigned char data是什么数据类型?
A5:定义一个变量的格式为:[存储种类]& 数据类型& [存储器类型]& 变量名表
在定义格式中除了触及类型和变量名表是必要的,其他都是可选项。存储种类有四种:
wauto(自动)、extern(外部)、static(静态)和register(寄存器),默认类型为自动。
存储器类型的说明是指定该变量在C51硬件系统中所使用的存储区域,并在编译是准确定位。如果省略存储器类型,系统则会按编译模式SMALL,COMPACT或LARGE所规定的默认存储器类型去指定变量的存储区域。89C51中的存储器类型有:
wdata :可直接寻址的内部数据存储区(128B),访问速度最快;
widata:间接寻址的内部数据存储区(256B),允许访问全部内存地址;
wbdata:可位寻址内部数据存储区(16B),允许位与字节混合访问;
wpdata:分页的外部数据存储区(256字节),用MOVX @Ri指令访问;
wxdata:外部数据存储区(64KB),用MOVX @A+DPTR指令访问;
wcode :程序存储区(64KB),用MOVC @A+DPTR指令访问;
&&《51单片机C语言入门教程》,磁动力工作室,第六课 变量
一般需要严格控制变量读取速度的时候用data。例如变量更新速度很快,或者需要很短时间内读取或者修改的变量。一般容量要求大的,但速度并没有太大要求的,放在xdata里面。
如果所有变量都不加这些关键字的话,编译器会自动分配,但编译器的分配方案并不一定是最好的。而且一般都不会非常合理。
Q6:void timer() interrupt 1 using 2是什么意思?
注:关于&中断&的详细学习放在 第二节:51单片机相关
A5:关键字interrupt表示这是一个中断函数,具体的书写格式为:
void 函数名() interrupt n [using m]
首先需要注意的是中断函数没有参数传递其无返回值。n表示中断源,m为单片机工作寄存器编号。[using m]为非必须内容。在设计中断时,尽量让中断函数做少量的工作,这样中断服务时间短,系统可以及时的响应其他中断。有些系统如果丢失中断或对中断反应太慢将产生十分严重的后果,这时有充足的时间等待中断是十分重要的。
89C51单片机的中断系统有5个中断源,2个优先级,可以实现二级中断嵌套。(中断服务进行中再进行一次优先级更高的中断)
所以n的取值为0,1,2,3,4共5个,对应了5种中断源,这5种中断源可以分为三种类型:外部中断,定时器中断,串口中断。
w0:外部中断0(INT0)
w1:定时器0(T0)
w2:外部中断1(INT1)
w3:定时器1中断(T1)
w4:串行口中断(RX/TX)
m的取值有0,1,2,3共4个,它涉及到中断的优先权,如果用不到二级中断,using m可以不加,系统会为你自动分配。如果加可能会导致不必要的冲突。
Q7:如何写一个1ms延迟的函数?
A6:在写函数之前首先要认识到,假如采用for循环,则循环一次所花费的时间是多少?这就涉及到单片机深层的概念:机器周期。而单片机的机器周期并不是最小的周期,在计算它之前还要了解一下其他几个周期的定义:
w晶振频率OSC:单片机的最小系统中有一个晶振,它能够使得CPU跑起来,这个晶振为单片机的CPU提供主频。这个晶振的频率就称为晶振频率(外加频率)。
w时钟周期Tc:又称为&震荡周期&,它等于晶振频率的导数。这是最基础的周期。
w机器周期Tm:1机器周期 = 12个震荡周期;单片机复位至少需要两个机器周期的高电平。
w指令周期Ti:执行一条指令所需的机器周期数。1指令周期 = 1、2、4个机器周期;
&Y一条赋值语句(j = 0)2个机器周期,j是unsign char类型;
&Y一条判断语句(j & 1)4个机器周期,j是unsign char类型;
&Y一条自增/减语句(j++)1个机器周期,j是unsign char类型;
&Y一条空语句(循环体内)1个机器周期。
晶振频率OSC
11.0592 MHz
12.0000 MHz
9.04225e-5 ms
8.33333e-5 ms
1.08507e-3 ms
1.00000e-3 ms
假如采用for循环,例如for(j=X;j&0;j--){ }; 这行代码有X个循环,每次循环有一条判断语句(j&0,4Tm),一条空语句({ },1Tm),一条自减语句(j--,1Tm),略去第一个循环的赋值语句(j=X,2Tm),共6X个机器周期。略去最后一次的判断语句(j=0时,4Tm),若要延迟一秒,只需令6X*Tm = 1,当采用12MHz的晶振时,X & 167。被略去的语句达6Tm,刚好等于一次循环所耗费的时间,所以对X进行X=X-1的修正,最终可得:X & 166。
这里讲的是j为char类型的变量,它最大只能取到255,所以要获得更大的延时,需要用到int类型。前面也学到int类型是16位的,而单片机是8位的,所以这会更加复杂。
下面给的两个延时函数。这里多说一句:我查阅网络资料发现延时1ms的程序不尽相同,甚至相差很大,如果你需要非常准确的延时,推荐你参考正规的教材或采用其他方法比如计时系统。
两种晶振的单片机,延时1ms的函数
11.0592MHz晶振
void delay_ms(unsigned int i){
& for(;i&0;i--)
& & for(j=114;j&0;j--);
void delay_ms(unsigned int i){
& for(;i&0;i--)
& & for(j=123;j&0;j--);
这种方法也有很大的缺点:延迟过程中,CPU被占用,无法进行其他任务,导致系统效率降低。延迟时间越长,该缺点便越明显,因此软件延时只适用于短暂延时,或简单项目。
Q8:经常看到TH0与TL0,例如TH0 = 0xD8;TL0 = 0xEF;这起什么作用?
A6:从上面的学习可知TH0与TL0是与定时器/计数器有关的SFR寄存器。这两句的含义是给定时/计数器赋初值,寄存器会按固定的时间间隔累加,当寄存器的值达到最大时会触发中断,这时可以利用中断函数进行一系列操作。而计时T就等于时间间隔*(最大值 & 初值)。大概就是这个意思。
二、51单片机相关
Q1:单片机的引脚电压是多少?它的电压是由谁控制的?
A1:单片机的引脚有两种电平:高电平与低电平。高电平的电压与单片机的工作电压有关,一般有5V和3.3V两种。低电平一般为0V。
P0,P1,P2,P3又称为并行I/O端口,它的输出/入是双向的:当其作为输出时,单片机可以通过程序指令控制其为高电平1还是低电平0;当其作为输入时,单片机可以检测其是高或低电平,例如扩展了红外寻迹模块,对应的引脚的高低电平由红外模块控制,低电平0代表红外光被反射并被接收管接收,高电平1代表红外光被外界(黑线等)吸收。
P1称为端口,P1.1称为P1端口的引脚,这两个概念之间的关系就是&整体&与&个体&的关系。&
Q2:P3口的8个引脚有哪些复用功能(第二功能),默认开启吗?
当复用功能没有开启时,P3可以做为普通I/O口使用。一般情况下,复位后第二功能都是关闭的,需要设置对应寄存器才能打开。
&YP3.0 RXD 串行输入口
&YP3.1 TXD 串行输出口
&YP3.2 INT0 外部中断0输入口
&YP3.3 INT1 外部中断1输入口
&YP3.4 T0 定时器/计数器0外部时间脉冲输入端
&YP3.5 T1 定时器/计数器1外部时间脉冲输入端
&YP3.6 WR 外部数据存储器写脉冲
&YP3.7 RD 外部数据存储器读脉冲
问题解决1:程序通过USB口无法烧入单片机
我的单片机插座要用一个USB转TTL设备才能从电脑上给单片机烧程序,当时我就在P3.0和P3.1上连了其他模块,结果每次下载都失败。后来我才明白TTL插口是和单片机上的RXD,TXD连着的,下载时是开启了它们的复用功能的。
Q3:我的程序编译后生成的HEX文件超过了8k,烧进单片机不会有问题吗?
A3:HEX文件不只包含了实际的操作指令,还包含了地址代码,这个文件是为了易于下载器的理解。真正下载到单片机上的并不是HEX文件,参考下面的链接,给单片机烧入160+K的HEX文件仍然没有问题。
问题解决2:Keil生成超过8K的HEX文件会报错,提示Target
not created
这是因为你所使用的Keil没有经过注册,需要注册一下就可以生成超过8K的文件了。至于如何注册这里就不多说了。
注意:如果真的是代码量超过所选单片机的容量(STC89C52RC的容量为8K),那么编译器在生产HEX文件时会提示 xxx code limit 之类的。
Q4:为了写中断程序,我需要详细了解一下中断系统。
A3:CPU在处理某一事件A时,事件B请求CPU迅速去处理,CPU暂时中断当前工作A,转去处理事件B,待CPU将事件B处理完后再返回继续处理A事件,这一过程称为中断。在这之中有几个专业名词需要解释一下:
w中断发生:事件B请求CPU迅速去处理;
w中断响应:CPU暂时中断当前工作A;
w中断服务:CPU转去处理事件B;
w中断返回:CPU再返回继续处理A事件;
w断点:程序A被中断的地方;
w中断源:引起CPU中断的根源。断源能够向CPU提出中断请求;
中断系统的结构如下图所示。
w第一列解释:INT0:外部中断0,INT1:外部中断1,T0定时器中断0,T1定时器中断0,RX、TX:串口中断(包装在一起的)。中断引起原因如下:
&YINT0:P3.2引脚低电平或下降沿信号;
&YT0:定时/计数器0计数回0溢出;
&YINT1:P3.3引脚低电平或下降沿信号;
&YT1:定时/计数器1计数0溢出;
&Y串行通信完成一帧数据发送或接受引起中断。
w第二列TCON解释:该列的第二列代表了五种中断源的中断标志,所谓中断标志就是&中断请求的标志&,CPU要进行中断服务,首先要判断中断请求标志,再判断中断使能标志是否Enable,最后才会响应这个中断。&&
&Y对于外部中断,当中断到来时(引脚的电平发生变化),硬件会自动将中断标志置为1;而对于计时器中断,中断标志的值是可以认为修改,所以可以利用这一点进行人为中断(通过软件/程序),可以达到计数、时钟累加、自检、扫描等目的。
&外部中断需要外部条件触发,计时器中断不用。
&Y需要注意的是,无论是机器中断还是人为中断,在中断服务完成后机器并不一定会清除该中断标志位(不同的MCU情况不同),所以为安全起见,我们一般利用程序清除。
&Y外部中断的中断标志前(第一列)各有两个开关,对应了外部中断的两种触发方式:当IT0/IT1=0时,选择为低电平0触发;当IT0/IT1=1时,选择为下降沿触发(从高电平1过渡到低电平0的过程)。这两种触发方式有不同的效果,低电平可以持续一段时间,而电平下降却是一瞬间的事,所以两种触发方法在延时效果上不同。
w第三列IE解释:IE代表中断允许/使能寄存器,它控制了所有中断的开放和屏蔽。共有两列开关,EA是总开关(EA=1时,第二列的5个开关全部闭合),第一列的5个开关:EX0、ET0、EX1、ET1、ES分别对应了第一列的5个中断源。
&Y如需开启INT0中断,需要将EX0与EA都合上,即EX0=1;EA=1;
w第四列IP解释:中断优先级控制寄存器。其中IP.7、IP.6与IP.5为保留位,其他位(PS=IP.4, PT1=IP.3,
PX1=IP.2, PT0=IP.1, PX0=IP.0)值为1时表示对应中断源具有高优先级,值为0表示其具有低优先级。
&Y若这5个中断源被设置为同等优先级,则按自然优先级排序依次执行中断服务。如下表所示:
89C51单片机的中断优先级有三条原则:
1、CPU同时受到几个中断时,首先响应优先级别最高的中断请求。
2、正在进行的中断服务不能被新的同级或低级的中断请求所打断。
3、正在进行的低级中断服务能被高级的中断请求所打断。
CPU响应中断的条件:1、中断源有中断请求;2、此中断的中断允许/使能标志为1;CPU开总中断(EA=1)。
程序示例1:蜂鸣器滴两次、进入中断服务&&数码管显示8,延迟1秒后熄灭。
#include &AT89X51.h& //预处理命令
#define Led&&&&
P0&&&& // 定义数码管显示端口
#define Buzz&&&
P2_3&& // 定义蜂鸣器的端口
// 11.0592M的晶振延迟1ms。这个函数要放在Buzz_didi的上面,否则会报错。
void delay_ms(unsigned int i){
&&& unsigned int
&&& for(;i&0;i--)
for(j=114;j&0;j--);
// 蜂鸣器发出滴滴声
Buzz_didi(){&&&&&
&&& Buzz=0;
delay_ms(100);
&&& Buzz=1;
delay_ms(300);
void main(){
1;&&&&&&&& // 打开总中断开关
1;&&&&&&&& // 开定时器中断0
&&& while(1){
Buzz_didi(); // 蜂鸣器滴一次
Buzz_didi(); // 蜂鸣器滴两次
TF0 = 1;&&&& // 定时器中断0的中断标志置1
// 中断函数一般放在main函数的下面
void LED_Show8() interrupt 1{
0x01;&&&& // 数码管显示为8
&&& delay_ms(1000); // 延迟1秒钟
0xFF;&&&& // 数码管不显示
//&&& TF0 =
0;&&&&&&& // 定时器中断0的中断标志置0
Q5:为了理解某段程序的作用,我需要详细了解一下计时/计数系统。
A5:单片机中有多个小闹钟(T0,T1;52单片机还有一个T2小闹钟),可以用来计数、定时等。它们的结构图如下
w定时/计数器0,T0,它的触发引脚为P3.4,计数器为8位寄存器TL0和TH0,用于存放数值,TL0是低八位,TH0是高八位。当低八位计数满了之后会向高八位进一位。对于T1同理。
w配置寄存器TCON:控制寄存器,控制T0、T1的启动和停止及设置溢出标志,与之相关的sbit由TF1、TR1、TF0、TR0;T2CON是T2时钟的控制寄存器,52单片机才有。
&YTF0、TF1是溢出中断请求标志为,详细参考&本节 Q4:为了写中断程序,我需要详细了解一下中断系统。&
&YTR0、TR1是运行控制位,TRX=1时,TX开始工作;TRX=0时,TX停止工作。TRX由软件置1或清0,所以可以用软件控制定时/计数器的启动与停止。
w配置寄存器TMOD:定时/计数器的工作方式寄存器,用来确定工作方式(M0和M1)和功能(GATE和C/T)
&YC/T:定时器或计数器功能的选择位。C/T=1时为计数器,通过外部引脚P3.4或P3.5输入计数脉冲,这样可以设置外部时钟源,不过比较复杂一般不用;C/T=0时为定时器,由内部系统时钟提供计时工作脉冲。,加1计数器的计时间隔为1个机器周期(计数频率为晶振频率的1/12)。所以定时时间T = 计数值N * 机器周期Tm。
&YGATE:门控位。当GATE=0时,只要用软件使TCON中的TR0或TR1为1,就可以启动定时/计数器工作;当GATE=1时,要用软件是TR0或TR1为1,同时外部中断引脚为高电平时,才能启动定时/计数器工作。我们一般让GATE=0。
T0、T1定时/计数器可以在四种方式下工作,由M0和M1的取值来确定。
方式1,以T0为例:定时/计数器0的实质是的由计数脉冲触发的按递增规律(即累加方式)工作的循环累加计数器,这个寄存器是16位的,由高八位的TH0与第八位的TL0组成。从预先设定的初始值开始,每来一个计数脉冲(时间间隔固定)就加计数器1,当TL0溢出后,对TH0进位,当TH0溢出后,TF0会被硬件置1,从而发出中断请求。
&Y溢出:当计数器的每一位都是1时,对计数器再加1就会溢出,结果就是计数器的每一位都回0。
&Y计数值N = 溢出时计数器的值() - 计数初值X
&Y当TF0=1时,cpu可以不做响应。学习了后面的中断系统后就会知道,cpu对中断做出响应需要两个判断条件,另外一个就是开启中断使能标志:EA=1;ET0=1;
Q6:如何用定时/计数器进行1ms的延迟?
A5:定时器的操作步骤(下面的X代表0或1):
w选择工作方式(设置M0,M1),这里选用方式1,即M0=1;M1=0;;
w选择控制方式(设置GATE),一般设GATE=0;;
w选择定时器还是计数器模式(设置C/T),一般采用定时器模式即C/T=0;;
w给定时/计数器赋初值(设置THX和TLX),注意结合一下两个公式:
&Y计数值N = 溢出时计数器的值() - 计数初值X
&Y定时时间T = 计数值N * 机器周期Tm = N*12 / 晶振频率
n如果频率的单位是MHz(兆赫兹),则时间的单位为us(微秒)
&Y计算出初值X后将其转化为16进制,THX就等于前2个数,TLX就等于后2个数。或者将其转化为10进制,它除以256的商为THX,余数为TLX。
w开启定时器中断(ETX=1;);
w开总中断(EA=1;);
w打开计数器(TRX=1)。
程序示例2:定时器的配置
void TimerConfiguration(){
0x01;& // 定时器0选择工作方式1
TH0 = 0x3C;
TL0 = 0xB0;& // 设置初始值
1;& // 打开总中断
1;& // 打开定时器0中断
1;& // 启动定时器0
程序示例3:蜂鸣器持续滴滴,利用定时器完成Nms的延时,进入中断服务&&数码管显示8,延迟1秒后熄灭。
&AT89X51.h&& &//预处理命令
Led&&&& P0&&&& // 定义数码管显示端口
Buzz&&& P2_3&& // 定义蜂鸣器的端口
// 11.0592M的晶振延迟1ms。
delay_ms(unsigned int i){
for(;i&0;i--)
for(j=114;j&0;j--);
// 初始化定时器0
TimerConfiguration(){
延迟1ms的计数N的精确值为921.6,这里舍入为921
以计数的方式,一次性最多可以延迟70ms
&&&&&& TMOD
= 0x01;& // 定时器0选择工作方式1
&&&&&& TH0
// 设置初始值
&&&&&& TL0
= ()%256;& // 设置初始值
&&&&&& EA&
= 1;& // 打开总中断
&&&&&& ET0
= 1;& // 打开定时器0中断
&&&&&& TR0
= 1;& // 启动定时器0
unsigned int
count = 1; //用于计数
void main(){
&&&&&& TimerConfiguration();
&&&&&& while(1){
&&&&&& &&&
Buzz=0; delay_ms(100);
&&&&&& &&&
Buzz=1; delay_ms(200);
// 中断函数一般放在main函数的下面
void inter_t0()
interrupt 1{
&&&&&& count++;&&&
//中断一次(1ms)计数加一
&&&&&& TH0
// 设置初始值
&&&&&& TL0
= ()%256;& // 设置初始值
//TF0 = 0;&&& // 定时器0的中断标志置0
&&&&&& if(count&1000){&
// 延迟1000ms,这里可以修改为Nms
&&&&&&&&&&&&& count
= 1;&&&&& // 重置计数
&&&&&& &&&
Led = 0x01;&&&& // 数码管显示为8
&&&&& delay_ms(1000);& // 延迟200ms
&&&&&&&&&&&&& Led
= 0xFF;&&&& // 数码管不显示
从程序示例1与程序示例3的对比可以得出以下结论:
l利用定时器中断有两种方法,一种方法只需将定时器0的中断标志置1(TF0 = 1;即程序示例1),另一种方法需要开启定时器0(TR0 = 1;即程序示例3)
l利用定时器进行延时,这个计时进程与main进程是并行的。
l无论采用定时器延时中断还是手动中断,中断服务与mian进程总是串行的。
l改程序的测试结果表明:有时候,当数码管显示8时,蜂鸣器是静音的;而有时候,当数码管显示8时,蜂鸣器在一直鸣响。这说明两点:
n定时器中断可以中断函数类型的延迟。
n单片机在服务中断的时候,既定的事实不会发生变化。也就是说若中断发生在蜂鸣器响的中间时刻,则蜂鸣器会一直响下去,直到中断服务返回。
Q7:单片机的有好多特殊寄存器,我需要总结一下他们的名称及用途
A6:关于8051单片机特殊功能寄存器的说明,可以查阅:
为防止链接失效,这里给出文件名:《8051,STC89C52单片机特殊功能寄存器》
下面给出第一页的预览图:
阅读(...) 评论()

我要回帖

更多关于 单片机晶振 的文章

 

随机推荐