1、项目分析
- 通过演示数码管动态显示的操作过程。
2、技术准备
1、 数码管动态显示
4个1位数码管和单片机如何连接
a、静态显示的连接方式
- 优点:不需要动态刷新;
- 缺点:占用IO口线多。
b、动态显示的连接方式
- 连接:所有位数码管的段选线并联在一起,由位选线控制是哪一位数码管有效;
- 缺点:需要动态刷新;
- 优点:占用IO口线少。
2、动态扫描的原理
- 动态显示是多个数码管,交替显示,利用人的视觉暂停作用使人看到多个数码管同时显示的效果(就像看的电影是有一帧一帧的画面显示的,当速度够快的时候看到它就是动态的,当显示数码管的速度够快的时候,也就可以看到它们是同时显示了)
- 所谓动态扫描显示即轮流向各位数码管送出字形码和相应的位选,利用发光管的余辉和人眼视觉暂留作用,使人的感觉好像各位数码管同时都在显示。
- 动态显示的亮度比静态显示的亮度低,所以在选择限流电阻时应小于静态显示电路中电阻值。
3、项目实施
1 一位数码管动态显示
实验需求:
- 第1位数码管从 0 - 9 循环显示
- 第1位数码管从 0 - 9 循环显示
实验分析
- 位选:第1位数码管(P2.4)工作设置为1,其他3个数码管不工作设置为0
- 段选:需要数码管显示0-9,则可使用数组存储 0-9 的十六进制值。
- 设置段选,循环中遍历数组中的值,并赋值给段P0。
实验代码
#include<reg52.h> #define pos P2 // 显示数值表0-9 unsigned char code dofly_table[10] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; // 函数声明 void Delay(unsigned int t); void main() { unsigned char i; pos = 0x18; while (1) { for (i = 0; i < 10; i++) { P0 = dofly_table[i]; Delay(60000); } } } /*------------------------------------------------ 延时函数,含有输入参数 unsigned int t,无返回值 unsigned int 是定义无符号整形变量,其值的范围是0~65535 ------------------------------------------------*/ void Delay(unsigned int t) { while (--t); }
2 数码管左移流动显示
- 实验需求:
- 在左数第4位数码管显示4,过1秒,
- 在左数第3位数码管显示3,过1秒,
- 在左数第2位数码管显示2,过1秒,
- 在左数第1位数码管显示1,过1秒,
- 上述过程不断循环
- 实验分析
- 位选:循环让4个数码管工作
- 段选:让对应的位分别显示 4 3 2 1
- 实验代码
- 方式1:按位逐一设置显示
#include <REGX52.H> #define par P0 #define pos P2 #define uchar unsigned char #define void delay(unsigned int xms); // 分别对应:1/2/3/4 uchar code sz[] = {0x06, 0x5b, 0x4f, 0x66}; void main() { while (1) { pos = 0x88; par = sz[3]; delay(1000); pos = 0x48; par = sz[2]; delay(1000); pos = 0x28; par = sz[1]; delay(1000); pos = 0x18; par = sz[0]; delay(1000); } } void delay(unsigned int xms) { unsigned int i, j; for(i=xms; i>0; i--) { for(j=112; j>0; j--); } return 0; }
- 方式2:定时器 + 数组遍历
#include <reg52.h> #define uint unsigned int // 定义端口:P2/P0、2个数组(存储位选与段选值)、定时器次数、数组索引 #define pos P2 #define par P0 uint posValues[] = {0x18, 0x28, 0x48, 0x88}; uint parValues[] = {0x06, 0x5b, 0x4f, 0x66}; uint count = 0; uint index = 3; void main2() { // 3.1 设置工作模式 TMOD = 0x01; // 3.2 设置初值 - 50ms --> 次数 * 机器周期 = 0.05s -> 次数 = 0.05 * 12 * 10^6 / 12 TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; // 3.3 打开“开关” EA = 1; TR0 = 1; ET0 = 1; while(1); } // 中断函数 void timer0() interrupt 1 { TH0 = (65536 - 50000) / 256; TL0 = (65536 - 50000) % 256; count++; if(count == 20) // 1s { count = 0; pos = posValues[index]; par = parValues[index]; if(index <= 0) { index = 4; } index--; } }
3 数码管数字0转圈显示
实验要求
- 使用第1位数码管的 a b c d e f 六段依次点亮
- 使用第1位数码管的 a b c d e f 六段依次点亮
实验分析
效果 h g f e d c b a a亮 0 0 0 0 0 0 0 1 b亮 0 0 0 0 0 0 1 0 c亮 0 0 0 0 0 1 0 0 d亮 0 0 0 0 1 0 0 0 e亮 0 0 0 1 0 0 0 0 f亮 0 0 1 0 0 0 0 0 代码实现
#include <reg52.h> #define pos = P2; unsigned int temp; unsigned char i; void delay(unsigned int t); void main() { pos = 0x18; while (1) { P0 = 0xff; for (i = 0; i < 6; i++) { delay(10000); temp = 0x01 << i; P0 = temp & 0xff; } } } void delay(unsigned int t) { while (t--); }
4 数码管显示00-99
实验要求
- 使用2位数码管显示00-99,每次间隔1s,如果到99则重新从0开始
- 使用2位数码管显示00-99,每次间隔1s,如果到99则重新从0开始
实验分析
- 位选:使用第1位数码管显示十位,第2位数码管显示个位
- 段选:使用变量记录两位数,在每1秒中对该变量加1,同时分别取出个位与十位,对应到存储0-9的数组中取出对应的数,用于段选的值。
实验代码:
#include <reg52.h> // 宏定义:简写 unsigned int #define uint unsigned int sbit pos = P2; // 分别对应:0/1/2/3/4/5/6/7/8/9 int code_sz[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f}; // 函数声明 void show_ge(uint x); void show_shi(uint y); void delay(uint xms); uint val = 0; // 记录显示的2位数 uint ge, shi; void main() { while (1) { val++; // 计数值增加1 if (val > 99) val =0; // 如果计数值大于99,则重新从0开始 ge = val % 10; // 计算个位的值 shi = val / 10; // 计算十位的值 show_shi(shi); // 调用显示十位的函数 delay(10); // 延时10ms,让十位数显示保持 show_ge(ge); // 调用显示个位的函数 delay(10); // 延时10ms,让十位数显示保持 pos = 0; // 位选复位(避免出现位选错乱,产生乱码) } } // 显示个位数字:左起第2位数码管 void show_ge(uint x) // x:计算的个位数的值,对应数组中的索引,从而取到对应的值 { P0 = 0x00; // P0(段选位)复位 pos = 0x28; // 第2位数码管 P0 = code_sz[x]; // 数组索引取到对应的数字值赋值给P0 } void show_shi(uint y) // y:计算的十位数的值,对应数组中的索引,从而取到对应的值 { P0 = 0x00; // P0(段选位)复位 pos1 = 0x18; // 选择第1位数码管 P0 = code_sz[y]; // 数组索引取到对应的数字值赋值给P0 } void delay(uint ms) // 延时指定的毫秒(错略延时) { uint i, j; for(i=ms; i>0; i--) { for(j=112; j>0; j--); } }