之前参加的MSP焕新大作战中的活动中,配备了一个数码管模块。稍微花了点时间,在Arduino下使用ESP12-E写了段驱动程序。
这个数码管模块使用三个接口线。DIO,SCLK,RCLK。其中DIO是输入串行数据用,相当于SPI接口中的MOSI,SCLK是串行移位脉冲,RCLK是所存数据用的,上升沿有效。数码管模块使用两片74HC595驱动,其中一个用来驱动数码管的笔段,另一个用来驱动数码管的公共端。
Arduino的程序如下:
#define SCLK 16 #define RCLK 5 #define DIO 4 #define SCLK_0 digitalWrite(SCLK, LOW) #define SCLK_1 digitalWrite(SCLK, HIGH) #define RCLK_0 digitalWrite(RCLK, LOW) #define RCLK_1 digitalWrite(RCLK, HIGH) #define DIO_0 digitalWrite(DIO, LOW) #define DIO_1 digitalWrite(DIO, HIGH) // 16进制数字显示信史段码(0-9,A-F),段码位=1时,数码管的对应的笔段不会被点亮 unsigned char TAB_SEG[] = { 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90, 0x77, 0x83, 0xC6, 0xA1, 0x86, 0x8E, 0xFF, 0xBF }; // 数码管模块的显示位置,自左向右 unsigned char TAB_POS[] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01}; /** * 显示数码管数据 * pos :显示位置 0-7,对应第一个到第八个数码管 * idx : 数值0-9 * flag: 是否显示小数点 */ void DispNum(unsigned char pos, unsigned char idx, unsigned char flag) { unsigned char i, num; // 根据字符,获取对应的段位码数据 if (idx>=0 && idx<=9) { num=TAB_SEG[idx]; if (flag) { num=num|0x80; } } else { return; } // 将段位码数据以串行方式发送给数码管显示模块 // 每个字符有八个笔段,小数点通常不用 for(i=0;i<8;i++) { // 输出笔段对应的数据位 if ((num & 0x80)>0) { // 笔段数据为1 的,DIO对应GPIO口输出高电平 DIO_1; } else { // 笔段数据为0 的,DIO对应GPIO口输出低高电平 DIO_0; } // 下一个笔段 num<<=1; // 发出移位用串行时钟上升沿脉冲 SCLK_0; SCLK_1; } // 发送完笔段数据,发送显示位置数据 num = TAB_POS[pos%8]; for(i=0;i<8;i++) { // 输出对应的数据位 if ((num & 0x80)>0) { DIO_1; } else { DIO_0; } // 下一个数码管位置 num<<=1; // 发出移位用串行时钟上升沿脉冲 SCLK_0; SCLK_1; } // 发出锁存信号,点亮数码管 RCLK_0; RCLK_1; } void setup() { // 三个接口均配置为输出模式 pinMode(SCLK,OUTPUT); pinMode(RCLK,OUTPUT); pinMode(DIO, OUTPUT); Serial.begin(115200); } void loop() { // put your main code here, to run repeatedly: unsigned char i=0; // 循环显示0-9 for (i=0; i<10;i++) { DispNum(0, i, 0); delay(1000); } }
对ESP12-E,GPIO16对应的是D0,GPIO5对应D1,GPIO4对应D2。用杜邦线按照下面方式连接好,烧录程序,就可以看到测试结果了。
ESP8266 数码管模块
----------------------------------
D0 (GPIO16) SCLK
D1(GPIO5) RCLK
D2(GPIO4) DIO