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

📄 -

📁 动态数码LED 显示,3片HC595首尾相连,8位串入并出,供初学51调试程序参考
💻
字号:
单片机数码管动态显示程序实验
 

【字体:大 中 小】 

来源:恒坚电器    作者:恒坚

 

// 单片机数码管动态显示程序实验,
  数码管显示一般分静态显示及动态显示两种驱动方式,静态显示占用口线比较多,本文介绍的是如何实现数码管动态显示,应该说数码管动态显示是单片机外部指令输出的重要途径,因此如何设计数码管以及数码管的工作原理、数码管显示的方法、数码管显示的抗干扰设计等在单片机系统设计中占有重要地位。这个例子在系统硬件的基础上设计了软件查询程序、软件延时程序(防止干扰),大致讲述了一种数码管动态显示的工作原理与读取方式。  
 
        s1     bit  p0.0        ;数码管位定义
        s2     bit  p0.1
        s3     bit  p0.2
        s4     bit  p0.3
        s5     bit  p0.4
        s6     bit  p0.5
        s7     bit  p0.6
        s8     bit  p0.7

 led_data   equ  p2      ;数码管数据定义

 org 00h                 ;程序开始
 jmp main                ;主程序开始处 

 org 030h                ;主程序从30H开始
 main:  mov sp,#30h             ;设置堆栈
        lcall rest              ;调用初始化程序
        lcall pro_8led          ;调用数码管显示程序
        jmp main                ;返回

;********* 初始化程序  **************
   
   rest:mov a,#00h              ;清寄存器
 mov b,#00h              ;清寄存器
 mov p0,#0               ;禁止数码管显示
 mov p2,#255             ;
 mov p1,0ffh             ;禁止LED显示
        clr beep                ;禁止蜂鸣器
     ret                        ;返回

;********  数码管显示程序  ***************
pro_8led:
 mov b,#32                ;一共显示32个数字
 clr psw.3                ;重新设置寄存器组
 setb psw.4               ;

 mov r0,#00h              ;数据显示从0开始
 mov r1,#01h              ;数码管从第1个开始
   loop:mov p0,r1                ;点亮当前数码管
    mov a,r0                 ;准备第一个数据
 mov dptr,#tab_nu         ;获得表头
 movc a,@a+dptr           ;得到第一个数据
 mov led_data,a           ;输出到显示数据口
                
        lcall delay              ; 500 ms 延时
        lcall delay              ; 1   s  延时
        inc r0                   ;准备下一个数据
        mov a,r1                 ;准备下一位数码管
        rlc a                    ;设置下一个数码管
        jc c1                    ;8位全部显示,转移
        mov r1,a                 ;否则,设置下一位
        djnz b,loop              ;32个数没有显示完,返回显示    
        ret                      ;否则返回主程序

c1:   mov r1,#1                  ;8位显示完,重新开始循环
        clr c                    ;设置显示位
        djnz b,loop              ;32位显示完则返回重新显示
        ret                      ;否则返回到主程序
;*************  数码管显示   *******************************

;*************  软件延时 500ms  *****************************
delay:  push psw              ; 保存原来的寄存器内容
        clr psw.3             ;
 clr psw.4             ; 设置新的寄存器组
 mov r0,#2             ; 延时参数1
 mov r1,#250           ; 延时参数2 
 mov r2,#2             ; 延时参数3
    dl1:djnz r0,dl1           ; 延时循环1
     mov r0,#250           ;
    dl2:djnz r1,dl1           ; 延时循环2
        mov r0,#240           ;
        mov r1,#248           ;
    dl3:djnz r2,dl1           ; 延时循环3
 nop                   ; 定时精度调整
 pop psw               ;  恢复原来的寄存器
        ret                   ;   返回
;**********************************************************

;**********************************************************
;这是数字显示表格,其中 带小数点的数字比不带小数点的数字大16
; 比如 0 的显示代码为 0;那么 0.的显示代码为 16;如此类推

tab_nu: 
       db 0c0h,  0f9h, 0a4h,  0b0h,  99h ,  92h ,  82h, 0f8h ; 数字0-7 不带小数点代码
       db 80h ,  90h,  88h ,  83h ,  0c6h,  0a1h,  86h, 8eh  ; 数字8-f   不带小数点代码
       db 40h ,  79h,  24h ,  30h ,  19h ,  12h ,  02h, 78h  ; 数字0-7  带小数点代码
       db 00h ,  10h,  08h ,  03h ,  46h ,  21h ,  06h, 0eh  ; 数字8-f   带小数点代码

      end   

 


;c语言
************************************************
//分别控制p0/p2的数据,就可以显示不同的数据
//现象,8个数码管依次显示0-F. 共 32 个数

#include <8051.h>

void delay(unsigned char times);
void display(unsigned char disseg,unsigned char disdata);

// 这里定义的是数码管对应的字符字根
code unsigned char disbuf_u[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,
                               0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,
                               0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,
                               0x00,0x10,0x08,0x03,0x46,0x21,0x06,0x0e};
void main()
{
    int k;
    P1 = 255;          //关闭LED显示
    P0 = 0;            //关闭数码显示
    P2 = 255;          //
 
    
  while(1)             //设置一个无限制循环
 {  for(k=0;k<32;k++)
    { delay(255);      //延时 
      display(k%8,k);
    } 
  }
}

//下面是延时程序。具体的延时时间不能通过表面程序看出,(为什么?)
//如果我们需要一个精密的延时程序,那么我们可以采用内嵌汇编代码的方式
void delay(unsigned char times)
{
    int t=25000;           //延时倍数
    unsigned char i=times;   
    for(;i!=0;i--)
    {for(;t!=0;t--){}}
}


//这里是显示子程序,入口参数为
// disseg  -> 位选 可选范围 0-7 一共8个数码管
// disdata -> 段选 可选范围 0-31 一个32个字符
//  段选 0-15  16个字符 为 "0"->"F"
//  段选 16-31 16个字符 为 "0."->"F."

void display(unsigned char disseg,unsigned char disdata)
{
    unsigned char dataf;
        dataf = 1;
    while(disseg)
    {
      dataf <<= 1;
      disseg--;
    }
     P0 = dataf;
      P2 = disbuf_u[disdata];
}

⌨️ 快捷键说明

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