74HC595数码管驱动开发
这个数码管是个通用性数码管,网上资料很多,拿来直接套就行。
本项目是通过一个595芯片控制两个数码管的显示,Q7为1时左边的数码管显示,为0时右边的数码管显示
不需要初始化,直接把IO口初始化下即可。
/*GPIO输出引脚*/ gpio = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_14 | GPIO_PIN_15;//GPIO_PIN_13 | gpio_mode_set(GPIOC, GPIO_MODE_OUTPUT, GPIO_PUPD_PULLUP, gpio); gpio_output_options_set(GPIOC, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, gpio);
1 //74HC595口线定义宏定义.当驱动74HC595引脚改变时,只需更改底层引脚宏定义即可 2 #define LED595_DATA_PORT GPIOC 3 #define LED595_DATA_PIN GPIO_PIN_9 4 #define LED595_CLK_PORT GPIOC 5 #define LED595_CLK_PIN GPIO_PIN_8 6 #define LED595_LATCH_PORT GPIOC 7 #define LED595_LATCH_PIN GPIO_PIN_10 8 //74HC595口线高低电平宏定义 9 #define LED595_DATA_SET gpio_bit_set(LED595_DATA_PORT,LED595_DATA_PIN) 10 #define LED595_DATA_RESET gpio_bit_reset(LED595_DATA_PORT,LED595_DATA_PIN) 11 #define LED595_CLK_SET gpio_bit_set(LED595_CLK_PORT,LED595_CLK_PIN) 12 #define LED595_CLK_RESET gpio_bit_reset(LED595_CLK_PORT,LED595_CLK_PIN) 13 #define LED595_LATCH_SET gpio_bit_set(LED595_LATCH_PORT,LED595_LATCH_PIN) 14 #define LED595_LATCH_RESET gpio_bit_reset(LED595_LATCH_PORT,LED595_LATCH_PIN)
1 /*LED数码管显示 0 1 2 3 4 5 6 7 8 9 */ 2 UINT8 led595displaycode[2][10] = {{0xBF,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF},//LEFT 3 {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F} //RIGHT 4 }; 5 6 BOOLEAN led595_flush_flag = FALSE;//数码管左右轮流显示 7 8 UINT8 led595_display_temp=0xff; 9 UINT8 led595_display_buf[2]; //存放数码管左右显示的数据 10 11 12 13 /** 14 *74HC595输出锁存 使能 15 **/ 16 void HC595_CS(void) 17 { 18 /** 步骤3:STCP产生一个上升沿,移位寄存器的数据移入存储寄存器 **/ 19 LED595_LATCH_RESET; // 将STCP拉低 20 delay_1us(1); // 适当延时 21 LED595_LATCH_SET; // 再将STCP拉高,STCP即可产生一个上升沿 22 delay_1us(1); 23 } 24 25 /** 26 * @brief 将输入的数据输出到74HC595的引脚. 27 * @param Input 1 byte data. 28 * @retval None. 29 **/ 30 void HAL_LED595SendData(UINT8 OutData) 31 { 32 UINT8 i; //发送数据时做循环使用临时变量 33 for(i=0; i<8; i++) //将8位数据按位发送,先发送高字节后发送低字节 34 { 35 LED595_CLK_RESET;//时钟线低电平 36 37 if( (OutData & 0x80) == 0x80)//判断数据高低位 38 { 39 LED595_DATA_SET; //数据线高电平 40 } 41 else 42 { 43 LED595_DATA_RESET; //数据线低电平 44 } 45 OutData = OutData << 1; //数据左移1位 46 47 LED595_CLK_SET; //时钟线高电平 48 } 49 50 HC595_CS();//先把所有字节发送完,再使能输出 51 } 52 53 //用户接口函数,提供用于数码管显示的接口 54 void LED595_dispaly(UINT8 Data) 55 { 56 if(led595_display_temp != Data) 57 { 58 led595_display_temp = Data; 59 60 if(led595_display_temp<10) 61 { 62 led595_display_buf[0] = led595displaycode[0][0]; 63 led595_display_buf[1] = led595displaycode[1][led595_display_temp]; 64 } 65 else 66 { 67 led595_display_buf[0] = led595displaycode[0][led595_display_temp/10]; 68 led595_display_buf[1] = led595displaycode[1][led595_display_temp%10]; 69 } 70 } 71 } 72 73 //用于数码管的中断刷新显示 74 void led595_displayPro(void) 75 { 76 if(led595_flush_flag) 77 { 78 HAL_LED595SendData(led595_display_buf[0]); 79 } 80 else 81 { 82 HAL_LED595SendData(led595_display_buf[1]); 83 } 84 85 led595_flush_flag = !led595_flush_flag; 86 }
因为数码管是左右两个轮流刷的,刷其中一个的时候另一个会熄灭,需要将 led595_displayPro()函数放在10ms的中断中进行高速刷新。10ms看起来很稳定,不会有闪烁的现象
本文来自博客园,作者:xjxcxjx,转载请注明原文链接:https://www.cnblogs.com/xjxcxjx/p/15689321.html,谢绝CSDN转载!