正文

【009】一位数码管循环计数 [51]2006-05-02 17:28:00

【评论】 【打印】 【字体: 】 本文链接:http://blog.pfan.cn/wentao/13438.html

分享到:

实验目的:1位数码管从0到9循环计数,间隔1s。
实验板: FB51A(查看


该实验用到实验板的资源电路图如下:

其中P0口是段码,低电平有效。P2口是位码,高电平有效。P2.0口控制第1个数码管,一直到P2.7口控制第8个。该板的段码表如下:

┌─────┬────────────────┬────┐
ㄧ          ㄧ P0.*:  7  6  5  4  3  2  1  0  ㄧ P0口值 ㄧ
ㄧ 十进制数 ㄧ  段 :  d dp  e  c  g  b  f  a  ㄧ 即段码 ㄧ
├─────┼────────────────┼────┤
ㄧ    0     ㄧ        0  1  0  0  1  0  0  0  ㄧ  48H   ㄧ
ㄧ    1     ㄧ        1  1  1  0  1  0  1  1  ㄧ  ebH   ㄧ
ㄧ    2     ㄧ        0  1  0  1  0  0  1  0  ㄧ  52H   ㄧ
ㄧ    3     ㄧ        0  1  1  0  0  0  1  0  ㄧ  62H   ㄧ
ㄧ    4     ㄧ        1  1  1  0  0  0  0  1  ㄧ  e1H   ㄧ
ㄧ    5     ㄧ        0  1  1  0  0  1  0  0  ㄧ  64H   ㄧ
ㄧ    6     ㄧ        0  1  0  0  0  1  0  0  ㄧ  44H   ㄧ
ㄧ    7     ㄧ        1  1  1  0  1  0  1  0  ㄧ  eaH   ㄧ
ㄧ    8     ㄧ        0  1  0  0  0  0  0  0  ㄧ  40H   ㄧ
ㄧ    9     ㄧ        0  1  1  0  0  0  0  0  ㄧ  60H   ㄧ
├─────┼────────────────┼────┤
ㄧ    0.    ㄧ        0  0  0  0  1  0  0  0  ㄧ  08H   ㄧ
ㄧ    1.    ㄧ        1  0  1  0  1  0  1  1  ㄧ  abH   ㄧ
ㄧ    2.    ㄧ        0  0  0  1  0  0  1  0  ㄧ  12H   ㄧ
ㄧ    3.    ㄧ        0  0  1  0  0  0  1  0  ㄧ  22H   ㄧ
ㄧ    4.    ㄧ        1  0  1  0  0  0  0  1  ㄧ  a1H   ㄧ
ㄧ    5.    ㄧ        0  0  1  0  0  1  0  0  ㄧ  24H   ㄧ
ㄧ    6.    ㄧ        0  0  0  0  0  1  0  0  ㄧ  04H   ㄧ
ㄧ    7.    ㄧ        1  0  1  0  1  0  1  0  ㄧ  aaH   ㄧ
ㄧ    8.    ㄧ        0  0  0  0  0  0  0  0  ㄧ  00H   ㄧ
ㄧ    9.    ㄧ        0  0  1  0  0  0  0  0  ㄧ  20H   ㄧ
└─────┴────────────────┴────┘

首先采用一个比较笨的办法,即先送段码0到P0口,延时1s后,再送段码1到P0口,延时1s …… 如此循环。



汇编实现:

          org   0000h
start:    mov   p2,#01h     ; 位码

loop:     mov   p0,#48h     ; 段码
          lcall delay_1s

          mov   p0,#0ebh
          lcall delay_1s

          mov   p0,#52h
          lcall delay_1s

          mov   p0,#62h
          lcall delay_1s

          mov   p0,#0e1h
          lcall delay_1s

          mov   p0,#64h
          lcall delay_1s

          mov   p0,#44h
          lcall delay_1s

          mov   p0,#0eah
          lcall delay_1s

          mov   p0,#40h
          lcall delay_1s

          mov   p0,#60h
          lcall delay_1s

          ajmp  loop

delay_1s: mov r0,#2
temp1:    mov r1,#0ffh
temp2:    mov r2,#100
temp3:    mov r3,#10
          djnz r3,$
          djnz r2,temp3
          djnz r1,temp2
          djnz r0,temp1
          ret
end



查表法实现如下:

          org    0000h
start:    mov    p2,#01h
          mov    r7,#0ffh
          mov    a,#0ffh
          mov    dptr,#table
          mov    a,#0
loop:     inc    r7           ;计数
          mov    a,r7
          movc   a,@a+dptr
          mov    p0,a
          lcall  delay_1s
          cjne   a,#60h,loop
          ajmp   start

table:    db     48h,0ebh,52h,62h,0e1h,64h,44h,0eah,40h,60h

delay_1s: mov    r0,#2
temp1:    mov    r1,#0ffh
temp2:    mov    r2,#10
temp3:    mov    r3,#100
          djnz   r3,$
          djnz   r2,temp3
          djnz   r1,temp2
          djnz   r0,temp1
          ret
          end


C51实现(软延时):

#include <reg51.h>

void delay_1s(void);  // 延时子程序

unsigned char code dis_code[11]={0x48,0xeb,0x52,0x62,0xe1,        // 0,1,2,3, 4
                                 0x64,0x44,0xea,0x00,0x60, 0xff}; // 5,6,7,8,9, off

unsigned char data dis;         // 显示索引

void main()
{
    P0 = 0xff; // 关闭所有数码管
    P2 = 0x00;
   
    P2 = 0x01; // 选通P2.0
    dis = 0;   // 当前偏移量为0
   
    while(1)
    {
         P0 = dis_code[dis];  // 段码送P0口
         delay_1s();           // 延时
         dis++;               // 下一个段码
        
         if (dis == 10)
             dis = 0;
    }

}
void delay_1s(void)

    unsigned char h,i,j,k;
    for(h=5;h>0;h--)
        for(i=4;i>0;i--)
            for(j=116;j>0;j--)
               for(k=214;k>0;k--);
}


