马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 Mike_python小 于 2023-1-19 09:17 编辑
51单片机 静态/动态数码管
数码管在我们的生活中非常常见,但是这节课可能有点不一样
你需要学习2进制转16进制(1248码)
和10进制转2进制(短除法)
1248码
比如我有一串2进制,10100010,使用1248码转换16进制就应该这么写:
1248码从右向左写
二进制先写右边的,依次对应
如果二进制不从右向做写的话,可能出现以下问题:
101001
第一个结果是29,而第二个是A4
在16进制中,A代表着10,B代表着11,以此类推
总结:
1248和二进制从右向左写,最后读数正读
短除法
10进制转2进制的短除法非常简单
比如我要短除23这个数
先用23/2=11余1
然后以此类推
到1/2=0余1的时候也就结束了
最后从下往上读,结果就是10111
我们一般采用第二种写法,第一种是方便大家理解
静态数码管
说了这么多了,该说说静态数码管了
这是一个数码管的原理图,上面是共阳,下面是共阴,我用的数码管就是共阴的
共阴极:当某个发光二极管的阳极为高电平时,发光二极管点亮,相应的段被显示。
共阳极:将所有发光二极管的阳极接到一起形成公共阳极(COM)的数码管。
如右图所表,数码管上的8个小部分分别对应着几个IO口,所以我们只需要接通他们相对应的IO口,就可以实现点亮
比如我想点亮一个6,就需要知道abcdefg dp中需要哪个给1
AFGCDE,这几个点亮就可以变成一个6
所以我们看右图这几个对应的引脚
74219 10,把这几个引脚点亮就行了(PS:点亮需要给16进制,这里的太乱了,我懒得算了,等后面再算)
但是这只是一个数码管啊,我们的是4个连城一体的啊
看到这么多先不要着急,听我慢慢到来
首先左边的那些我们都不用看,只看两个大黄色的数码管就可以
这个数码管跟我们看到的一个的数码管很想,从下方都截出来了abcdefg dp这8个引脚,但是有一个问题,我们这8个数码管练成一体了,怎么就出来8条线(1一个数码管的线)?不应该是8x8=64条线吗?!
厂家为了减少IO口,就用了以下的方法:
看没看见每个数码管上方的LED8,LED7等等?这就是妙处
我们想要点亮比如说LED8的abcd,我们先给LED8一个1,就表明我们只要点亮led8,其他的是熄灭的,然后再把abcd点亮就行了~
如何把abcd点亮
我们把abcd点亮和单个数码管的一样,需要给abcd “1”,其他的 “0”
再从下网上数就是00001111,转化为16进制就是 0x0F
再看左侧,引脚都是P01,P02,P03,这时候我们采用统一赋值,给P0 = 0x0F
就可以把abcd点亮了
如何把LED8点亮
看这张图的右边,LED8对应着Y7,LED6对应着Y6,LED5对应着Y5
再看这张图的左边,有P22, P23, P24
这是有就有人要说了,为什么8个数码管用3个IO口就能控制????
好问题,这也是节省IO口的妙用
3个IO口正好可以表现0~7的10进制,比如P22, P23, P24都为1的时候就是7,都为0的时候就是0
那要控制LED7就是111,从下网上读对应的就是P24是1,P23也是1,P22也是1
那要控制LED6呢?就是110, P24是1,P23是1,P22就是0了
注意!二进制第一位要对应P24而不是P22
通过代码实现
#include <8052.h>
void main() {
P2_4=1;
P2_3=1;
P2_2=1;
P0 = 0x7D;
while (1) {
}
}
这里,我给大家总结了一个库,你们直接调用这个库就行
nixie.c
#include "Sleep.h"
#include <8052.h>
char num[18] = {
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x00
};
void Nixie(unsigned char weizhi, unsigned char number) {
P2 &= ~0x1c;
P2 |= (~weizhi & 0x07) << 2;
/*
switch (weizhi) {
case 1:
P2_4 = 1;
P2_3 = 1;
P2_2 = 1;
break;
case 2:
P2_4 = 1;
P2_3 = 1;
P2_2 = 0;
break;
case 3:
P2_4 = 1;
P2_3 = 0;
P2_2 = 1;
break;
case 4:
P2_4 = 1;
P2_3 = 0;
P2_2 = 0;
break;
case 5:
P2_4 = 0;
P2_3 = 1;
P2_2 = 1;
break;
case 6:
P2_4 = 0;
P2_3 = 1;
P2_2 = 0;
break;
case 7:
P2_4 = 0;
P2_3 = 0;
P2_2 = 1;
break;
case 8:
P2_4 = 0;
P2_3 = 0;
P2_2 = 0;
break;
}
*/
// 因为这个number所表示的含义有点乱
// 要改这个switch就得改number所表示的含义
switch (number) {
case 0: P0 = num[0]; break;
case 1: P0 = num[1]; break;
case 2: P0 = num[2]; break;
case 3: P0 = num[3]; break;
case 4: P0 = num[4]; break;
case 5: P0 = num[5]; break;
case 6: P0 = num[6]; break;
case 7: P0 = num[7]; break;
case 8: P0 = num[8]; break;
case 9: P0 = num[9]; break;
case 'A': P0 = num[10]; break;
case 'B': P0 = num[11]; break;
case 'C': P0 = num[12]; break;
case 'D': P0 = num[13]; break;
case 'E': P0 = num[14]; break;
case 'F': P0 = num[15];
case ' ': P0 = num[16];
}
Sleep(2);
P0 = 0x00;
}
这里要感谢@人造人 大佬
然后你们添加一个头文件
nixie.h
#ifndef __NIXIE_H__
#define __NIXIE_H__
void Nixie(unsigned char weizhi, unsigned char number);
#endif
之后直接调用这个库就行
比如说我想要在3处显示9
直接想在2处显示空想在5处显示A
大家也可以自己丰富一下
动态数码管
因为厂家为了减少IO口,这8个数码管中不能同时打开,那怎么办呢?
利用数码管的余晖和人眼的残影保留,快速的开关开关数码管,欺骗人眼实现全部显示
在nixie库中我就已经做好了动态需要的步骤了
也就是最后的sleep2是为了不要太快,不然就会有很明显的上一个的残影
P0=0x00也是为了消除数码管上次太多的残影
完整代码是这样的
#include <8052.h>
// #include "../Sleep.h"
#include "../nixie.h"
void main() {
// P2_4=0;
// P2_3=0;
// P2_2=1;
P2 = 0x00;
while (1) {
Nixie(1, 4);
Nixie(2, 6);
// Sleep(3);
// P2_2 = 0;
}
}
这节课有点难理解,建议去看看江科大的视频
如果有什么不理解的地方或者我有什么错误,请联系我
也可以在我的博客里看哦~https://cxwindlight.online/
|