H文件#ifndef __FY_HC595_H #define __FY_HC595_H #include fy_includes.h #define HC595B_H (u16)(10) #define HC595B_G (u16)(11) #define HC595B_F (u16)(12) #define HC595B_E (u16)(13) #define HC595B_D (u16)(14) #define HC595B_C (u16)(15) #define HC595B_B (u16)(16) #define HC595B_A (u16)(17) #define HC595A_H (u16)(18) #define HC595A_G (u16)(19) #define HC595A_F (u16)(110) #define HC595A_E (u16)(111) #define HC595A_D (u16)(112) #define HC595A_C (u16)(113) #define HC595A_B (u16)(114) #define HC595A_A (u16)(115) #define SEG_DATA_BACK_OFF 16 //空 #define SEG_DATA_BACK_0 0 //补0 typedef struct { u16 value_595; u8 seg_data[4]; u8 seg_index; u8 seg_dp; u8 flashCnt; u8 flash; u8 times; u8 flashTimes; u8 leds; }_typdef_hc595; void HC595_Configuration(void); void HC595_ShowValue(u16 value); void HC595_SegData(s16 value,u8 index,u8 mode); void HC595_Diplay(void); void Set_SegFlash(u8 flash_cnt); void Seg_FlashTick(void); void Seg_SetDp(u8 dp,u8 cmd); void HC595_SetLed(u8 led,u8 cmd); u8 HC595_GetLedState(u8 led); #endifC文件#include fy_hc595.h #define SEG_A (u8)(17) #define SEG_B (u8)(16) #define SEG_C (u8)(15) #define SEG_D (u8)(14) #define SEG_E (u8)(13) #define SEG_F (u8)(12) #define SEG_G (u8)(11) #define SEG_H (u8)(10) #define LED0 (10) #define LED1 (11) #define LED2 (12) #define LED3 (13) #define SEG_COM_0 (14) #define SEG_COM_1 (15) #define SEG_COM_2 (16) #define SEG_COM_3 (17) #define HC595_RCK_RCC RCC_AHBPeriph_GPIOA #define HC595_RCK_PORT GPIOA #define HC595_RCK_PIN GPIO_Pin_0 #define HC595_RCK_H() GPIO_SetBits(HC595_RCK_PORT,HC595_RCK_PIN) #define HC595_RCK_L() GPIO_ResetBits(HC595_RCK_PORT,HC595_RCK_PIN) #define HC595_DAT_RCC RCC_AHBPeriph_GPIOB #define HC595_DAT_PORT GPIOB #define HC595_DAT_PIN GPIO_Pin_1 #define HC595_DAT_H() GPIO_SetBits(HC595_DAT_PORT,HC595_DAT_PIN) #define HC595_DAT_L() GPIO_ResetBits(HC595_DAT_PORT,HC595_DAT_PIN) #define HC595_CLK_RCC RCC_AHBPeriph_GPIOA #define HC595_CLK_PORT GPIOA #define HC595_CLK_PIN GPIO_Pin_1 #define HC595_CLK_H() GPIO_SetBits(HC595_CLK_PORT,HC595_CLK_PIN) #define HC595_CLK_L() GPIO_ResetBits(HC595_CLK_PORT,HC595_CLK_PIN) const unsigned char numtab[] { /*00*/ (unsigned char)(~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F)), /*11*/ (unsigned char)(~(SEG_B | SEG_C)), /*22*/ (unsigned char)(~(SEG_A | SEG_B | SEG_D | SEG_E | SEG_G)), /*33*/ (unsigned char)(~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_G)), /*44*/ (unsigned char)(~(SEG_B | SEG_C | SEG_F | SEG_G)), /*55*/ (unsigned char)(~(SEG_A | SEG_C | SEG_D | SEG_F | SEG_G)), /*66*/ (unsigned char)(~(SEG_A | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)), /*77*/ (unsigned char)(~(SEG_A | SEG_B | SEG_C)), /*88*/ (unsigned char)(~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)), /*99*/ (unsigned char)(~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_F | SEG_G)), /*10A */ (unsigned char)(~(SEG_A | SEG_B | SEG_C | SEG_E | SEG_F | SEG_G)), /*11b */ (unsigned char)(~(SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)), /*12C*/ (unsigned char)(~(SEG_A | SEG_D | SEG_E | SEG_F)), /*13d*/ (unsigned char)(~(SEG_B | SEG_C | SEG_D | SEG_E | SEG_G)), /*14E*/ (unsigned char)(~(SEG_A | SEG_D | SEG_E | SEG_F | SEG_G)), /*15F*/ (unsigned char)(~(SEG_A | SEG_E | SEG_F | SEG_G)), /*16全灭*/ (unsigned char)((SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G) | SEG_H), /*17全亮*/ (unsigned char)(~(SEG_A | SEG_B | SEG_C | SEG_D | SEG_E | SEG_F | SEG_G)), /*18-*/ (unsigned char)(~(SEG_G)), /*19c*/ (unsigned char)(~(SEG_D | SEG_E | SEG_G)), /*20o*/ (unsigned char)(~(SEG_C | SEG_D | SEG_E | SEG_G)), /*21H*/ (unsigned char)(~(SEG_B | SEG_C | SEG_E | SEG_F | SEG_G)), /*22r*/ (unsigned char)(~(SEG_E | SEG_G)), /*23U*/ (unsigned char)(~(SEG_B | SEG_C | SEG_D | SEG_E | SEG_F)), /*24u*/ (unsigned char)(~(SEG_C | SEG_D | SEG_E)), /*25L*/ (unsigned char)(~(SEG_D | SEG_E | SEG_F)), /*26T*/ (unsigned char)(~(SEG_A | SEG_E | SEG_F)), /*27P*/ (unsigned char)(~(SEG_A | SEG_B | SEG_E | SEG_F | SEG_G)), /*28i*/ (unsigned char)(~(SEG_E | SEG_F)), /*29k*/ (unsigned char)(~(SEG_B | SEG_D | SEG_E | SEG_F | SEG_G)), /*30n*/ (unsigned char)(~(SEG_C | SEG_E | SEG_G)), /*31*/ (unsigned char)(~(SEG_A | SEG_B | SEG_F | SEG_G)), /*32上u*/ (unsigned char)(~(SEG_B | SEG_F | SEG_G)) }; const u8 numToBit[8] {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; _typdef_hc595 _hc595; //初始化74HC595对应IO void HC595_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; //*********************HC595_RCK*********************// //1、时钟配置 RCC_AHBPeriphClockCmd(HC595_RCK_RCC, ENABLE); //2、GPIO配置 GPIO_InitStructure.GPIO_Pin HC595_RCK_PIN; GPIO_InitStructure.GPIO_Mode GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd GPIO_PuPd_UP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(HC595_RCK_PORT, GPIO_InitStructure);/* 配置引脚*/ //*********************HC595_DAT*********************// //1、时钟配置 RCC_AHBPeriphClockCmd(HC595_DAT_RCC, ENABLE); //2、GPIO配置 GPIO_InitStructure.GPIO_Pin HC595_DAT_PIN; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode GPIO_Mode_OUT; GPIO_Init(HC595_DAT_PORT, GPIO_InitStructure); //*********************HC595_CLK*********************// //1、时钟配置 RCC_AHBPeriphClockCmd(HC595_CLK_RCC, ENABLE); //2、GPIO配置 GPIO_InitStructure.GPIO_Pin HC595_CLK_PIN; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode GPIO_Mode_OUT; GPIO_Init(HC595_CLK_PORT, GPIO_InitStructure); } //74HC595发送一个字节 static void HC595_SendByte(u8 dat) { u8 i; for(i0; i8; i) { HC595_CLK_L(); // __NOP(); if(dat 0x01) HC595_DAT_H(); else HC595_DAT_L(); // __NOP(); HC595_CLK_H(); // __NOP(); dat 1; } } void HC595_ShowValue(u16 value) { HC595_RCK_L(); HC595_CLK_L(); HC595_SendByte(value0xFF); HC595_SendByte(value8); HC595_RCK_H(); HC595_CLK_L(); // __NOP(); HC595_RCK_L(); } /* 数码管输入要显示的数据地址从最低位开始 value 数据 index 地址 mode SEG_DATA_BACK_OFF 高位为0时不显示 SEG_DATA_BACK_0 高位为0时显示0 */ void HC595_SegData(s16 value,u8 index,u8 mode) { u8 s; u8 a; u8 i; if (value 0) { s 1; value -value; } else { s 0; } i 0; do { _hc595.seg_data[index--] numtab[value % 10]; value / 10; if (i 4) { break; } } while (value ! 0); a numtab[mode]; while (i 4) { _hc595.seg_data[index--] a; } if(s) { index; _hc595.seg_data[index] numtab[18]; } } //一次显示一个数字 //00000000 0000 0000 //数码管段选 数码管位选 LED void HC595_Diplay(void) { u8 seg_value; if(_hc595.seg_index4) //这里的4指的是数码管的4位 { _hc595.seg_index0; } seg_value _hc595.seg_data[_hc595.seg_index]; if (_hc595.seg_index 4 )//_hc595.seg_index !3_hc595.seg_index !7 { if (numToBit[_hc595.seg_index] _hc595.seg_dp)//显示小数点 { seg_value ~SEG_H; } else //不显示小数点 { seg_value | SEG_H; } if (_hc595.flash) { if (_hc595.flashCnt 25) { if (_hc595.seg_index 4) { seg_value 0xff; } } if (_hc595.flashCnt 50) { _hc595.flashCnt 0; if (_hc595.flashTimes) { _hc595.flashTimes--; if(_hc595.flashTimes0) _hc595.flash0; } } } } _hc595.value_595 numToBit[3-_hc595.seg_index]4; //位选 _hc595.value_595 | (_hc595.leds0x0f); //LED if (_hc595.seg_index 4) { _hc595.value_595 | seg_value8;//段选 } HC595_ShowValue(_hc595.value_595); _hc595.seg_index; } void Set_SegFlash(u8 flash_cnt) { _hc595.flashCnt0; _hc595.flash 1; _hc595.flashTimesflash_cnt; } void Seg_FlashTick(void) { _hc595.flashCnt; } void Seg_SetDp(u8 dp,u8 cmd) { if (cmd) { _hc595.seg_dp | dp; } else { _hc595.seg_dp ~dp; } } void HC595_SetLed(u8 led,u8 cmd) { if (cmd 1) { _hc595.leds | led; } else if (cmd 0) { _hc595.leds ~led; } else { if(_hc595.leds led) _hc595.leds ~led; else _hc595.leds | led; } } u8 HC595_GetLedState(u8 led) { return _hc595.leds (1led) ? 1:0; } /*********************************************END OF FILE********************************************/这个底层我使用了很长时间了今天记录并分享出来把关键的地方提一下剩下的需要自己啃一下。驱动部分一般都用串行转并行的逻辑芯片这样io就能省下来不少。1、数码管的位数这个在结构体里面的数组里面定义2、整体思路是给数码管开辟一个缓存最终显示调用方式为HC595_Diplay这个调用比较耗处理器一般我是2ms或者1ms调用一次来解决频闪问题。3、更改、送数为HC595_SegData、Seg_SetDp当然因为缓存也可以查询。4、整体闪烁函数调用为Set_SegFlash5、上述针对4位一体数码管如果位不一致的话需要更改。By Urien 2019年9月1日 15:51:39