⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 【006】多位数码管动态显示 [51] -- 一步一脚印 -- 编程爱好者blog.htm

📁 本人写的STC单片机EEPROM功能程序
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            <P>start: mov&nbsp;&nbsp; a,#08h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;0&nbsp;&nbsp;&nbsp; ;段码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; 
            p2,#01h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;位码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall delay_1ms </P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            a,#0abh&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;1&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p2,#02h<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall delay_1ms</P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            a,#12h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;2<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p2,#04h<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall delay_1ms</P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            a,#22h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;3<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p2,#08h<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall delay_1ms</P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            a,#0a1h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;4<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p2,#10h<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall delay_1ms</P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            a,#24h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;5<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p2,#20h<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall delay_1ms</P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            a,#04h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;6<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p2,#40h<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall delay_1ms</P>
            <P><FONT color=#5ea25e>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; a,#0aah&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;7<BR>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,a</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            p0,#0aah&nbsp;&nbsp;&nbsp;&nbsp; 
            ;感觉用这句和上面两句实现一样,可能这种习惯以后会有用吧<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; p2,#80h<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            lcall delay_1ms</P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ljmp&nbsp; start</P>
            <P>delay_1ms: mov&nbsp; r6,#2<BR>temp:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp; 
            r5,#0ffh<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            djnz 
            r5,$<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            djnz 
            r6,temp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ret<BR>end</P>
            <P></P>
            <P>下载到板上得到测结果为从低到高八位分别显示0到7(含点)。<BR><BR><FONT 
            color=#0000ff>★</FONT>上述方法逐次给P0或者P2赋值,一方面程序的复杂程度增加,另外一方面会使得程序的灵活性降低。如果要改变显示的数字,程序改动起来很麻烦。&nbsp;所以要用51单片机中常用的一种方法:<FONT 
            color=#0000ff>查表法</FONT>。例如P0口输出段码时,我们可以把要显示的段码放在一个表格中,然后每次从这个表格里面取数,送到P0口即可。P2口输出位码时,可以把要用的位码放在另一个表格里,每次从此表中取数,送入P2口。这样,如果要改变显示的数字,只需要改变表格里面的数。<BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            org&nbsp;&nbsp; 0000h</P>
            <P>start: mov&nbsp;&nbsp; r7,#0ffh&nbsp;&nbsp;&nbsp;&nbsp; 
            ;r7,r6查表时送入变址寄存器a 
            (因自加1后为0,所以预置ffh)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; r6,#0ffh<BR>loop:&nbsp; lcall 
            play1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;调用显示段码子程序<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall 
            play2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;调用显示位码子程序<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lcall 
            delay_1ms<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cjne&nbsp; 
            a,#80h,loop&nbsp; 
            ;判断是否到了最左边的数,即第8个位码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ajmp&nbsp; start</P>
            <P>play1:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;查表求段码子程序&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR>;<FONT color=#669971>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; 
            a,r7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc&nbsp;&nbsp; 
            a<BR>;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; r7,a</FONT></P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc&nbsp;&nbsp; 
            r7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;这2句和上面三条语句实现功能相同<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; a,r7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;a在这里做变址寄存器</P>
            <P>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT 
            color=#0000ff>mov&nbsp;&nbsp; dptr,#table1</FONT> 
            ;表首址送dptr,dptr做基址寄存器<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT 
            color=#0000ff>movc&nbsp; a,@a+dptr</FONT>&nbsp;&nbsp;&nbsp; 
            ;基址寄存器加变址寄存器寻址<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; p0,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret</P>
            <P>play2:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;查表求位码子程序(原理同play1)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; 
            a,r6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; inc&nbsp;&nbsp; 
            a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp; 
            r6,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT 
            color=#0000ff>mov&nbsp;&nbsp; 
            dptr,#table2</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT 
            color=#0000ff>movc&nbsp; 
            a,@a+dptr<BR></FONT>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; p2,a<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret</P>
            <P>table1: db 08h,0abh,12h,22h,0a1h,24h,04h,0aah&nbsp; 
            ;段码表<BR>table2: db 
            01h,02h,04h,08h,10h,20h,40h,80h&nbsp;&nbsp;&nbsp;&nbsp; ;位码表</P>
            <P>delay_1ms:&nbsp; mov&nbsp;&nbsp; 
            r5,#02h&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ;延时1ms子程序<BR>temp:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            mov&nbsp;&nbsp; 
            r4,#0ffh<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            djnz&nbsp; 
            r4,$<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            djnz&nbsp; 
            r5,temp<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            ret<BR>end<BR><BR>下载到板上验证得到预想结果。<BR>
            <HR>
            C51实现如下(参考了<A href="http://blog.programfan.com/article.asp?id=11866" 
            target=_blank><FONT color=#0099ff>AS</FONT></A>的例程): 
            <P></P>
            <P>#include &lt;reg51.h&gt;<BR>#include 
            &lt;intrins.h&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 包含了左移函数_crol_()</P>
            <P>void delayms(unsigned char ms); // 延时子程序</P>
            <P>unsigned char data dis_digit;&nbsp;&nbsp; // 位选通值, 
            传送到P2口用于选通当前数码管的数值,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 如等于0x01时,选通P2.0口数码管</P>
            <P>unsigned char code 
            dis_code[11]={0x08,0xab,0x12,0x22,0xa1,&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 0,1,2,3, 
            4<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            0x24,0x04,0xaa,0x00,0x20, 0xff}; // 5,6,7,8,9, off </P>
            <P>unsigned char data dis_buf[8];&nbsp; // dis_buf 显于缓冲区基地址</P>
            <P>unsigned char data dis_index;&nbsp;&nbsp; // 显示索引, 
            用于标识当前显示的数码管和缓冲区的偏移量</P>
            <P>void main()<BR>{<BR>&nbsp;&nbsp;&nbsp; P0 = 0xff;&nbsp; // 
            关闭所有数码管<BR>&nbsp;&nbsp;&nbsp; P2 = 0x00; </P>
            <P>&nbsp;&nbsp;&nbsp; dis_buf[0] = 
            dis_code[0];<BR>&nbsp;&nbsp;&nbsp; dis_buf[1] = 
            dis_code[1];<BR>&nbsp;&nbsp;&nbsp; dis_buf[2] = 
            dis_code[2];<BR>&nbsp;&nbsp;&nbsp; dis_buf[3] = 
            dis_code[3];<BR>&nbsp;&nbsp;&nbsp; dis_buf[4] = 
            dis_code[4];<BR>&nbsp;&nbsp;&nbsp; dis_buf[5] = 
            dis_code[5];<BR>&nbsp;&nbsp;&nbsp; dis_buf[6] = 
            dis_code[6];<BR>&nbsp;&nbsp;&nbsp; dis_buf[7] = 
            dis_code[7];<BR>&nbsp;&nbsp;&nbsp; <BR>&nbsp;&nbsp;&nbsp; dis_digit 
            = 0x01;&nbsp; // 首先选通P2.0<BR>&nbsp;&nbsp;&nbsp; dis_index = 
            0;&nbsp;&nbsp;&nbsp;&nbsp; // 当前偏移量为0<BR>&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;&nbsp; while(1)<BR>&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P0 = 
            dis_buf[dis_index];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 段码送P0口<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; P2 = 
            dis_digit;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 选能位(即位码)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            delayms(1);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 延时<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dis_digit 
            = _crol_(dis_digit, 1); // 位选通左移, 
            下次选通下一位<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            dis_index++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 下一个段码<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR><FONT 
            color=#0000ff>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            dis_index &amp;= 
            0x07;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 见注释</FONT><BR>&nbsp;&nbsp;&nbsp; }</P>
            <P>}<BR>void delayms(unsigned char 
            ms)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            // 
            延时子程序(晶振12M)<BR>{&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
            <BR>&nbsp;&nbsp;&nbsp; unsigned char i;<BR>&nbsp;&nbsp;&nbsp; 
            while(ms--)<BR>&nbsp;&nbsp;&nbsp; 
            {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for(i = 0; i &lt; 
            120; i++);<BR>&nbsp;&nbsp;&nbsp; }<BR>}</P>
            <P><BR><FONT color=#ff0000>★</FONT><FONT color=#0000ff>注释</FONT>: 
            此句作用是8个数码管全部扫描完一遍之后,再回到第一个开始下一次扫描。写回一般形式:dis_index = dis_index &amp; 
            0x07 。这种方法挺新,第一次见到,十六进制的07就是二进制的00000111,这样通过与操作可以控制循环了。比如dis_index 
            经第一次循环后值为00000001,和0x07与操作后值不变仍为0x01,第二次循环时,其值为0为0x02,与0x07后仍为0x02,一直到其值增为0x07时还是不变的,但再次循环后其值为0x80,再与0x07后就变成0x00了,这样又从初始循环了。此句可用 
            if (dis_index == 8) dis_index = 0 代替,效果一样。</P>
            <P><FONT 
            color=#0000ff>★</FONT>通过C51用上述方法实现时,其段码放在了数组dis_code[11]中,再通过缓冲区数组dis_buf[]将程序中要调用的值装入,这样就可以用下标(偏移量)访问了。这样看上去有些繁锁,但其思路比较清楚,结构上也很明了,具有通用性,便于扩展。<BR><BR><FONT 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -