数码管——wiringPi接口的使用

我们先来看下数码管的实物图


正面


背面

数码管由四个引脚:CLK,DIO,VCC,GND

VCC接5V   GND接GND   CLK和DIO接GPIO。

实现原理: https://blog.csdn.net/q1241580040/article/details/45815245

数码管显示原理:https://www.cnblogs.com/yuwl26/p/3307337.html

数码管相对于之前的LED,按钮之类要复杂,想要了解详情的可以看以上两个链接。

我就简单的介绍下数码管原理:通过CLK DIO 两个引脚的高低电平变化来写入数据。


开始与停止信号

数码管接收到开始信号后 可以写入数据 接收到停止信号后结束写入。

数码管分两种:共阴极  和 共阳极

数码管上的每个数字都由七条短杠 和 一个小数点组成,共阴极的数码管 当短杠接收到高电平时会通电发光,供阳极则为低电平通电发光。


这样说不是很好理解 我就举个例子,比方说我们想让共阴极的数码管显示数字 5,那就要让afgcd 这五个短杠 为高电平1,那个abcdefgD(D表示小数点)为 10110110,这里的数据写入格式为 Dgfedcba ,即01101101,转换为十六进制为 0x6d

unsigned char code table[]={//共阴极0~f数码管编码

0x3f,0x06,0x5b,0x4f,    //0~3

0x66,0x6d,0x7d,0x07,    //4~7

0x7f,0x6f,0x77,0x7c,    //8~b

0x39,0x5e,0x79,0x71    //c~f

};

除了显示数字字母 数码管还有一些固定的命令

0xc0~0xc3 表示数码管上四个数字的地址

代码

#include

#include

#include

#include

#include

#include

#include

#define CLK 27

#define DIO 22

//共阴极0~f数码管编码

char segdata[]={

0x3f,0x06,0x5b,0x4f,    //0~3

0x66,0x6d,0x7d,0x07,    //4~7

0x7f,0x6f,0x77,0x7c,    //8~b

0x39,0x5e,0x79,0x71,    //c~f

0x00  //不显示

};

//共阴极0~9带小数点的数码管编码

char segdatadp[]={

0xbf,0x86,0xdb,

0xcf,0xe6,0xed,

0xfd,0x87,0xff,0xef

};

//初始化wiringPi 使用BCM编码

void tm1637_init()

{

if(-1==wiringPiSetupGpio())

{

exit(-1);

}

pinMode(CLK,OUTPUT);

pinMode(DIO,OUTPUT);

}

//当CLK高电平时,DIO由高变低则代表开始信号

void tm1637_start()

{

digitalWrite(CLK,1);

usleep(140);

digitalWrite(DIO,1);

usleep(140);

digitalWrite(DIO,0);

usleep(140);

digitalWrite(CLK,0);

usleep(140);

}

//当CLK高电平时,DIO由低变高则代表停止信号

void tm1637_stop()

{

digitalWrite(CLK,0);

usleep(140);

digitalWrite(DIO,0);

usleep(140);

digitalWrite(CLK,1);

usleep(140);

digitalWrite(DIO,1);

usleep(140);

}

void write_bit(char bit)

{

digitalWrite(CLK,0);

usleep(140);

if(bit){

digitalWrite(DIO,1);

}else{

digitalWrite(DIO,0);

}

usleep(140);

digitalWrite(CLK,1);

usleep(140);

}

void write_byte(char data)

{

char i = 0;

for(i=0;i<8;i++)

{

write_bit((data>>i)&0x01);

}

digitalWrite(CLK,0);

usleep(140);

digitalWrite(DIO,1);

usleep(140);

digitalWrite(CLK,1);

usleep(140);

pinMode(DIO,INPUT);

while(digitalRead(DIO));

pinMode(DIO,OUTPUT);

}

void write_command(char cmd)

{

tm1637_start();

write_byte(cmd);

tm1637_stop();

}

void write_data(char addr,char data)

{

tm1637_start();

write_byte(addr);

write_byte(data);

tm1637_stop();

}

void number_display(int h_shi,int h_ge,int m_shi,int m_ge)

{

write_command(0x40);//写数据

write_command(0x44);//固定地址

write_data(0xc0,segdata[h_shi]);//写入第一个数码管

write_data(0xc1,segdata[h_ge]);

write_data(0xc2,segdata[m_shi]);

write_data(0xc3,segdata[m_ge]);

write_command(0x88);//显示开

}

void time_display(int h_shi,int h_ge,int m_shi,int m_ge,int f_dp)

{

write_command(0x40);//写数据

write_command(0x44);//固定地址

write_data(0xc0,segdata[h_shi]);//写入第一个数码管

if(f_dp)

{

write_data(0xc1,segdata[h_ge]);

}else{

write_data(0xc1,segdatadp[h_ge]);

}

write_data(0xc2,segdata[m_shi]);

write_data(0xc3,segdata[m_ge]);

write_command(0x88);//显示开

}

//sigint信号处理函数 退出并关闭数码管

void handler(int signo)

{

number_display(16,16,16,16);

exit(-1);

}

int main()

{

char FLAGDP = 1;

signal(SIGINT,handler);

tm1637_init();

char i = 0;

#if 0

while(1)

{

for(i=0;i<10;i++)

{

number_display(i,i,i,i);

sleep(1);

}

}

#endif

while(1)

{

FLAGDP^=1;

time_t t = time(NULL);

struct tm* _mt = gmtime(&t);

int h_s=0,h_g=0,m_s=0,m_g=0;

h_s = (_mt->tm_hour+8)/10;//时区+8

h_g = (_mt->tm_hour+8)%10;

m_s = _mt->tm_min/10;

m_g = _mt->tm_min%10;

time_display(h_s,h_g,m_s,m_g,FLAGDP);

sleep(1);

}

return 0;

}

你可能感兴趣的:(数码管——wiringPi接口的使用)