本帖最后由 t176 于 2023-5-5 11:30 编辑
Lesson 7
数码管实践(静态和动态扫描)
段码讲解:
通过上一课的学习,我们已经能点亮指定数码管中的一个发光二极管通道
我们接下来通过仿真的方式学习下,段码和位码的原理
首先在ISP 中将试验箱设置成仿真
因为代码很简短,我们直接F8 单步调试到while 中,进行空循环
我们再观察试验箱的 现象,已经成功点亮数码管 的F通道
我们在仿真中,查看下内存的段码 数据
我们可以看到 P6 的数据是DF 我们将它转换成二进制 ,再和数码管的排序进行比对
眼尖的小伙伴们 应该发现规律
1 1 0 1 1 1 1 1 二进制
dp G F E D C B A 对应段码
小知识点:
dp:就是小数点,有的数码管样式是: 也是dp位.
因为试验箱中使用的共阳数码管,也就是说, IO口为0情况下,通道才能点亮.
是不是 很简单,明白了 这个道理,那么我们应该如何点亮 一个数字5呢?
我们通过刚才的学习,将它转成二进制
1 0 0 1 0 0 1 0 二进制
dp G F E D C B A 对应段码
10010010 B = 92 H
现在去内存中将DF,修改成92 试试.
我们看下试验箱的 现象:
是不是很简单.........段码讲完了.....别说你没弄明白
位码讲解:
段码我们已经学习完了,现在说说位码,刚才的实验现象可以看到,5显示在 第一位数码管上 如果我们需要让他显示在第二位数码管应该怎么做呢?
从之前的原理图中我们了解过,位控制位COM0-7
使用P7IO口 进行控制,那么我们去看下内存中的P7数据
我们将7F HEX转换成二进制 01111111,是不是很熟悉. 那么如果显然他 点亮第二位 是不是只要改成 10111 1111 再将10111 1111 B 转换成HEX 是 BF
我们也去内存中将 P7的数据改成 BF HEX
我们再观察下实验现象:
是不是已经达到我们的预期效果.理解了 段码后,位码 是不是感觉好简单....
根据刚才学的知识 你可以根据数码管 制造 很多奇奇怪怪的 字符 ,甚至,可以通过 流程控制 写一个 花样流水灯.
实际数码管应用中,我们比较常见的 还是数字和简单的英文.下面我给整理出来了,这样你就不需要自己一个个的去制造段码了.
试验箱中使用的共阳:
- unsigned char code leddata[]={
-
- 0xC0, //"0"
- 0xF9, //"1"
- 0xA4, //"2"
- 0xB0, //"3"
- 0x99, //"4"
- 0x92, //"5"
- 0x82, //"6"
- 0xF8, //"7"
- 0x80, //"8"
- 0x90, //"9"
- 0x88, //"A"
- 0x83, //"B"
- 0xC6, //"C"
- 0xA1, //"D"
- 0x86, //"E"
- 0x8E, //"F"
- 0x89, //"H"
- 0xC7, //"L"
- 0xC8, //"n"
- 0xC1, //"u"
- 0x8C, //"P"
- 0xA3, //"o"
- 0xBF, //"-"
- 0xFF, //熄灭
- 0x92 //自定义
-
- };
复制代码
当然,市面还有共阴,这里为了以后你们方便我也提供下:
- unsigned char code leddata[]={
-
- 0x3F, //"0"
- 0x06, //"1"
- 0x5B, //"2"
- 0x4F, //"3"
- 0x66, //"4"
- 0x6D, //"5"
- 0x7D, //"6"
- 0x07, //"7"
- 0x7F, //"8"
- 0x6F, //"9"
- 0x77, //"A"
- 0x7C, //"B"
- 0x39, //"C"
- 0x5E, //"D"
- 0x79, //"E"
- 0x71, //"F"
- 0x76, //"H"
- 0x38, //"L"
- 0x37, //"n"
- 0x3E, //"u"
- 0x73, //"P"
- 0x5C, //"o"
- 0x40, //"-"
- 0x00, //熄灭
- 0x6D //自定义
-
- };
复制代码
接下来是 位码表:
- unsigned char code WEI_data[] = {
- 0x7f, // 0111 1111 b 0
- 0xbf, // 1011 1111 b 1
- 0xdf, // 1101 1111 b 2
- 0xef, // 1110 1111 b 3
- 0xf7, // 1111 0111 b 4
- 0xfb, // 1111 1011 b 5
- 0xfd, // 1111 1101 b 6
- 0xfe, // 1111 1110 b 7
- } ;
复制代码
静态扫描:
好了段码表和位码表 都提供了.现在,可以写一个小程序巩固下:
- #include <STC32G.H>
-
- unsigned char code WEI_data[] = {
- 0x7f, // 0111 1111 b 0
- 0xbf, // 1011 1111 b 1
- 0xdf, // 1101 1111 b 2
- 0xef, // 1110 1111 b 3
- 0xf7, // 1111 0111 b 4
- 0xfb, // 1111 1011 b 5
- 0xfd, // 1111 1101 b 6
- 0xfe, // 1111 1110 b 7
- };
-
- unsigned char code leddata[] = {
-
- 0xC0, //"0"
- 0xF9, //"1"
- 0xA4, //"2"
- 0xB0, //"3"
- 0x99, //"4"
- 0x92, //"5"
- 0x82, //"6"
- 0xF8, //"7"
- 0x80, //"8"
- 0x90, //"9"
- 0x88, //"A"
- 0x83, //"B"
- 0xC6, //"C"
- 0xA1, //"D"
- 0x86, //"E"
- 0x8E, //"F"
- 0x89, //"H"
- 0xC7, //"L"
- 0xC8, //"n"
- 0xC1, //"u"
- 0x8C, //"P"
- 0xA3, //"o"
- 0xBF, //"-"
- 0xFF, // 熄灭
- 0x92 // 自定义
-
- };
-
- void Delay500ms() //@11.0592MHz
- {
- unsigned long i;
-
- _nop_();
- _nop_();
- i = 1382398UL;
- while (i)
- i--;
- }
-
- void main()
- {
-
- int DUAN = 0, WEI = 0, i = 0;
- WTST =0X00;
- P6M0 = 0x00;
- P6M1 = 0x00;
- P7M0 = 0x00;
- P7M1 = 0x00;
-
- while (1)
- {
- for (i = 0; i < 8; i++)
- {
-
- P7 = WEI_data[i];
- P6 = leddata[i];
- Delay500ms();
- }
- }
- }
复制代码
试验箱现象:
通过上面的实验,我们发现只能显示一位数码管或者几位相同的数字数码管,那么有什么办法同时显示多位并且不同的数值呢呢?,这就引出 我们下面这一部分的内容:
动态扫描:
动态扫描是一种常见的多路复用显示方法,基本原理是将要显示的数字分别输出到每个数码管上,由于人眼的视觉暂留效应,数码管快速切换时会产生“看起来同时显示”的效果。
当系统的刷新率高于人眼视觉的响应速度,人眼就无法察觉到数码管的闪烁,而是错觉它们在同时显示。
在动态扫描中,每次只有一个数码管被选通,其他数码管都处于关闭状态。
所以当数码管每次切换的速度足够快,就能达到动态扫描的目的
其原理 也非常的简单.我们传入一个值只要将每一位上的数据存到一个数组中,然后用极短的时间去切换显示每一位数码管.下面是实现代码
- #include <STC32G.H>
-
- unsigned char code WEI_data[] = {
- 0x7f, // 0111 1111 b 0
- 0xbf, // 1011 1111 b 1
- 0xdf, // 1101 1111 b 2
- 0xef, // 1110 1111 b 3
- 0xf7, // 1111 0111 b 4
- 0xfb, // 1111 1011 b 5
- 0xfd, // 1111 1101 b 6
- 0xfe, // 1111 1110 b 7
- };
-
- unsigned char code leddata[] = {
-
- 0xC0, //"0"
- 0xF9, //"1"
- 0xA4, //"2"
- 0xB0, //"3"
- 0x99, //"4"
- 0x92, //"5"
- 0x82, //"6"
- 0xF8, //"7"
- 0x80, //"8"
- 0x90, //"9"
- 0x88, //"A"
- 0x83, //"B"
- 0xC6, //"C"
- 0xA1, //"D"
- 0x86, //"E"
- 0x8E, //"F"
- 0x89, //"H"
- 0xC7, //"L"
- 0xC8, //"n"
- 0xC1, //"u"
- 0x8C, //"P"
- 0xA3, //"o"
- 0xBF, //"-"
- 0xFF, // 熄灭
- 0x92 // 自定义
-
- };
- /*
- *----------------------------------------------------------------------------------------------
- * 函数名称:void Delay2ms()
- * 函数功能:延迟2ms
- * 入口参数:@
- * 函数返回:@
- * 当前版本: Ver1.0
- * 修改时间:2023/05/05 10:45:07
- * 作者:t176#qq.com
- * 创建时间:2023/05/05 10:45:07
- -----------------------------------------------------------------------------------------------
- */
- void Delay2ms() //@11.0592MHz
- {
- unsigned long i;
-
- _nop_();
- i = 5528UL;
- while (i)
- i--;
- }
-
- /*
- *----------------------------------------------------------------------------------------------
- * 函数名称:void Display( long val)
- * 函数功能:拆分一个长整型,数码管每一位显示相关数据
- * 入口参数:@
- * 函数返回:@
- * 当前版本: Ver1.0
- * 修改时间:2023/05/05 10:43:11
- * 作者:t176#qq.com
- * 创建时间:2023/05/05 10:43:11
- -----------------------------------------------------------------------------------------------
- */
- void Display(long val)
- {
- int val_arr[8]; // 定义一个大小为8的整型数组
-
- int i, j = 0;
- while (val != 0)
- {
- val_arr[j] = val % 10; // 取num的最后一位,存入数组
- val /= 10; // 缩小10倍
- j++; // 移动数组下标
- }
-
- for (i = 0; i < j; i++)
- {
- P6 = 0XFF; // 清除鬼影
- P7 = WEI_data[j - i - 1]; // 位选择(j-i-1)反转显示
- P6 = leddata[val_arr[i]]; // 段选择
-
- Delay2ms();
- }
- }
- void main()
- {
-
- WTST = 0X00; // 速度最快
- P6M0 = 0x00;
- P6M1 = 0x00;
- P7M0 = 0x00;
- P7M1 = 0x00;
-
- while (1)
- {
- Display(1254680);
- }
- }
复制代码
试验箱现象:
|