您的位置:控制工程论坛网论坛 » 嵌入式系统 » MSC-51编程应用范例【转帖】

zhiy66

zhiy66   |   当前状态:在线

总积分:6528  2026年可用积分:0

注册时间: 2007-12-18

最后登录时间: 2012-01-11

空间 发短消息加为好友

MSC-51编程应用范例【转帖】

zhiy66  发表于 2008/9/26 19:10:31      1657 查看 6 回复  [上一主题]  [下一主题]

手机阅读

1、并行I/O口编程范例

单片机I/O的应用最典型的是通过I/O口与7段LED数码管构成显示电路,我们从常用的LED显示原理开始,详尽讲解利用单片机驱动LED数码管的电路及编程原理,目的在于通过这一编程范例,让初学者了解I/O口的编程原理,意在起举一反三,抛砖引玉的作用。
    LED的发光原理,稍有电子技术基础的人士都很清楚,我们不想作过多的介绍,7段LED数码管,则在一定形状的绝缘材料上,利用单只LED组合排列成“8”字型的数码管,分别引出它们的电极,点亮相应的点划来显示出0-9的数字。


    LED数码管根据LED的接法不同分为共阴和共阳两类,了解LED的这些特性,对编程是很重要的,因为不同类型的数码管,除了它们的硬件电路有差异外,编程方法也是不同的。右图是共阴和共阳极数码管的内部电路,它们的发光原理是一样的,只是它们的电源极性不同而已。
    将多只LED的阴极连在一起即为共阴式,而将多只LED的阳极连在一起即为共阳式。以共阴式为例,如把阴极接地,在相应段的阳极接上正电源,该段即会发光。当然,LED的电流通常较小,一般均需在回路中接上限流电阻。假如我们将"b"和"c"段接上正电源,其它端接地或悬空,那么"b"和"c"段发光,此时,数码管显示将显示数字“1”。而将"a"、"b"、"d"、"e"和"g"段都接上正电源,其它引脚悬空,此时数码管将显示“2”。其它字符的显示原理类同,读者自行分析即可。
LED数码管结构图
LED显示电路    左图为实验电路图,我们使用80C51单片机,电容C1、C2和CRY1组成时钟振荡电路,这部分基本无需调试,只要元件可靠即会正常起振。C3和R1为单片机的复位电路,80C51的并行口P1.0-P1.7直接与LED数码管的"a-f"引脚相连,中间接上限流电阻R3-R10。值得一提的是,80C51并行口的输出驱动电流并非很大,为使LED有足够的亮度,LED数码管应选用高亮度的器件。
    此外,图中的80C51还可选用C51系列的其它单片机,只要它们的指令系统兼容C51即可正常运行,程序可直接移植,例如选用低价Flash型的AT89C1051或2051(详细技术手册)等,它们的ROM可反复擦写,非常适合作实验用途。
    · 程序清单:
    01  START: ORG     0100H      ;程序起始地址
    02   MAIN: MOV    R0,#00H     ;从“0”开始显示
    03         MOV    DPTR,#TABLE ;表格地址送数据指针
    04   DISP: MOV    A,R0        ;送显示
    05         MOVC   A,@A+ADPTR  ;指向表格地址
    06         MOV    P1,A        ;数据送LED
    07         ACALL  DELAY       ;延时
    08         INC    R0          ;指向下一个字符
    09         CJNE   R0,#0AH,DISP ;未显示完,继续
    10         AJMP   MAIN        ;下一个循环
    11  DELAY: MOV    R1,#0FFH    ;延时子程序,延时时间赋值
    12  LOOP0: MOV    R2,#0FFH
    13  LOOP1: DJNZ   R2,LOOP1
    14         DJNZ   R1,LOOP0
    15         RET                ;子程序返回
    16  TABLE: DB     0C0H        ;字型码表
    17         DB     0F9H
    18         DB     0A4H
    19         DB     0B0H
    20         DB     99H
    21         DB     92H
    22         DB     82H
    23         DB     0F8H
    24         DB     80H
    25         DB     90H
    26         END                ;程序结束

1楼 0 0 回复
  • zhiy66

    zhiy66   |   当前状态:在线

    总积分:6528  2026年可用积分:0

    注册时间: 2007-12-18

    最后登录时间: 2012-01-11

    空间 发短消息加为好友

    zhiy66   发表于 2008/9/26 19:07:01

    上一节我们讲述了单只LED与单片机的接口电路及编程实例,目的在于让初学者了解LED在单片机中的应用原理,单只LED显示在实际应用中并无多大用途,一般都是多位的LED显示。现在我们作进一步学习,我们要讲解的是8位LED的显示原理及实际的编程方法。这里我们没有采用多I/O口的8051系列单片机,而是采用了完全兼容C51指令系统的质优价廉的AT89C2051单片机,它的软件编程与C51完全一致。
        在多数的应用场合中,我们并不希望使用多I/O端口的单片机,原则上是使用尽量少引脚的器件。在没有富余端口的情况下,怎样通过扩展电路达到预期的目的呢?我们希望通过此例使设计人员在实际应用中了解一点电路扩展的原理,对实际的应用有所帮助。

        左图是显示电路,由于AT89C2051外部15个I/O引脚,即P1口和P3口,单P3口的P3.6是不引出的,15个I/O口要直接驱动8位LED显然是不够的,我们通过一片面74LS273对地址进行锁存,如果P1口仅用于显示驱动,而没有与其它外设进行数据交换,可省略这个锁存器,直接或通过其他驱动电路驱动连接LED。地址线我们通过一片74LS138三—八译码器对8位LED进行分时选通,这样在任一时刻,只有一位LED是点亮的,但只要扫描的频率足够高(一般大于25Hz),由于人眼的视觉暂留特性,直观上感觉却是连续点亮的,这就是我们常说的动态扫描电路。
    8位LED显示电路
        此电路中,74LS273用于驱动LED的8位段码,8位LED相应的"a"—"g"段连在一起,它们的公共端分别连至由74LS138(点击芯片型号可浏览其详细的技术手册)译码选通后经74LS04反相驱动的输出端。这样当选通某一位LED时,相应的地址线(74LS04输出端)输出的是高电平,所以我们的LED选用共阳LED数码管。
        动态扫描的频率有一定的要求,频率太低,LED将出现闪烁现象。如频率太高,由于每个LED点亮的时间太短,LED的亮度太低,肉眼无法看清,所以一般均取几个ms左右为宜,这就要求在编写程序时,选通某一位LED使其点亮并保持一定的时间,程序上常采用的是调用延时子程序。在C51指令中,延时子程序是相当简单的,并且延时时间也很容易更改,可参见程序清单中的DELAY延时子程序。
        为简单起见,我们只是编写了8位LED同步显示"00000000"—"11111111"直到"99999999"数字,并且反复循环。程序很简单,流程图略去。

        · 程序清单:
    2楼 回复本楼

    引用 zhiy66 2008/9/26 19:07:01 发表于2楼的内容

  • zhiy66

    zhiy66   |   当前状态:在线

    总积分:6528  2026年可用积分:0

    注册时间: 2007-12-18

    最后登录时间: 2012-01-11

    空间 发短消息加为好友

    zhiy66   发表于 2008/9/26 19:07:40

    单片机并行I/O口数量总是有限的,有时并行口需作其他更重要的用途,一般也不会用数量众多的并行I/O口专门用来驱动显示电路,能否用80C51的串行通信口加上少量I/O及扩展芯片用于显示电路呢?答案是肯定的。
        80C51的串行通信口是一个功能强大的通信口,而且是相当好用的通信口,用于显示驱动电路再合适不过了,下面我们就根据这种需要设计一个用两个串行通信口线加上两根普通I/O口,设计一个4位LED显示电路。当然只要再加上两根I/O口线即可轻易实现8位LED的显示电路。
    串行口动态扫描显示电路
        左图是电原理图,我们还是采用C2051单片机,同时用廉价易得的74LS164和74LS138作为扩展芯片。74LS164(详细技术手册)是一个8位串入并出的移位寄存器,其此处的功能是将C2051串行通信口输出的串行数据译码并在其并口线上输出,从而驱动LED数码管。74LS138是一个3-8译码器,它将单片机输出的地址信号译码后动态驱动相应的LED。但74LS138电流驱动能力较小,为此,我们使用了未级驱动三极管2SA1015作为地址驱动。
        将4只LED的段位都连在一起,它们的公共端则由74LS138分时选通,这样任何一个时刻,都只有一位LED在点亮,也即动态扫描显示方式,其优点在上一节中我们已经阐述。使用串行口进行LED通信,程序编写相当简单,用户只需将需显示的数据直接送串口发送缓冲器,等待串行中断即可,看看下面的程序。
    · 程序清单
     
    3楼 回复本楼

    引用 zhiy66 2008/9/26 19:07:40 发表于3楼的内容

  • zhiy66

    zhiy66   |   当前状态:在线

    总积分:6528  2026年可用积分:0

    注册时间: 2007-12-18

    最后登录时间: 2012-01-11

    空间 发短消息加为好友

    zhiy66   发表于 2008/9/26 19:08:20

      我们以一个实际的时钟电路来说明定时器的软件编程方法,时钟就是我们最为常见的显示时、分、秒为单位的计时工具,它是典型的应用代表。

        时钟的最小计时单位是秒,但使用单片机定时器来进行计时,若使用6.0MHz的晶振,即使按工作方式1工作,最大的计时时间也只能到131ms,所以我们可把每个定时时间取125ms,这样定时器溢出8次(125ms╳8=1000ms)就得到最小的计时单位秒。而要实现8次计数用软件方法实现是轻而易举的。

        我们使用定时器1,以工作方式1工作,定时器进行125ms定时。采用中断方法进行溢出次数的累计,当计满8次即得到1秒的计时。

        一个时钟的计时累加,要实现分、时的进位,要用到多种进制,秒、分、时中的进位是十进制,秒向分进位和分想时进位却是六十进制,而每天又有十二小时制或二十四小时制,它们分别又是十二进制和二十四进制。从秒到分和从分到小时可以通过软件累加和数值比较方法实现。

        在单片机的内部RAM中,需要设置显示缓冲区,显示的时、分、秒值是从显示缓冲区中取出的,在RAM中设置四个单元作为显示缓冲区,分别是7AH、7BH、7CH。为使电路和原理叙述方便,我们这里不显示秒值,秒的进位我们通过闪烁分值实现。这样我们一共有四位LED分别显示时和分值。同时时钟都需要校准的。在程序中还需设置显示码表,要显示的数值通过查表指令将显示用的真正码值送到LED上。我们用单片机AT89C2051的PP3.4和P3.5两个I/O口外接微动开关来实现时和分的校正,每按一次小时或分值加1,连续按下数值累计下去,实现时钟的校准。

        在电路中我们还设置了一个蜂鸣器,用作简单报时用,如可设早上7:30分起床,中午1点30分再有起床报时,每次响时1分钟,响1秒,停2秒的方式,而不是连续响铃。这个程序我们采用12小时制,为此,要在程序中设置相应的标志,以利于主程序识别。同样计时程序中还会有几个相关的标志,主要是控制程序流的转向。程序中我们都作了较详细的注释,这里不再赘述。

        硬件电路,我们还是以低价的AT89C2051单片机为微处理单元,这个芯片兼容C51指令系统,在C51上编写的程序,无需任何修改即可方便地移植到这个芯片上来。我们以P0口作为LED的字段位驱动输出,秒的“进位”采用分值闪烁提示,亮0.5秒,熄0.5秒。,P3.1—P3.3用于位驱动,使用动态扫描方式显示,每位LED的显示时间10—25ms之间均可,扫描频率不能太高,否则每位LED显示的时间过短,亮度太低,不易于观看,以肉眼不感觉到LED闪烁为宜。为了直观,我们的驱动输出没有采用集成电路,而是使用了分立元件—三极管,但工作原理却是一致的。
    电路原理图
        这个电路结构决定LED采用共阳极的数码管,可以采用LQ5101BS普通的发光二极管,驱动三极管可采用易得的2SA1015和2SC1815等型号,当然也可使用象S9012,S9013,S9014,2N5401,2N5555等小功率三极管,其它器件没有特殊要求。为便于实验,单片机AT89C2051可采用DIP20P插座,程序编制好后,调试无错,即可烧写到AT89C2051中,值得一提的是,AT89C2051是Flash程序存储器,程序可反复擦写,对于做实验是非常方便的。
    4楼 回复本楼

    引用 zhiy66 2008/9/26 19:08:20 发表于4楼的内容

  • zhiy66

    zhiy66   |   当前状态:在线

    总积分:6528  2026年可用积分:0

    注册时间: 2007-12-18

    最后登录时间: 2012-01-11

    空间 发短消息加为好友

    zhiy66   发表于 2008/9/26 19:08:58

     6538是任天堂游戏机专用视频图像处理器芯片,它具有极强的图像处理能力。如果把6538用于8031单片机系统,把它较强的图像处理能力用于工业控制领域,将使单片机如虎添翼。而且6538在市场上极为常见,价格仅为十几元一片,在工业控制领域极有应用前途。

        市场上常见的6538是台湾联华公司生产的UMC6538,其引脚排列如图1所示。它能在较少的外围电路支持下完成图像处理,直接输出复合视频信号,可直接送监视器显示。如果通过射频调制,可以用有线或无线方式在彩色或黑白电视机上显示图像。

        6538可以显示分辨率为256×240点的彩色图像,每个点有52种颜色选择。6538所显示的图像由四个页面叠加而成,从前向后依此是卡通0页、背景页、卡通1页、底背景页。各页均可由软件开关控制显示与否。在这4个叠加的页面中,前面的页面图像可以覆盖后面的页面图像,使画面具有很强的立体感。在这4个页面中只有背景页面占有显示缓冲区,背景页共有4页,缓冲区位于6116中,实际只能使用2页。卡通页可显示64个8×8点阵图形块,缓冲单元位于6538中,修改参数可使卡通图像在屏幕上以点为单位任意移动,底背景页只能显示单一颜色,不能显示图形,不占缓冲单元,其颜色可由软件选择。
        6538与8031的接口如图2所示。6538为6502总线结构,不能与此同时8031直接连接,可以通过外部接口于之相连,这样会占用很多外部接口,操作也不方便。图2中把8031的读写信号经过变换,使6538可以直接挂在8031的系统总线上,可节约很多外部接口,也方便操作,可以直接用MOVX指令访问6538。图2中的6538的R/W信号接到8031的一根地址线A8上,这就要求8031访问6538时限制地址,要求写6538时A8为低电平,读6538时A8为高电平。
        6538通过8个寄存器与8031通信,8031通过访问这些寄存器控制显示及访问显示缓冲区和字库。字库由一片2764构成,其中可以固化512个8×8点阵图形块,这些图形块可以是ASCII字符或卡通图形,也可以是汉字点阵相当于4个8×8点阵图形块。建议在2764中固化128个ASCII字符和96个常用汉字点阵,这可满足大部分场合使用,如果要显示任意汉字,可把2764换成6264,把大容量汉字库挂在8031系统内,当要显示某一汉字时,8031通过接口把该汉字点阵传送到6538的字库6264中,这样6538就可以显示任意汉字了。
    6538引脚图
    6538与8031的接口电路

        为了能实时处理图像,6538还提供了一个中断信号输出端INT,该信号可由软件开关控制,当允许中断时,INT端在一场图像回扫期间发出宽度为1.286ms,频率为50Hz的低脉冲信号,利用该信号触发中断可同步处理每一场图像,又不占用过多机时,给程序设计带来极大的方便。

        例如要在屏幕上显示“COMPUTER图像处理”几个文字,字库为2764,其中固化有ASCII字符和“图像处理”等汉字点阵。

        程序清单:
    程序清单hspace

    5楼 回复本楼

    引用 zhiy66 2008/9/26 19:08:58 发表于5楼的内容

  • zhiy66

    zhiy66   |   当前状态:在线

    总积分:6528  2026年可用积分:0

    注册时间: 2007-12-18

    最后登录时间: 2012-01-11

    空间 发短消息加为好友

    zhiy66   发表于 2008/9/26 19:09:42

    ICL7135具有±20000个数的分辨率,而且有BCD码和STB选通信号输出,与微机接口十分方便,因此有很多文章介绍ICL7135作为微机的高精度A/D接口电路。本篇文章与其他文章不同之处是利用ICL7135的“busy”输出信号与单片机MCS-51衔接。

        在小型化仪表中,应该以最少的元件完成尽可能多的任务,8031需外接EPROM,剩下的16个I/O口是十分宝贵的。如果利用ICL7135的BCD码和STB选通信号就要占5个I/O口,而利用ICL7135的“busy”端,只要一个I/O和8031内部的一个定时器就可以把ICL7135的数据送入单片机。

        为了便于读者理解,首先介绍ICL7135的“busy”端的功能。ICL7135是以双积分方式进行A/D转换的电路。每个转换周期分为三个阶段:
        [1].自动调零阶段
        [2].被测电压积分阶段
        [3].对基准电压进行反积分阶段

        以输入电压Vx为例,其积分器输出端(ICL7135的4脚)的波形如图1所示。“busy”输出端(ICL7135的21脚)高电平的宽度等于积分和反积分时间之和。ICL7135内部规定积分时间固定为10001个时钟脉冲时间,反积分时间长度与被测电压的大小成比例。如果利用单片机内部的计数器对ICL7135的时钟脉冲计数,利用“busy”作为计数器门控信号,控制计数器只能在busy为高电平时计数,将这段busy高电平时间内计数器的内容减去10001,其余数便等于被测电压的数值。
    图1
    图2    图2是MCS-51定时器的逻辑框图,如果我们把T0规定为模式1定时器方式。定时器控制端(8031的12脚)接ICL7135的“busy”端。这样就能实现计数器由“busy”控制对单片机1/12时钟频率的计数要求。

        图3是ICL7135与单片机MCS-51通过“busy”接口的电路图。若8031的时钟采用6MHz晶体,在不执行MOVX指令的情况下,ALE是稳定的1MHz频率,经过4分频可得到250kHz的稳定频率,传给ICL7135时钟输入端,使ICL7135的转换速率为每秒6.25次,选取这一转换速率,一方面照顾ICL7135A/D转换的精度,另一方面为了尽量少占用8031的资源。定时器为16位计数器,最大计数值65535。在6.25次/秒转换速率条件下,满度电压输入时,busy宽度为30001个时钟脉冲。再结合图1和图2可知,8031内部定时器的输入频率是500kHz,比ICL7135的时钟频率(250kHz)高1倍,在满度电压输入时,定时器计数值为30001x2=60002。不超过定时器最大值。在“busy”高电平期间定时器的数值除以2,再减去10001,余数便是被测电压的数值。具体程序如下:
    图3
    6楼 回复本楼

    引用 zhiy66 2008/9/26 19:09:42 发表于6楼的内容

  • zhiy66

    zhiy66   |   当前状态:在线

    总积分:6528  2026年可用积分:0

    注册时间: 2007-12-18

    最后登录时间: 2012-01-11

    空间 发短消息加为好友

    zhiy66   发表于 2008/9/26 19:10:31

      我们在进行《液体浓度在线测量仪》的研制过程中,应用8031单片机作为系统控制和数据处理部件,探头是光纤传感器,光源为发光二极管LED。考虑到:(1)直流信号的温度效应(如光电接收器的暗电流、放大电路的零点漂移),(2)增大LED的工作电流,增强其发光强度,提高信噪比,使整套仪器抗干扰能力强。(3)延长LED的使用寿命等。我们采用脉冲发光方法,即在每测量一次数据的周期内,LED发光200us,同时光信号由PIN二极管转换为电信号,放大后由LM398进行取样保持。在8031进行数据采集和处理所需的580ms时间内,LED不发光。由于LED处于占空比较小的脉冲发光状态,因此无论是理论上还是实验上都要求LED工作于均匀间隔发光的形式,这样才能保证LED物理特性最好,发光稳定,才可能进行绝对值测量。程序中有判断、转移,每次测量中数据处理的时间并不相等,8031内部定时器若工作在常数自动重新装入的8位定时/计数方式时,也仅能与程序并行定时较短时间,与所需的近600ms相差甚远。因此我们将定时/计数器用于外部计数器的方法,来强迫定时开启LED发光电路达到目的,电路如图1所示。

    工作电路

        4060是14级计数兼振荡器,内部串级构成14级2进计数/分频器,另有两级反相放大器。晶体为32kHz(电子手表内用小晶振),4脚(Q6)输出周期为4ms的方波,作为外部脉冲输入到8031的定时器T1(P3.5),当记满150次(600ms)时,LED发光一次。

        还需要提及的是,光纤传感器直接与被测液体相接触,易被液体污染而影响测量数据的准确性,我们采用超声波清洗技术,效果理想。在超声波清洗过程中,虽然不进行数据采集和处理,也要求LED处于均匀发光状态。相应的主要程序如下:
    程序清单
    7楼 回复本楼

    引用 zhiy66 2008/9/26 19:10:31 发表于7楼的内容

总共 , 当前 /