原理图
micropython 的 main.py from machineimport Pinimport time# 定义引脚 latch_pin= Pin( 21 , Pin. OUT) clock_pin= Pin( 22 , Pin. OUT) data_pin= Pin( 23 , Pin. OUT) # 数码管显示码 (共阳极) dis_table= [ 0xC0 , 0xF9 , 0xA4 , 0xB0 , 0x99 , 0x92 , 0x82 , 0xF8 , 0x80 , 0x90 ] # 位选码 (控制哪一位数码管亮) dis_buf= [ 0xF1 , 0xF2 , 0xF4 , 0xF8 ] # 初始化索引 inx= 0 def shift_out ( data_pin, clock_pin, value) : """模拟shiftOut函数,发送一个字节的数据""" for iin range ( 8 ) : # 先发送高位 data_pin. value( ( value>> ( 7 - i) ) & 1 ) # 时钟脉冲 clock_pin. value( 1 ) clock_pin. value( 0 ) def display ( data) : """显示数据到4位数码管""" global inx disbuff= 0 # 根据当前索引计算要显示的数字位 if inx== 0 : disbuff= data// 1000 # 千位 elif inx== 1 : disbuff= ( data// 100 ) % 10 # 百位 elif inx== 2 : disbuff= ( data// 10 ) % 10 # 十位 else : disbuff= data% 10 # 个位 # 确保数值在有效范围内 if disbuff< 0 or disbuff> 9 : disbuff= 0 # 发送数据 latch_pin. value( 0 ) shift_out( data_pin, clock_pin, dis_table[ disbuff] ) # 发送段码 shift_out( data_pin, clock_pin, dis_buf[ inx] ) # 发送位码 latch_pin. value( 1 ) # 更新索引 inx= ( inx+ 1 ) % 4 # 主循环 while True : display( 1567 ) time. sleep_ms( 2 ) arduino 的 main.cpp # include <Arduino.h> int latchPin= 21 ; int clockPin= 22 ; int dataPin= 23 ; //这里定义了那三个脚 void setup ( ) { pinMode ( latchPin, OUTPUT) ; pinMode ( clockPin, OUTPUT) ; pinMode ( dataPin, OUTPUT) ; //让三个脚都是输出状态 } void display ( uint16_t data) { static unsigned char Dis_table[ ] = { 0xC0 , 0xF9 , 0xA4 , 0xB0 , 0x99 , 0x92 , 0x82 , 0xF8 , 0X80 , 0X90 } ; //LED状态显示的变量 static unsigned char Dis_buf[ ] = { 0xF1 , 0xF2 , 0xF4 , 0xF8 } ; static unsigned char disbuff= 0 ; static char i= 0 ; switch ( i) { case 0 : disbuff= data/ 1000 ; break ; case 1 : disbuff= ( data% 1000 ) / 100 ; break ; case 2 : disbuff= ( data% 100 ) / 10 ; break ; case 3 : disbuff= data% 10 ; break ; default : disbuff= 0 ; } digitalWrite ( latchPin, LOW) ; //将ST_CP口上面加低电平让芯片准备好接收数据 shiftOut ( dataPin, clockPin, MSBFIRST, Dis_table[ disbuff] ) ; //发送显示码 0-3 shiftOut ( dataPin, clockPin, MSBFIRST, Dis_buf[ i] ) ; //发送通值 //串行数据输入引脚为dataPin,时钟引脚为clockPin,执行MSB有限发送,发送数据table[i] digitalWrite ( latchPin, HIGH) ; //将ST_CP这个针脚恢复到高电平 i++ ; if ( i== 4 ) { i= 0 ; } } void loop ( ) { display ( 1567 ) ; delay ( 2 ) ; } zynq的 emioGpio DigitalTubePt.cpp /** * 数码管的值每隔1s增加1 * 写1个数字需要10us * 5ms写1个数字 * 20ms写4个数字 */ # include "../lib/Protothread.h" # include "../lib/AtShell.h" # include "../bsp/bsp_emio_gpio.h" # include "../bsp/bsp_timer.h" class LedPt; //4 static int latchPin= 54 ; //7 static int clockPin= 55 ; //8 static int dataPin= 56 ; //这里定义了那三个脚 // 模拟 shiftOut,发送一个字节(高位先行) static void shiftOut ( uint8_t dataPin, uint8_t clockPin, uint8_t value) { // 循环 8 位,高位先发 for ( int i= 0 ; i< 8 ; i++ ) { // 取出当前位(高位优先) BspEmioGpioWrite ( dataPin, ( value>> ( 7 - i) ) & 1 ) ; // 产生时钟脉冲:上升沿发送数据 BspEmioGpioWrite ( clockPin, 1 ) ; BspEmioGpioWrite ( clockPin, 0 ) ; } } // 三合一显示函数 // 参数1:data 要显示的数据 // 参数2:point 小数点位置 0~3=亮,-1=不亮 // 参数3:mode 0=十进制,1=十六进制 static void display ( uint16_t data, char point, uint8_t mode) { // 完整段码表:0~9 + A~F static unsigned char Dis_table[ ] = { 0xC0 , 0xF9 , 0xA4 , 0xB0 , 0x99 , 0x92 , 0x82 , 0xF8 , 0X80 , 0X90 , // 0-9 0x88 , 0x83 , 0xC6 , 0xA1 , 0x86 , 0x8E // A-F } ; static unsigned char Dis_buf[ ] = { 0xF1 , 0xF2 , 0xF4 , 0xF8 } ; // 位选 static unsigned char disbuff= 0 ; static char i= 0 ; uint8_t seg; // ====================== // 数字拆分:十进制 / 十六进制 // ====================== if ( mode== 0 ) { // 十进制模式 data= data% 10000 ; switch ( i) { case 0 : disbuff= data/ 1000 ; break ; case 1 : disbuff= ( data% 1000 ) / 100 ; break ; case 2 : disbuff= ( data% 100 ) / 10 ; break ; case 3 : disbuff= data% 10 ; break ; default : disbuff= 0 ; } } else { // 十六进制模式 switch ( i) { case 0 : disbuff= ( data>> 12 ) & 0x0F ; break ; case 1 : disbuff= ( data>> 8 ) & 0x0F ; break ; case 2 : disbuff= ( data>> 4 ) & 0x0F ; break ; case 3 : disbuff= data& 0x0F ; break ; default : disbuff= 0 ; } } // 取段码 seg= Dis_table[ disbuff] ; // ====================== // 小数点控制(已修正硬件反序) // ====================== char realPoint= - 1 ; if ( point>= 0 && point<= 3 ) { realPoint= 3 - point; // 对齐视觉位置 } if ( i== realPoint&& realPoint!= - 1 ) { seg&= 0x7F ; // 点亮小数点 } // ====================== // 硬件输出 // ====================== BspEmioGpioWrite ( latchPin, 0 ) ; shiftOut ( dataPin, clockPin, seg) ; shiftOut ( dataPin, clockPin, Dis_buf[ i] ) ; BspEmioGpioWrite ( latchPin, 1 ) ; i++ ; if ( i>= 4 ) i= 0 ; } class DigitalTubePt: public Protothread{ void Init ( ) { AT_println ( "Digital Tube 595 init" ) ; BspEmioGpioSetDir ( latchPin, BSP_GPIO_OUT) ; BspEmioGpioSetDir ( clockPin, BSP_GPIO_OUT) ; BspEmioGpioSetDir ( dataPin, BSP_GPIO_OUT) ; } boolRun ( ) { static uint32_t s_lastTime= 0 ; static uint32_t s_disValue= 0 ; uint64_t now= BspGetTickMs ( ) ; if ( now- s_lastTime> 1000 ) { s_lastTime= now; s_disValue++ ; } display ( s_disValue, - 1 , 0 ) ; PtOsDelay ( 5 ) ; return true; } } ; DigitalTubePt g_digitalTubePt;