数码管作为最廉价的输出设备,在各种自动化设备中有很大的应用,最简单普通的显示方式为动态刷新显示,称为假动态显示,即通过分时扫描每一位,利于人眼的视觉停留现象,造成一种静态显示的效果,如下图所示:

C51单片机由于运行速度很慢,在高刷新频率下,单片机的资源耗费很厉害,这样单片机就不可以再进行大量的计算工作,实际上,单片机在刷新时,只需要周期性的改变GPIO口的状态就可以了,剩下的时间其实都是在空转的状态下,我们能不能将这个空转的状态拿来用呢?当然是可以的啦,这里,我们利用单片机的定时器周期地产能中断,在中断内进行数码管的刷新工作,就可以将等待中断的这个CPU时间拿来做别的事情了。

硬件电路:

代码贴过来:

主函数

#include "shumaguan.h"
#include "timer.h"sbit sw_jdq=P1^0;//定义一位继电器操作
void main(void)
{int cnt=0;//设定初值timer_init();//初始化定时器while(1){value_now = cnt;//送初值到显示缓存delay(50);cnt++;sw_jdq=~sw_jdq;//切换继电器状态if(cnt>9999)//数值超出界线,回归最小cnt=-999;}
}

数码管驱动函数

#include "shumaguan.h"#define DType    1           //define the Digital LED type, 1: VCC in common, 0: GND in common
#if DType==1
/*--------------------------------------------------------
Set the digital LED display code
From left to right for
0,1,2,3,4,5,6,7,8,9,a.b,c,d,e,f,dp,-,
--------------------------------------------------------*/
uchar code DS_BUF[]={0xc0 , 0xf9 , 0xa4 , 0xb0 , 0x99 , 0x92 , 0x82 , 0xf8 , 0x80 , 0x90 , 0x88 ,
0x83 , 0xc6 , 0xa1 , 0x86 , 0x8e , 0x7f , 0xbf , 0xff };
#else
uchar code DS_BUF[]={0x3f , 0x06 , 0x5b , 0x4f , 0x66 , 0x6b , 0x7d , 0x07 , 0x7f , 0x6f , 0x77 ,
0x7c , 0x39 , 0x5e , 0x79 , 0x71 , 0x80 , 0x40 , 0x00 };
#endif
uchar xdata buf_sm[4];            //set display bufferuchar frash_cnt=0;//刷新计数器
uchar wei_buf=0x10;//位输出计数器/*--------------------------
Compute the number from Value
value: something to display, range from -999 to 9999, suport float
--------------------------*/
void calc_sm(float value)
{uint tmp=0;if(value>=0)//输入值为正数,不显示负号{if(value>9999)//输入值大于9999,显示----{buf_sm[0]=17;buf_sm[1]=17;buf_sm[2]=17;buf_sm[3]=17;}else if(value>=1000)//输入值大于999,只显示整数{tmp=value;buf_sm[0]=tmp/1000;buf_sm[1]=tmp%1000/100;buf_sm[2]=tmp%100/10;buf_sm[3]=tmp%10;}else if(value>=100)//显示一位小数{tmp=value*10;buf_sm[0]=tmp/1000;buf_sm[1]=tmp%1000/100;buf_sm[2]=(tmp%100/10)+20;buf_sm[3]=tmp%10;}else if(value>=10)//显示两位小数{tmp=value*100;buf_sm[0]=tmp/1000;buf_sm[1]=(tmp%1000/100)+20;buf_sm[2]=tmp%100/10;buf_sm[3]=tmp%10;}else//显示三位小数{tmp=value*1000;buf_sm[0]=(tmp/1000)+20;buf_sm[1]=tmp%1000/100;buf_sm[2]=tmp%100/10;buf_sm[3]=tmp%10;}}else//输入值小于0,显示负号,其余同上{if((value<0)&&(value>-10)){tmp=value*100;tmp=abs(tmp);buf_sm[0]=17;buf_sm[1]=(tmp/100)+20;buf_sm[2]=tmp%100/10;buf_sm[3]=tmp%10;}else if((value<=-10)&&(value>-100)){tmp=value*10;tmp=abs(tmp);buf_sm[0]=17;buf_sm[1]=(tmp/100);buf_sm[2]=tmp%100/10+20;buf_sm[3]=tmp%10;}else if((value<=-100)&&(value>-1000)){tmp=value;tmp=abs(tmp);buf_sm[0]=17;buf_sm[1]=(tmp/100);buf_sm[2]=tmp%100/10;buf_sm[3]=tmp%10;}}}
/*
显示部分,每执行一次,显示的位左移一位,移到最左边时,重新回到最右边,开始下一次刷新。
定义有小数点的位+20,每次送断码,检查大于20,段与0x7f添加小数点。
*/
void display()
{if(frash_cnt<=3){wei |=0xf0;//数码管的消隐if(buf_sm[3-frash_cnt]>=20){duan = (DS_BUF[(buf_sm[3-frash_cnt])-20]&0x7f);//显示小数点}elseduan = DS_BUF[buf_sm[3-frash_cnt]];//不显示小数点wei = ~wei_buf;wei_buf <<=1;//显示位左移一位frash_cnt++;}else{wei |=0xf0;//数码管的消隐frash_cnt=0;wei_buf=0x10;//显示位回到最右边}
}
/*
数码管自用延时
*/
void delay(uint i)
{uchar j;for(;i>0;i--)for(j=0;j<120;j++);}

数码管头文件

#ifndef _shumaguan_h_
#define _shumaguan_h_
#include "math.h"
#include "reg52.h"
#define duan P0
#define wei P2#define uchar unsigned char
#define uint unsigned intextern uchar frash_cnt;
extern uchar wei_buf;void calc_sm(float value);
void display();
void delay(uint i);#endif

定时器配置及中断服务函数

#include "reg52.h"
#include "timer.h"
#include "shumaguan.h"float xdata value=0 , value_now = 0;void timer_init()
{TMOD = 0x02;                    //set timer0 as mode1 (16-bit)TL0 = T1MS;                     //initial timer0 low byteTH0 = T1MS;                //initial timer0 high byteTR0 = 1;                        //timer0 start runningET0 = 1;                        //enable timer0 interruptEA = 1;                         //open global interrupt switch
}/* Timer0 interrupt routine */
void tm0_isr() interrupt 1 using 1
{if(value!=value_now)//检测显示值与当前值是否匹配{value=value_now;//刷新显示值calc_sm(value_now);//重新计算显示值的输出缓冲区}display();//刷新数码管显示}

定时器头文件

#ifndef _timer_h_
#define _timer_h_
#include "reg52.h"
#define uchar unsigned char
#define uint unsigned int//-----------------------------------------------/* define constants */
//#define FOSC 11059200L
#define FOSC 12000000L#define T1MS 0   //1ms timer calculation method in 12T mode//-----------------------------------------------extern float xdata value , value_now;void timer_init();#endif

C51单片机数码管动态显示相关推荐

  1. 蓝桥杯单片机数码管动态显示_单片机静态动态数码管

    单片机系统中常用的显示器有: 发光二极管LED(Light Emitting Diode)显示器.液晶LCD(Liquid Crystal Display)显示器.TFT液晶显示器等.LED显示器有两 ...

  2. STC89C52单片机 数码管动态显示

    数码管动态显示 静态与动态显示 动态显示 动态显示的特点是将所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效.选亮数码管采用动态扫描显示.所谓动态扫描显示即轮流向各位数码管送出字形码和相 ...

  3. c语言数码管流动显示一个数,51单片机数码管动态显示 - 数码管动态扫描显示01234567程序(三种方案)...

    数码管动态扫描显示01234567程序二--51单片机动态显示共阳数码管01234567 原理图 c语言程序 程序如下: #include #define uint unsigned int #def ...

  4. c51单片机数码管的控制

    电路图 注:实际中,我单片机的74HC573电路接法与P0端接反了 138译码器资料:https://pan.baidu.com/s/1COTcutsnMxMSc8tq0M2yVw 密码:1jww 1 ...

  5. 单片机——数码管动态显示

    1.头文件和定义,代码还使用了 sbit 定义来声明了两个变量 duan 和 wei,它们实际上是 P2.6 和 P2.7 端口的别名,用于控制数码管的段选和位选信号.这种方法可以使代码更具可读性,并 ...

  6. 蓝桥杯单片机数码管动态显示_关于蓝桥杯训练小程序 中断控制数码管显示数字的左右移动...

    /******************************************************************************************** 利用数码管在 ...

  7. C51单片机的电子时钟(数码管显示)

    C51单片机的电子时钟 硬件环境: 相关开发板原理图解析 正式代码: 效果预览图 硬件环境: 普中科技51单片机开发板STC89C52 相关开发板原理图解析 查看这两个原理图,我们可以发现控制这8个数 ...

  8. C51数码管动态显示+AD转换

    老师让做AD转换的实验,并把转换结果用数码管显示出来.由于疫情的原因,没有C51的小试验箱,就只能用protues进行仿真. 一.AD部分 AD转换我用的是ADC0808芯片.ADC0808的内部结构 ...

  9. STC8H8K系列汇编和C51实战——实现键控不同方式数码管动态显示(C51版和汇编版)

    51和汇编分别实现键控不同方式数码管动态显示 前言 一.实验名称 二.实验内容与要求 三.代码 1.51部分 2. 汇编部分 总结 系列文章--STC8H8K系列汇编51实战 前言 个人对这个实验的汇 ...

最新文章

  1. 安装模拟器遇到的问题
  2. fix--向零方向取整
  3. 【小白学PyTorch】9.tensor数据结构与存储结构
  4. JDK12的新特性:teeing collectors
  5. vs2013 c# 中调用 c 编写的dll出错的可能错误
  6. oc引导windows蓝屏_跟电脑蓝屏say no!【亲测有效】
  7. js年会抽奖_嘿!这真的是一个正经的抽奖程序!
  8. 谁在使用Docker?
  9. hdu3787 A+B
  10. 过滤Filtering
  11. ADB常用命令及详解
  12. 【渝粤题库】广东开放大学 财务会计(1) 形成性考核
  13. MYSQL基础(sql语句)
  14. 空气净化器什么牌子好,家用空气净化器哪个牌子好推荐
  15. 常见基础注入类型-SQL注入-web安全
  16. 【CH9434】使用CH9434移植到32单片机扩展4串口
  17. python车牌识别系统开源代码_python+opencv实现车牌定位功能(实例代码)
  18. 摄像头poe供电原理_如何区分摄像头是否支持PoE供电摄像头?
  19. 计网第三章复习(数据链路层)
  20. 鸿蒙智慧屏pro,鸿蒙OS带来了什么?荣耀智慧屏PRO现场轻体验

热门文章

  1. 小米Pro 安装Ubuntu,以及安装成功之后,各种关机重启的卡死问题
  2. 佛祖保佑 永无shell
  3. 数据库设计三大范式:
  4. 进行的vistor实验
  5. 基于JavaSwing开发天猫购物商城系统(用户 管理员角色) 课程设计 毕业设计源码
  6. JAVA学习数据库2
  7. 随手查_python
  8. oracle使用小技巧,Oracle在linux下使用小技巧
  9. 剑指Offe面试题:用两个栈实现队列
  10. C++课堂笔记0716