C51(中断延时)

#include <reg51.h>

unsigned char code dis_code[11] = {0x48, 0xeb, 0x52, 0x62, 0xe1,        // 0,1,2,3,4
                                   0x64, 0x44, 0xea, 0x40, 0x60, 0xff}; //5,6,7,8,9,off

unsigned char data index;   // 显示索引

unsigned char data count;   // 软件计数器

void main()
{
    P0 = 0xff;    // 关闭全部数码管
    P2 = 0x00;

    TMOD = 0x01;  // 00000001B,定时计数器0工作在方式1,为16位
    TH0 = 0x3C;
    TL0 = 0xB0;   // 预置初值3CB0H=15536D, 即一次中断为65536-15536=50ms (12M)

    IE = 0x82;    // 10000010B T0溢出中断允许    
    TR0 = 1;      // 启动T0

    index = 0;
    count = 0;
   
    while(1);     // 循环等待中断
}

void timer0() interrupt 1     // 定时器中断服务程序
{
    TH0 = 0x3C;               // 发生中断重装初值
    TL0 = 0xB0;

    count++;                  // 软件计数器递增

    if (count == 20)          // 50ms×20 = 1s 时
    {
        P2 = 0x01;
                    
        P0 = dis_code[index];

        index++;              // 段码自加

        if (index == 10)      // 控制循环值
            index = 0;

        count = 0;            // 计数器归0
    }
}

用此方法实现, 实测开始会有一个1s的延时,即第一个1s内无显示,原因是在第一个中断(实际上是第20个)之前未对显示处理。若在main函数中开始就显示0,则在第一次显示9之后要归0时的处理会麻烦一些,这并不是本实验所关心的,故未做处理。


下载到板子上实测结果与上述仿真结果相符。

阅读(4674) | 评论(9)


版权声明:编程爱好者网站为此博客服务提供商,如本文牵涉到版权问题,编程爱好者网站不承担相关责任,如有版权问题请直接与本文作者联系解决。谢谢!

评论

loading...
您需要登录后才能评论,请 登录 或者 注册