




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、C51单片机步步学笔记(最新更新)作为一个初学者,如何单片机入门?我需要那些知识和设备?知识上,其实不需要多少东西,会简单的C语言,知道51单片机的基本结构就可以了。一般的大学毕业生都可以了,自学过这2门课程的高中生也够条件。设备上,一般是建议购买一个仿真器,这样才可以进行实际的,全面的学习。日后在工作上,仿真器也大有用处还有,一般光有仿真器是不行,还得有一个实际的电路,即学习板。学习板一般价格都比较贵,而且许多学习板配套程序和讲解不够完善。这里介绍的是最简单的学习板,4个按键加4个LED发光管,一个蜂鸣器,一个24c02即可。通过30个教程,初学者可以学到:单片机控制外部设备,读取外部设备状
2、态,外部中断的应用,中断的深入理解,变量和标记的灵活应用,定时器的灵活应用,可编程自动控制的方法,按键控制设备动作的方法,PWM输出的设计,存储器的读写,延时报警器的设计,各种报警音的设计,音乐播放的设计,程序模块化的设计等等知识。虽然,这些知识的覆盖面有限,但是,当你学习并掌握了这30个试验之后,您就会豁然开朗,单片机的编程控制如此简单!学习完后,您就已经完全地入门了,并可以自主地对其它的单片机知识进行学习、试验,甚至进行项目开发!第一课了解单片机及单片机的控制原理,控制一个LED灯的亮和灭本章学习内容:单片机基本原理,如何仿真器,如何编程点亮和灭掉一个LED灯,如何进入KEILC51uV调
3、试环境,如何使用单步,断点,全速,停止的调试方法单片机现在是越来越普及了,学习单片机的热潮也一阵阵赶来,许多人因为工作需要或者个人兴趣需要学习单片机。可以说,掌握了单片机开发,就多了一个饭碗。51单片机已经有30多年的历史了,在中国,高校的单片机课程大多数都是51,而51经过这么多年的发展,也增长了许多的系列,功能上有了许多改进,也扩展出了不少分支。而国内书店的单片机专架上,也大多数都是51系列。可以预见,51单片机在市场上只会越来越多,功能只会越来越丰富,在可以预见的数十年内是不可能会消失的。下面以51为例来了解一下单片机是什么东西,控制原理又是什么?在数字电路中,电压信号只有两种情况,高电
4、平和低电平,用数字来记录就是1和0。单片机内部的CPU,寄存器,总线等等结构都是通过1和0两种信号来运作的,数据也是以1或者0来保存的。单片机的输入输出管脚,也就是IO口,也是只输出或识别1和0两种信号,也就是高电平和低电平。当单片机输出一个或一组电平信号到IO口后,外部的设备就可以读到这些信号,并进行相应操作,这就是单片机对外部的控制。当外部一个或一组电平信号送到单片机的IO口时,单片机也可以读到这些信号,并进行分析操作,这就是单片机对外部设备信号的读取。当然实际的操作中,这些信号可能十分复杂,必须严格地按照规定的时间顺序(时序)输入输出。每种设备也都规定了自己的时序,只要都严格遵守,就可以
5、控制任何设备,做出只要你想象得出的任何事情。您可能会再问,我如何让单片机去控制和分析外部设备呢?答案是程序,您可以编写相单片机在上电时,就会一步一步按照关的程序,并且把他们烧写到单片机内部的程序空间,您写的程序去执行指令,做您想做的事情。在51标准芯片中,有32个输入输出IO,分为4组,每组8个,分别为P0口,P1口,P2口,P3口。P1口的8条脚就用P1.0至P1.7表示,其余类似。51就是用这32个口来完成所有外部操作的。对于51的内部结构,如果您已经了解,那是最好;如果不懂,也可以先放下,在完成了本教程开始的几个章节之后,您就会大有兴趣,自己去寻找资料阅读了。当然,如果您希望成为一个优秀
6、的单片机开发程序员,还是必须熟悉单片机的内部结构及工作原理,切不可偷懒!在这一章,您将用程序去控制一个LED发光管的亮和灭。你应该知道,LED发光管在通过一定电流时亮,不通电就灭。为了不让LED通过太大的电流把它烧坏,我们还要串上限流电阻。51的IO是弱上拉的方式,在输出高电平时,只能输出几十微安的电流到地,而在输出低电平时,VCC电源可以输入几十毫安的电流到IO。一般LED需要10毫安左右电流点亮,我们就将LED接在电源VCC和IO口之间,中间串上电阻,当IO输出低电平时,灯就亮了,反之,灯就灭了。我们在这个程序里要控制的是P1.0。请参考一下我们将要使用的试验板的电路图。上一 n n* _
7、 7:?.M在实际的单片机学习和开发中,i可以用仿真器模拟一个CPU芯片,让它按照您编写的程序工作,并且进行调试,一步步排除程序的bug,使程序正常工作。程序工作正常后,您就可以用烧写器将您编写的程序烧入购买来的单片机芯片中,让它自己去运行了。要使用仿真器,还得有一个编译调试的环境,这个环境是在计算机上运行的,我们就在计算机上编写和调试程序,计算机和仿真器有连接,仿真器中的各种数据和程序,都可以从计算机上观察到,并可以观察变量,写入变量的值,单步调试程序,在程序中设置断点调试,全速运行,停止程序运行,等等操作。我们使用keilC51编译调试环境,仿真器的选择太多了,你可以根据自己的实际情况来选
8、择。随后我将给大家提供keilc51相关的中文说明资料,这些资料详细地说明了如何使用C51编程和如何使用keiluV2环境调试。现在可以开始做试验了,我们打开已经建立好的工程和编写好的程序试验。顺便还会学习一下程序调试的技巧。至于如何建立一个新工程,请参考C51的帮助文件。请双击lessoncode01目录下的lesson1.uv2,打开后界面如下:点一下上图第三排第2或者第3个按钮(您的编译器按钮位置不一定在那个位置,自己找找),就可以看到编译结果了。上面显示是0errrs,0warnings,这是最佳的编译结果,如果有error,则无法进行下一步仿真,如果有warning,一定要尽量消除,
9、确实无法消除的,也要确认不会对程序造成影响,才进行下一步的仿真。在编译结果中,我们还可以看到有data,xdata,code等用了多少字节的报告,要注意您的单片机中是否有这么多的资源,如果不够,将来烧片运行时就可能出现问题。比如AT89C51的程序空间是4K,xdata如果没有外扩就是0个,data是128个。超出这些范围,程序就不能在AT89c51中运行。不同的芯片有不同的容量,如SST89E516RD就有64K程序,内部768字节XDATA,还有256个字节的data。我们的例程中肯定都考虑了这些了,肯定不会超出,将来自己开发时就要注意了。下面我们故意把第9行的P10写成P11,点编译,因
10、为没有预先定义P11,所以就报告错误了,如下图:双击一下错误报告的那一行,窗口就也会跳到这一行,方便您进行修改。好了,现在请把错误改回去,再编译一次,出现报告正确了以后,下面开始仿真了。点一下第二行第5个一个放大镜里面一个d字母的按钮,就可以进入仿真了,仿真器要事先连接好哟。进入仿真后要退出仿真环境也是点这个按钮。注意,等会如果程序在正在全速运行时,仿真环境是不能直接退出的,得先点停止运行后,再点仿真按钮才可以退出。点进入仿真按钮,程序开始装载,PC自动运行到了main()停下,并指向了main()函数的第一行。进入仿真窗口后,如果出现的不是前面的源代码窗口,而是夹有反汇编代码的窗口,直接关掉
11、这个窗口就会恢复到代码窗口。下次进入也会直接进入到源代码窗口。现在先试验单步,点单步(两个单步都可以,一般点单步跨过)。可以看到灯亮了。PC指针也指向了下一个程序行。再点一下单步,PC又走下一步,灯灭了。再点一次,PC走到挂起的程序行了,继续点仍然在这一行。这句指令其实就是使程序不断地跳到自己这一行,别的什么也不做。一般称作程序挂起。一般的实际应用中的程序是不会挂起的,一般是在main函数里做一个大循环,程序如下:voidmain(void)/主程序while(1)P11=0;/亮灯P10=1;/灭灯请将main函数程序改为上面的代码,我们下一步将试验断点的操作。在第15行双击一下,可以看到程
12、序行左边出现了一个红方块,这就是设置断点,再双击一次,断点就取消了。如果程序在全速运行的过程中遇到断点,就会自动停下来给你分析。注意在进入仿真后,并且程序是停止状态时,才可以设置或者取消断点。g冒:le e« 好 PKijict 占y 引醇力p可2值4 k。= 好口 纱s* Heph.MKI:芭窿图同£电IA 二,"y % .£哨I三1 M .:#*” 旧1国画, n x|独趣幽眄rKrrMR HLII:悝团*;当廖产.。手;:,伸ff±-1'Ui(i misi niftd mt。由寸 Lt a uloRC Hun 我lore«
13、;mclude CrBS5P.)O"隹百一个印师市向弑国土文件fibLl FLO二Pl*。,"受三件中度者走戈用心靛要自己来走发了char co* dxE】53 it QkCU二h ;,:V事F £ 耳其煮口voidT f? 7I*i】M力F般序褶“心Fmtq寺叮 1方 I PIOzl. Jj"J J IJ现在点全速运行,可以看到程序在断点处停了下来,并且由于前一句指令刚刚执行了点灯,所以这时灯是亮着的。现在在第14行设置断点,并且取消上一个断点。现在点全速运行,可以看到程序在断点处停了下来,并且由于刚刚执行了灭灯,灯是灭着的。好,现在试验全速运行和停止
14、。把断点取消,再点全速运行,可以看到灯是亮着的,但是不是很亮,这是由于程序是循环的,亮灭交替进行,亮的时间并不是全部的时间。现在点停止,可以看到程序停止了,重复几次进行全速和停止,可以发现每次停止的地方不一定是同一位置。第二课用指令方式延时闪烁LED灯本章将学习如何使LED闪烁,和如何查看变量的值。单片机内部的CPU工作都是要靠时钟驱动的。在标准51芯片中,每个指令周期是12个时钟。所以只要外部时钟固定,某一条指令运行的时间也是固定的。比如本试验中的单片机晶振振荡输出的时钟是HZ,一条单周期指令执行的时间就是12/秒=5.425347X107秒,这样如果你想在程序里延迟一段时间,就可以用循环执
15、行多少条指令来实现。这是一个最简单的延时方法,优点是不占用其他的单片机资源,缺点是不容易计算准确延时时间,而且延时过程中CPU无法做其他工作。指令延时方法一般用在一些不用精确计时的场合。在需要精确计时的场合,需要使用定时器,在之后的课程中将会学到。程序由一个循环组成,在点亮 P10 口的LED之后,延时一段时间,再灭掉 LED,又 延时一段时间,之后循环到前面。for ()循环后面直接一个分号,表示这个循环里面什么C写法。事情也不做,就等循环完成指定的次数就退出来。这也是指令循环延时的最常见的编译后,按进入仿真。按全速运行,可以看到P1.0的LED灯不断地闪烁。下面我们用另一个更简单的方式点灯
16、,就是取反IO口的状态。取反指令将当前bit变量的状态反转,当前是1,取反后就是0,当前是0,取反后就是1。IO口相当于一个bit变量,也可以这样取反。请修改程序如下:出隹31-小同赢71需01士枇F才尼ik】依广心:区zigned出自i7W'一下方传林.电口:*dfinuuintunsignedibnt-三Ttlrfireillfltilone口sinclude<iei62.h>“包楮一T5游准内樵的头经件u*WgtFl口Pl'。;/佚式件轲曼村定义的m就要自己东走M雕显晶翳产迷SrQBU;“这是为了仿其收量的jo±liiiriiyci-dj,>&
17、#39;ii.TLkiMtvtii1c1-5/将Jt-后试!F1XT4。:“取反tfc?阳n团用f-:ri#:;r<2QGOO:Ki)可以看到旁边出现了一个小框框,上面显示了n=0x47D3,这就是变量此时的值。如果觉得Fr口gram31。日;d同匕&3口国coJeSScrftT111_3h*KFilstrf1IRssnn"",.,hl»«EQEilM-0Error(r),0warning(g)«,ll*卜4.3rnd,FifidinFfef11'-:!?-编译成功后,再点全速运行。同样可以看到LED闪烁的现象。可以看到,
18、这种方法,我们只需要一次延时,就可以实现闪烁了。下面我们再来学习如何查看变量n在运行中的值。注意,要查看变量的值,只能在程序停下来的状态下查看。在程序运行的过程中,程序不断地运行,变量也在不断地变化,一般是无法查看的。点停止程序,将鼠标放在程序中的“n”上面。这样可能会点不准确,可以选中你要看的变量,同样会显示变量的值,个人感觉这种操作更为方便。如图:需耳曲tr)-uOgpk 1 Ilf ItL- B.pJ .L&gistcr卜,4_Liu三氐*交LhtUD"rl%*2QWr3OOJm""" r-4.JrOO- r5fcDO54T3打工一.马口油
19、i- tEhiDD, ,灯DkOTdj?Lrre $匚:口&,国 IWWMttiOTMm w M aDewoeM M1 lM1aM1017ielefI It I'iiJcTingUFLi ci at ft虐in*udrisig,n-d-iriE-ludE Ce cyh2. h>在h pio - rro:"人文件事没存疣义田皿旅w日lctiar C3de ciE L t5 3 it CsEdb ;/江是涉 了优其黄之/Wfjftfr:rniil nir Cvo3(D ,: ,I'序Hint rr"wiu_lq c i/7辕件徉科jnsSOtCU
20、= 日第(11I上勺匚门a d "r j WLiQiCUTnpTit Hindt 】qgqrX口日见 itii qtjr外t"十泉面zISI*?i5S:3W Br*akDiciblo BmaikEiimkln BrakKil BraakListP,( rki.l ) ,1 .HG rl >1S _l - - M 17 I r -LL;LoCir在命令行输入的方法也可以看变量,在命令行输入n,回车,就看到结果了。请注意看卜图的命令行窗口的结果。中相nt.但国营号二上阳尸l_:Si sLerp- S-如口i-OLtriOO门鼐0 J-3OhiOJ-g: r4mg tSLh
21、iHf同一0>id3A" SyS五31_二-町 taOTT箱=1 ?i Fr 11Fwiecil wotpKcTm-etY PU fP1飞:人二阡甲涓耳.二史的加就要日已勾ai gds dxblM的 就 0«0031»捱是苦了帕羡也 门/灯社即2VI: j.rl j-tarr. t'c ui J) 匚/ I :同值,工口也富mf nr lr-11 I 71<?U1U Iumt n;Huhn.叮广平律圻卡叼14中I方I.ElCoK.nfrstad to Hofitor 52 V.&KLo±d "口亦703C: 5orL
22、in-nts. and Xt ting,“枭而立】NLi : t=1、嵬茴一打iririKB j 1Fi H ira pl=5 L L+UJ这里再教一招,如果我想让n现在就变成我想要的值怎么办?这也是调试常见的手段,设置一个变量的值,比如,让n=0x1234,只要在命令框里输入“n=0x1234”就行了,几乎所有变量都可以这样直接设置,包括IO,比如你输入“P1.1=0”结果第二个灯就亮了。还有一招常用的,就是在watch窗口看变量。点watch图标,就是那个有个眼镜的图标,打开watch窗口。如图:这个窗口里有locals页就是当前函数使用的变量的列表,还有有watch1和2两个窗口,就是自
23、定义要看的变量的值,可以手工输入,也可以选中某个变量,按右键,将出现一个菜单。选择add到watch窗口即可,在程序停止时随时看到此变量的值。注意要看某个变量,如果这个变量是某个函数私有的,必须是程序停止时并且PC已经停止在了这个函数中才可以看到,各种看变量的情况都是这样。还有一种直接看存储器的方法,可以看到所有存储器的值,但是和变量名称就不是那么好对应起来了。点memory窗口图标,打开memory窗口,如图:(8S iEi©初行田pgpct Mur 心 pax .口三u |归I国|cc ;,、-UI 口叱“PU三F1飞:7头友伴中尊连史的M嗷JF自已勾 char 皿 dxblb口
24、1 或 吮00时;"这另为了衡宜皆于 门了可斤不一nai±i(v«iD "uint n;郑馨修辞plo=Ti口;"取房糕 tot (f. k" 2j00J.r-H-. .1iS 国 am.3 n. cD-版口: D:OkOF: D: Ok. IE:口! 口支孙 D:Dk.4B1 ::'X :_D D E I- C D n 1- n- D u r- -I -L I -I- I o o o o o o o 口口 口力0 Q 0 Lecce t -L o o o o D o _u 1noe 口 口口 .LOCCDCC o o o o
25、 o o o ,u o o o o o o L o c c o o _L 3 o D c _u o c o o o o o o D 5 c n- c o n- c F o o o _u o o 2 0 0 0 0 o o D o D o D o o 7 D D D u D D 4 o n D D D D n D D Do Do u D D c o Do o D D D D D D D D D c D Do D D D c D D 3 n D o 口口 L o c D o D £ o D D D o D _u o D D D o Do , D D D D .上:q在Address窗口输
26、入:“d:0x00就可以看到data空间的从0x00开始的所有内存。如上图。输入“i:0x00就可以看到idata空间的所有内存的值。输入“x:0x00,“就可以看到xdata空间的所有内存的值。输入“c:0x00,”就可以看到code空间的所有程序。在实际的硬件调试方式中,如果不用看memery窗口,就建议不用打开它。因为保持它的打开会增加仿真时通讯的时间,特别是单步运行的时间。这一章就完成了,我们学会了,指令延时,取反的用法,还有更重要的就是如何在keil调试环境中查看变量。第三课跑马灯试验在本课中,你可以学习到几乎所有单片机试验课程都会介绍到跑马灯试验。打开工程文件,如图:-I 93耐I
27、I二:Source 白口u j*'因 main.匚34537SQQ O 0 0 0 a O 1ffdefira uJong sjnsiened lent#通“1加。钝52h>外包括一个5 2际送内柠的头文件ja| =1 va 愀I 嘴2 X- 4 8 8 a 1 2 a 4 5 0 ? 8 111111112 2 0-222-52窗Kt F1Q = F1*O;"/文件1H受有定义的R就表自己未定文sbii Fl I = Pl'1;sti-t H2 = Pl *2;mh ris = pr-a;chai cade dx516 3 it _ 1:s口3b :"
28、;坟呈治了 值巨在甘B./;跳马灯程序void t.aiii(void) / 王桂挣uint ii'whilo. (1) /程一德环(P13=l T1D=O:icr (n.=0 ,n<400004 r.+4);F1D=1;Pl1=0;工”林二。;弹"QUUU ; r+0 ,Fll-1 T12-0 ;ter <n.=O ;n<1COOO; r.+->);P12=1;P13=Q;-frr(n=n :n<40BOD: n+J :1=1 mni4 sProgram Size:erecting hex* L&sson" - Udata-9
29、.Czdataa0code-1621&frart11lessor".,:rr-ors)rUWarning(s).这里实现跑马灯的方法是,依次灭掉前一个灯和点亮后一个灯,再延时一会,不断循环,就可以看到跑马灯的效果了。请在编译后,进入仿真,点全速运行看结果。好好研究这段代码,可以自己试着自己修改代码:例程中的跑马灯在同一时刻只显示1个灯,现在改为同时亮着2个灯的跑马灯。第4课读IO,用按钮控制点灯请看一下电路,今天我们要学习用单片机读取按键的值,并且使用一个按键K1去控制点亮P1.0控制的LED,用另一个按键K2去控制P1.1控制的LED。看电路图,K1是接在P32上的,K2是
30、接在P35上的。下面讲述一下识别按键的原理。在单片机中,我们可以读取某个IO的值。在51的IO口,如果处于输出1的状态(51上电后IO就默认为1),这时IO内部可以简化为有一个几十K的电阻上拉到电源VCC(P0除外),这时这个IO就可以作为输入脚用。P0是没有上拉的,相当于一个悬空的引脚,就是高阻状态,如果用P0,必须在外部接上拉电阻。我们这里用的是P3口的IO,内部有上拉。如果直接读一个没有按下按键的IO,就会读到1。如果这个按键按下了,这个IO就通过按键短路到了地。这是就会读到0。这就是读按键的原理。下面看程序:ProjectspicexE.ejgisterV.1三1通Q。二.j,gist
31、,.j.rrQ0.ri0.rZ0r30.r40.f50.r50.r70.El-Sysa0.b-dptr0.PC$CIt阵w0.g#include<rag52.h>/也括一+晓标带内载Q5Jtl口序sbitPIO=PTC:/要棒制的LED灯079sbLtKl=P3"2;"按镂Eh开灯用口口北汽X2=P3"5;"按键关灯用1口charcodedx5163_at0H口口劾:/J这是“了:为主4 4用?个按睫分别控制匚ED灯亮火12 voidmain(void)/主程序13 (恒vhile(l)/程序裾坏15 1伯ift!Kl)"如果读到K
32、1为上点灯17isF10=0.1920ifClK2)”如果读到K2为匕火灯2'F22P10=l;231勾】26卜20i;:7.;,*LbJ国芝格噂哥(:il编译,进入仿真,开始全速运行。这时可以实际操作一下,按下K1,灯亮;按下K2,灯灭。第5课标记的用法,用一个按键控制1个LED灯的亮灭,按键防抖动这一课,我们学习怎么用一个按键K1控制1个LED灯的亮和灭两种斗犬态。按一次K1灯亮,再按一次K1灯灭。再按一次又亮,再按一次又灭。我们学习一下用一个bit变量来做一个标记,然后在按键的控制下,这个标记会变化,再根据这个标记的值,LED也输出不同的状态。因为按键按下时可能会有抖动的情况,每
33、次按下时,可能会发生了人难以觉察到的多次抖动,相当于一下子按下了很多次。这会导致程序无法识别出您真正的按键意图。但是抖动一般都是发生在刚按下键和松开键的时候,所以,我们只要避开这一段时间,等键稳定按下或者松开时,再去读它的值,一般就可以正确读取了。所以,当读到第一次按键的值时,要延时等待一会,再处理。在松开后,也延时一会,免得检测到松开的抖动以为又有按键。(注,更复杂的应用,需要在按下延时之后重新验证按键,为了简化和方便理解,这个例程里没有这样做。)另外,因为程序是循环运行的,当一次按键处理后,又会再循环回来继续检测,如果您的按键这时还没有松开,又会被读到一次新的按键,并做处理。所以我们还要做
34、一个特殊的处理,识别到一个按键并处理完成之后,还要等待这个按键松开后,再继续循环运行。ETStiltcharru = pro;"贾护刮的lnk£1= pyz;7技健立 cods 43516 3 _t 出£口斯:。这标温的用总甫一下按蕊担用1小工藤void JiaiBL(voidJ ” 主程序5it 1 ight;,/ 位娈量UU上让 11.ihilrd)门程序福厂if (IKI)“如耳到口知口foi (nF0;n<lC00:nr); /伟诗为律稳京 liEht-"lighrt ;"萼徵臃一次,品已变化一波 vhileEIKJj:"
35、;等侍行键松F(由0 ;m2i CM; V等待帙髓特金也升1pikiiat,。直接把色变型赋信消l三工(请根据例程里的注释理解程序。请编译,进入仿真,全速运行,看结果。全速后,由于light变量初始化时默认为0,所以灯是亮的。按下K1,松开后,灯灭了;再按一次K1,松开后,灯灭了。这个例子里,我们只用一个按键就控制了灯的亮灭,这种方法可以节省了硬件资源,也就是节省了硬件成本。在实际项目设计中,有成本优势,产品就更具竞争力。所以我们应该多学习类似的可以节省资源的方法。第6课用定时器中断闪灯,定时器中断的学习在第二课,我们学习了用指令延时闪灯,但是用指令方式闪灯有cpu不能做其他工作的缺点。这一课
36、,我们将学习如何使用定时器方式使灯闪烁。中断的理解。这里将涉及到单片机中断的应用,在cpu的一步步按照指令运行的过程中(主程序),可能会有其它的更紧急的需要做的事情(中断服务程序),需要cpu暂时停止当前的程序(主程序),做完了(中断服务程序)之后,又可以继续去运行先前的程序(主程序)。就像你正在吃饭,一边又在给水桶里放水,吃着吃着,水满了,你就得赶快去把水龙头关掉或者换一个空的水桶,再回来吃饭。单片机的定时器就像是一个水桶,你让它启动了,也就是水龙头打开了;开始装水了;定时在每个机器周期不断自动加1,最后溢出了;水桶的水不断增加,最也就满出来了;定时器溢出时,你就要去做处理了;水桶的水满了,
37、你也应该处理一下了;处理完后,单片机又可以回到刚刚开停止的地方继续运行;水桶处理了,先前你在做什么也可以继续去做什么了。单片机的主程序是从0x0000开始运行的,单片机服务程序从哪里开始运行呢?在51里,有多个中断服务程序入口,0号入口是外中断0,地址在0x0003;1号入口是定时器0,在0X000B;2号入口是外中断1;地址在0x0013,3号入口是定时器2;地址在0X001B,等等。当中断发生时,程序就记下当前运行的位置,跳到对应的中断入口去运行中断服务程序,运行完之后,又跳回到原来的位置继续运行。在C51中,你不用理会中断服务程序放在哪里,会怎么跳转。你只要把某个函数标识为几号中断服务函
38、数就可以了。在发生了对应的中断时,就会自动的运行这个函数。请看一下相关的51的硬件的书,对定时器工作的寄存器设置做进一步的了解。也可以做完试验再了解,因为例程中都已经为您设置好了。Proj-scl WotiAdelineucLauursiEneddiacA'/i1'p:在中断服务函数内设置断点,再点全速。稍后就会停止在断点上,就可以继续单步运行了。如图:FTQjiCl WkhSfj0优- Xffdefins uirt unsierL&d ir.tLUU杵a分中工门守 ulur写 un?igrt*d LengAiluldde <±oE62 h;3但括一个&
39、amp;2标推泄川sbi+ Pio = pi n;"至桓前的工面灯方髓海翼崎与甑理春冬景康 wid JLiiiL Lvuid) Z/ 主桂,序T附由:gni /宅H-器n. IK拉丁作F式TS0=l EId=lEAl:南小"启动完".器“打了定时番。中断"小步总不断 “程序循环主程坪在小早就邛断自错邱,笑睥/1“走困会口中断ti n?r3 .) ir+ernpt 1/舞时器:中明星1三对心匚0; 丁二叱收 PlO-TlOi/F人走叫霸而蛤值二磔。阮选择每秒中断24次,每次溢出选择每秒中断30次,每次溢出1843200/24=768001843200/30
40、=61440选择每秒中断32次,每次溢出选择每秒中断36次,每次溢出选择每秒中断40次,每次溢出1843200/32=576001843200/36=512001843200/40=46080个机器周期,超出65536,无效。个机器周期个机器周期个机器周期个机器周期30次,每次溢出6从上面可以看到我们可以选择方式有很多,但是最佳的是每秒中断U0 09 1Q 11 12 43IO W 17 la20 :4 上工 33 4 252S2Q 二日 3Q si 32二二 M.1=1 mkin. c1440个机器周期。也就是赋定时器T2初值6553661440=4096,换成十六进制就是0x1000。从上
41、面的计算也可以看出晶振2118400Hz的好处,它可以整除的倍数多,要准确定时非常方便。更常见的应用是在串口波特率上,使用HZ可以输出最多准确的标准波特率。请打开程序,如图:在我们的这个例程中,前一课的1秒钟输出信号,被换成了一个全局标记。在主程序中去检查这个标记,再清0标记和处理相应的工作。这一课的跑马灯输出方式也改变了,我们采用查表的方式,将要点亮的灯预先设置好,到了时间,就一起送到P1口。这样,程序的执行效率会更高。下面请认真学习和分析例程:以下是例程,请打开lesson8目录的工程,内容是一样的。#defineucharunsignedchar/定义一下方便使用#defineuintu
42、nsignedint#defineulongunsignedlong#include<reg52.h>/包括一个52标准内核的头文件sbitP10=P1A0;头文件中没有定义的IO就要自己来定义了sbitP11=P1A1;sbitP12=P1A2;sbitP13=P1A3;bitldelay=0;/长定时溢出标记,预置是0charcodedx5163_at_0x003b;/这是为了仿真设置的/定时器中断方式的跑马灯voidmain(void)/主程序ucharcodeledp4=0xfe,0xfd,0xfb,0xf7;/预定的写入P1的值ucharledi;/用来指示显示顺序RCA
43、P2H=0x10;/赋T2的预置值0x1000,溢出30次就是1秒钟RCAP2L=0x00;TR2=1;/启动定时器ET2=1;/打开定时器2中断EA=1;/打开总中断while(1)/主程序循环if(ldelay)/发现有时间溢出标记,进入处理ldelay=0;/清除标记P1=ledpledi;/读出一个值送到P1口ledi+;/指向下一个if(ledi=4)ledi=0;/到了最后一个灯就换到第一个/定时器2中断timer0()interrupt5staticuchart;TF2=0;t+;if(t=30)/T2的预置值0x1000,溢出30次就是1秒钟,晶振HZt=0;ldelay=1;
44、/每次长时间的溢出,就置一个标记,以便主程序处理编译,进入仿真,看结果。可以看到4个灯以精确的1秒的速度不断循环跑动。第9课,自动变速的跑马灯试验这一课,我们仍然使用上一个定时器跑马灯工作方式,但是我们让跑动的速度自动变化,从慢到快。相对于上一颗的跑马灯试验,我们新设置了一个变量speed,用来保存跑马灯的移动速度,其实也就是定时器的累计时间溢出次数。我们在程序中修改speed的数值,溢出的时间就会改变,跑马灯的移动速度也就改变了。我们是在每循环跑完一圈,就改变一次速度的。请仔细研究代码,做到充分理解。源代码如下:请打开对应目录里的例程,和下面的代码是一样的。#defineucharunsig
45、nedchar/定义一下方便使用#defineuintunsignedint#defineulongunsignedlong#include<reg52.h>/包括一个52标准内核的头文件sbitP10=P1A0;头文件中没有定义的IO就要自己来定义了sbitP11=P1A1;sbitP12=P1A2;sbitP13=P1A3;bitldelay=0;/长定时溢出标记,预置是0ucharspeed=10;/设置一个变量保存跑马灯的移动速度charcodedx5163_at_0x003b;/这是为了仿真设置的/自动变速的跑马灯试验voidmain(void)/主程序ucharcode
46、ledp4=0xfe,0xfd,0xfb,0xf7;/预定的写入P1的值ucharledi;/用来指示显示顺序RCAP2H=0x10;/赋T2的预置值0x1000,溢出30次就是1秒钟RCAP2L=0x00;TR2=1;/启动定时器ET2=1;/打开定时器2中断EA=1;/打开总中断while(1)/主程序循环if(ldelay)/发现有时间溢出标记,进入处理ldelay=0;/清除标记P1=ledpledi;/读出一个值送到P1口ledi+;/指向下一个if(ledi=4)ledi=0;/到了最后一个灯就换到第一个speed-;if(speed=0)speed=10;/每循环显示一次,就调快
47、一次溢出速度/定时器2中断timer2()interrupt5staticuchart;TF2=0;t+;if(t=speed)/比较一个变化的数值,以实现变化的时间溢出t=0;ldelay=1;/每次长时间的溢出,就置一个标记,以便主程序处理请编译,运行,并查看结果。第10课,4个按键4级变速的跑马灯试验,多任务的工作方式这一课,我们要用4个按键,控制跑马灯的4种不同的跑动速度。按键的控制我们也做过了,结合跑马灯,很容易程序就出来了。只是每按一个键,就赋给一个不同的定时器2溢出次数而已。我们设置为1秒,1/2秒,1/5秒,1/10秒四个档次,分别时K1K4控制。这个程序的主程序执行了2个任务
48、。一个是跑马灯,一个是检测按键。程序的结构非常清晰。程序如下:#defineucharunsignedchar/定义一下方便使用#defineuintunsignedint#defineulongunsignedlong#include<reg52.h>/包括一个52标准内核的头文件sbitP10=P1A0;头文件中没有定义的IO就要自己来定义了sbitP11=P1A1;sbitP12=P1A2;sbitP13=P1A3;sbitK1=P3A2;sbitK2=P3A5;sbitK3=P2A4;sbitK4=P2A5;bitldelay=0;/长定时溢出标记,预置是0ucharspe
49、ed=10;/设置一个变量保存默认的跑马灯的移动速度charcodedx5163_at_0x003b;/这是为了仿真设置的/自动变速的跑马灯试验voidmain(void)/主程序ucharcodeledp4=0xfe,0xfd,0xfb,0xf7;/预定的写入P1的值ucharledi;/用来指示显示顺序RCAP2H=0x10;/赋T2的预置值0x1000,溢出30次就是1秒钟RCAP2L=0x00;TR2=1;/启动定时器ET2=1;/打开定时器2中断EA=1;/打开总中断while(1)/主程序循环if(ldelay)/发现有时间溢出标记,进入处理ldelay=0;/清除标记P1=led
50、pledi;/读出一个值送到P1口ledi+;/指向下一个if(ledi=4)/到了最后一个灯就换到第一个/检查到按键,设置对应的跑马速度ledi=0;if(!K1)speed=30;if(!K2)speed=15;if(!K3)speed=6;if(!K4)speed=3;/定时器2中断timer2()interrupt5staticuchart;TF2=0;t+;if(t=speed)|(t>30)/ 比较一个变化的数值,以实现变化的时间溢出, 同时限制了最慢速度t=0;ldelay=1;/每次长时间的溢出,就置一个标记,以便主程序处理请打开工程,编译,运行。可以看到,启动后,以默认
51、的速度跑马,按K1,速度是1秒一个灯,按K2,是1/2秒一个灯,按K3是1/5秒一个灯,按K4,则最快,是1/10秒。第11课,一个按键控制的10级变速跑马灯试验在本课中,我们要用一个按键来实现跑马灯的10级调速。这又会涉及到键的去抖的问题。本课的试验结果是,每按一次按键,跑马速度就降低一级,共10级。这里我们又增加了一个变量speedlever,来保存当前的速度档次。在按键里的处理中,多了当前档次的延时值的设置。请看程序:#defineucharunsignedchar/定义一下方便使用#defineuintunsignedint#defineulongunsignedlong#includ
52、e<reg52.h>/包括一个52标准内核的头文件sbitP10=P1A0;/头文件中没有定义的IO就要自己来定义了sbitP11=P1A1;sbitP12=P1A2;sbitP13=P1A3;sbitK1=P3A2;bitldelay=0;/长定时溢出标记,预置是0ucharspeed=10;/设置一个变量保存默认的跑马灯的移动速度ucharspeedlever=0;/保存当前的速度档次charcodedx5163_at_0x003b;/这是为了仿真设置的/一个按键控制的10级变速跑马灯试验voidmain(void)/主程序ucharcodeledp4=0xfe,0xfd,0x
53、fb,0xf7;/预定的写入P1的值ucharledi;/用来指示显示顺序uintn;RCAP2H=0x10;/赋T2的预置值0x1000,溢出30次就是1秒钟RCAP2L=0x00;TR2=1;/启动定时器ET2=1;/打开定时器2中断EA=1;/打开总中断while(1)/主程序循环if(ldelay)/发现有时间溢出标记,进入处理ldelay=0;/清除标记P1=ledpledi;/读出一个值送到P1口ledi+;/指向下一个if(ledi=4)ledi=0;/到了最后一个灯就换到第一个if(!K1)/如果读到K1为0for(n=0;n<1000;n+);/等待按键稳定while(
54、!K1);/等待按键松开for(n=0;n<1000;n+);/等待按键稳定松开speedlever+;if(speedlever=10)speedlever=0;speed=speedlever*3;/档次和延时之间的预算法则,也可以用查表方法,做出不规则的法则/定时器2中断timer2()interrupt5staticuchart;TF2=0;t+;if(t=speed)|(t>30)/比较一个变化的数值,以实现变化的时间溢出,同时限制了最慢速度为1秒t=0;ldelay=1;/每次长时间的溢出,就置一个标记,以便主程序处理请打开lesson11目录的工程,编译,运行,看结果:按K1,速度则降低一次,总共10个档次第12课,可编程自动控制控制跑马灯这一颗,我们学习如何让跑马灯自动按照我们预定的顺序进行。这种控制在工控场合经常用到。这个程序里,我们预先定义了一个变化的顺序speedcode,每跑一圈灯就根据预定设置的表格数据来决定下一圈的跑马速度。这样我们就实现了按照预定的顺序自动变化运行。请看代码:#defineucharunsignedc
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 民宿短租平台用户入住及退房流程管理协议
- 国际法律顾问团队派遣服务协议
- 专业美容美发技术培训与创业支持合同
- 互联网支付货币合规管理补充协议
- 艺术展览馆运营与管理委托合同
- 俄罗斯能源输送管道监理与维护补充协议
- 电力设施租赁补充协议(储能电站建设)
- 房产抵押贷款与互联网金融创新服务合同
- 快餐连锁品牌加盟及绿色有机食材供应协议
- 仓库租赁补充协议(含消防)
- 诺如病毒校园防控知识
- 常见神经系统疾病康复15节
- 关于梳理、修订、完善公司规章制度的通知
- 会计信息考试系统复习题(试题及答案)
- 高中物理学习中的数字化教学资源
- (高清版)TDT 1067-2021 不动产登记数据整合建库技术规范
- 安措费清单完整版本
- 人教版五年级数学下册全册分层作业设计含答案
- 学校减免校服政策方案
- 企业管理中的组织行为学
- 培训课件 -华为铁三角工作法完全解密
评论
0/150
提交评论