数码管显示 0-9999计数器

前几天,回答了一个问题:数码管显示0-9999计数器,两个按键,一个按键复位,一个按键累加计数。
可见:http://hi.baidu.com/do_sermon/item/620ab2cadf946422e90f2e91

呵呵,刚刚提交了程序,就被提问者选为最佳答案!
其实,提交的当时,只是准备看看回答的效果,因为百度知道有时犯混,提交的回答显示不出来。
结果,电路也没有来得及附上;另外在程序中,还忽略了消除无效0的功能。
下面把消除无效0的功能进行简单的介绍,并给出完整的程序。
;===========================================
四位显示器,是可以显示0000~9999的,但是在设计工程实际的产品时,前三个0,是不应该显示的。
一个成熟的程序,都应该有消除无效0的程序段。
消除无效0,其实就是用“空白”的代码来代替“0”。
在程序中,大家都知道有个七段码表,一般是把0123...的七段码依次排列在里面,那么第0~15个,通常就是0~F的七段码。
如果把“空白”七段码FFH,排在第16个位置,那么“空白”的代码就是16。
消除无效0的程序,应该从高位到低位(千位、百位、十位)依次判断,个位的0,是应该显示的,则不用判断。
某一位是0,就替换为16,如果不是0,不仅不用替换,还要停止判断后面其它的位。
比如:
千位是0:替换成16;
百位不是0:不用改,正常显示百位;
十位:无论是不是0,都应该正常显示,不用判断了。
做而论道看过不少大学的教材和参考书,都没有看到消除无效0的程序(也许,还是没有看全)。
呵呵,这大概就是“教学”和“工程”的区别吧。
;===========================================
下面做而论道把自己编写的“消除无效0的程序”公布出来,希望能够抛砖引玉。
消除无效0,话是说了很多,可是做而论道编写的程序,都是很简练的,看了不要失望。
程序如下:
;
      ORG  0000H
      LJMP MAIN
      ORG  0030H
MAIN:
      MOV  70H, #0         ;显示缓冲区.
      MOV  71H, #0
      MOV  72H, #0
      MOV  73H, #0
      MOV  74H, #00H       ;计数单元.
      MOV  75H, #80H       ;都是 BCD 码.
;-------------------------------
M_LOOP: 
      LCALL DISP
      JNB   P3.2, JIA_YI
      JNB   P3.3, QING_L
      AJMP  M_LOOP
;-------------------------------
JIA_YI:
      LCALL DISP
      JB    P3.2, M_LOOP
      MOV   A,  75H
      ADD   A,  #1
      DA    A
      MOV   75H, A
      MOV   A,  74H
      ADDC  A,  #0
      DA    A
      MOV   74H, A
J_L:
      LCALL DISP
      JNB   P3.2, J_L
      AJMP  M_LOOP
;-------------------------------
QING_L:
      LCALL DISP
      JB    P3.3, M_LOOP
      MOV   74H, #0
      MOV   75H, #0
      AJMP  M_LOOP
;-------------------------------
DISP:
      MOV  R0, #70H
      MOV  A,  74H
      SWAP A
      ANL  A,  #0FH
      MOV  @R0,  A
      INC  R0
      MOV  A,  74H
      ANL  A,  #0FH
      MOV  @R0,  A
      INC  R0
      MOV  A,  75H
      SWAP A
      ANL  A,  #0FH
      MOV  @R0,  A
      INC  R0
      MOV  A,  75H
      ANL  A,  #0FH
      MOV  @R0,  A
;---------------------------下面是消除无效的0
      MOV  R0, #70H
LL:
      CJNE @R0, #0, QQ
      MOV  @R0, #16
PP:
      INC  R0
      CJNE R0, #73H, LL
QQ:
;---------------------------下面是显示部分
      MOV  DPTR, #D_TAB
      MOV  R2, #254
      MOV  R0, #70H
D_LOOP:
      MOV  A,  @R0
      MOVC A,  @A+DPTR
      MOV  P2, #255       ;消隐.
      MOV  P0, A          ;输出段码.
      MOV  P2, R2         ;输出位码.
      LCALL  DL_1MS
      MOV  A,  R2
      RL   A
      MOV  R2, A
      INC  R0
      CJNE R0, #74H, D_LOOP
      RET
D_TAB: 
      DB  0C0H, 0F9H, 0A4H, 0B0H, 99H,  92H, 82H, 0F8H
      DB   80H,  90H,  88H,  83H, 86H, 0A1H, 86H,  8EH, 0FFH ;FF是空白的代码
;-------------------------------
DL_1MS:
      DJNZ  R7, $
      DJNZ  R7, $
      RET
;-------------------------------
END 

仿真电路图可以看前面给出的链接。

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
以下是一个简单的51单片机代码,实现数码管显示0000-9999,并使用按键实现不同的功能。 ```c #include <reg52.h> // 数码管编码表 unsigned char code SEG_TABLE[] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 }; // 数码管位选表 unsigned char code POS_TABLE[] = { 0xfe, 0xfd, 0xfb, 0xf7 }; // 全局变量,用于存储计数器的值 unsigned int counter = 0; // 函数声明 void delay(unsigned int ms); void display(unsigned int num); void reset_counter(); void increase_counter(); void decrease_counter(); void main() { // 初始化IO口状态 P0 = 0xff; P2 = 0xff; // 重置计数器 reset_counter(); // 主循环 while (1) { // 显示计数器的值 display(counter); // 检测按键状态并执行相应的操作 if (P1 == 0x7f) { // 按下K1 increase_counter(); // 增加计数器的值 } else if (P1 == 0xbf) { // 按下K2 decrease_counter(); // 减少计数器的值 } else if (P1 == 0xdf) { // 按下K3 reset_counter(); // 重置计数器的值 } } } // 延时函数 void delay(unsigned int ms) { unsigned int i, j; for (i = 0; i < ms; i++) { for (j = 0; j < 110; j++); } } // 数码管显示函数 void display(unsigned int num) { unsigned int i, j; unsigned char seg_data[4]; // 将数字转换为数码管编码 seg_data[0] = SEG_TABLE[num / 1000]; seg_data[1] = SEG_TABLE[num % 1000 / 100]; seg_data[2] = SEG_TABLE[num % 100 / 10]; seg_data[3] = SEG_TABLE[num % 10]; // 循环显示四个数码管 for (i = 0; i < 4; i++) { P0 = seg_data[i]; P2 = POS_TABLE[i]; // 为了避免闪烁,每个数码管显示的时间很短,需要延时一段时间 for (j = 0; j < 50; j++); } } // 重置计数器 void reset_counter() { counter = 0; } // 增加计数器的值 void increase_counter() { counter++; if (counter >= 10000) { counter = 0; } delay(10); // 防止多次触发 } // 减少计数器的值 void decrease_counter() { if (counter == 0) { counter = 9999; } else { counter--; } delay(10); // 防止多次触发 } ``` 这段代码使用了P0口和P2口来控制数码管的显示,使用P1口来读取按键的状态。按下K1键可以增加计数器的值,按下K2键可以减少计数器的值,按下K3键可以重置计数器的值。要注意的是,为了避免按键反复触发,需要在每次按键后延时一段时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值