一、数码管种类
数码管一般分为共阴极和共阳极。
共阴极数码管在引脚处于高电平时显示,而共阳极反之。
对于单个数码管,共有abcdefg以及dp 8个引脚,若直接连接到微控制器上就会占用大量端口
而对于4个数码管来说,就需要32个引脚,这对于微控制器来说是不现实的。
所以这个时候就需要减少引脚的需求,用一个引脚来控制多个引脚。
74HC595就很好的满足了这一要求。
二、74HC595的结构
此次研究的是两个74HC595芯片级联下控制4个数码管。
图中第一个74HC595有五个外接端口,分别为VCC、SCLK、RCLK、DIO、GND。
VCC和GND分别连接到STM32L432KC的3V3和GND位置,而另外三个端口自由选择微控制器上的三个GPIO端口,也是此次单片机上的Digital pin
SCLK是移位寄存器时钟,在上升沿移位,可以看作在数据输入时,每给一个端口输入数据后,SCLK处上升沿移位至下一个端口,然后继续传输数据,相当于改变数据输入的端口;
RCLK是所存寄存器时钟,处于高电平时存储数据;
DIO是串行数据输入端,负责将数据输入至Q7~Q0,从高位到低位,Q7~Q0属于并行数据输入端;
第一个74HC595的QH‘将数据传至第二个74HC595的SER端口,继续将新的数据输入至第二个中的Q7~Q0;而第二个的QH’端口还可以继续级联第三个74HC595,这里就不详细讲述了。
三、如何控制4位数码管
要用两个芯片控制4个数码管,需要实现三个功能:
1、传输数据至正确端口,显示正常数字或字母;
2、选择正确的数码管;
3、存储数据;
- 由于我们已经知道数据是从高位到低位Q7~Q0依次输入的,因此使用8位二进制数进行位运算的操作便可将数据传入对应端口,这里需要注意的是这里的数码管是共阳极的,因此0是正常显示,1是不显示;
- 通过第一个芯片的内部结构可知,Q0~Q3对应着4个数码管. 通过位选,可以选择对应序列的数码管;
- 存储数据的操作可以直接构建函数用RCLK进行存储;
四、代码展示
1. 显示0~3
在mbed OS中编码
#include "mbed.h"
DigitalOut dataPin(D5); // DIO
DigitalOut clockPin(D6); // SCLK
DigitalOut latchPin(D9); // RCLK
const uint8_t digits[10] = {
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
};
void senddata(uint8_t digit){ // input the data to Q7~Q0
for(int i = 0;i<8;i++){
dataPin=(digit & ( 1<<(7-i) )) ? 1:0;
clockPin=1;
clockPin=0;
}
}
void storedata(uint8_t choice,uint8_t digit){ // store the data in the Nixie tube
latchPin=0;
senddata(digit); //show the number on the tube
senddata(1<<(choice)); //select the Nixie tube
latchPin=1;
}
int main()
{
while (true) {
for(int n=0;n<4;n++){
storedata(n,digits[3-n]);
ThisThread::sleep_for(1ms);
}
}
}
2.计时器
#include "mbed.h"
#include <cstdint>
#include <cstdlib>
#include <stdlib.h>
#include <time.h>
DigitalOut dataPin(D5); // DIO
DigitalOut clockPin(D6); // SCLK
DigitalOut latchPin(D9); // RCLK
const uint8_t mychoice[4] = {
0b00000001, // G 1
0b00000010, // G 2
0b00000100, // G 3
0b00001000, // G 4
};
const uint8_t digits[10] = {
0b11000000, // 0
0b11111001, // 1
0b10100100, // 2
0b10110000, // 3
0b10011001, // 4
0b10010010, // 5
0b10000010, // 6
0b11111000, // 7
0b10000000, // 8
0b10010000, // 9
};
void senddata(uint8_t digit,uint8_t choice){
for(int i = 0;i<8;i++){
dataPin=(digit & ( 1<<(7-i) )) ? 1:0;
if(choice==mychoice[2]){
if(i==0){
dataPin=0;
}
}
clockPin=1;
clockPin=0;
}
}
void storedata(uint8_t choice,uint8_t digit){
latchPin=0;
senddata(digit,choice);
senddata(choice,choice);
latchPin=1;
}
int main() {
int second=0,minute=0;
while (1) {
time_t now;
now = time(NULL);
long int a;
int sec1=second % 10;
int sec2=second / 10;
int min1=minute % 10;
int min2=minute / 10;
storedata(mychoice[0],digits[sec1]);
wait_us(300);
storedata(mychoice[1],digits[sec2]);
wait_us(300);
storedata(mychoice[2],digits[min1]);
wait_us(300);
storedata(mychoice[3],digits[min2]);
wait_us(300);
if(now == (a+1)){
second++;
if(second==60){
second=0;
minute++;
}
if(minute==60){
minute=0;
}
}
a=now;
}
}
PS:这是小编在做实验时借鉴了各种前人的经验然后自行钻研出的有关mbed OS上如何使用这种4位数码管的心得,想让各位跟小编一样新接触mbed的新人能快速上手一个器件,不像自己曾经一样耗费几个夜晚才弄懂.
小编是第一次发布文章,如有错误还请指出,还望多多包涵,感谢各位的支持,希望能对各位有所帮助!