STM32实战项目 |
您所在的位置:网站首页 › 74ls244驱动数码管的电路 › STM32实战项目 |
程序实现功能: 1、上电后,数码管间隔50ms计数; 2、触摸按键1调节数码管亮度,8个等级; 目录 1、硬件电路 1.1数码管 1.2TIM1620 驱动电路 二、技术讲解 2.1概述 2.2特性 2.3引脚说明 3.指令说明及配置 3.1显示模式命令设置 3.2写数据地址模式 3.3显示控制命令设置 3.4显示寄存器地址 3.5数码管显示驱动 4.软件编程 4.1串口高低电平配置 4.2数码管译码配置 4.3写入函数 4.4初始化TIM1620函数 4.5数码管显示函数 4.6运行函数 4.7回调函数-按键控制亮度 1、硬件电路 1.1数码管 1.2TIM1620 驱动电路 二、技术讲解 2.1概述 TM1620是一种LED(发光二极管显示器)驱动控制专用IC,内部集成有MCU数字接口、数据锁存器、 LED驱动等电路。 2.2特性• 采用CMOS工艺• 显示模式(8 段× 6 位~10段× 4位) • 辉度调节电路(8 级占空比可调) • 串行接口(CLK,STB,DIN) • 振荡方式:内置RC振荡 • 内置上电复位电路 • 内置数据锁存电路 • 内置针对LED反偏漏电导致暗亮问题优化电路 • 抗干扰能力强 • 封装形式: SOP20 2.3引脚说明TIM1620需要通过引脚CLK、DIN、STB 控制串行数据传输,所以优先配置好GPIO串口,具体配置如下图所示: 3.指令说明及配置 3.1显示模式命令设置该指令用来设置选择段和位的个数(4~6 位,8~10 段) 。当该指令被执行时,显示被强制关闭。 在显示模式不变时,显存内的数据不会被改变,显示控制命令控制显示开关。如下图所示: 为了移植方便,在我们的显示函数声明部分,将所以可能的选项枚举出来,具体代码如下: /显示模式 typedef enum { Disp_Mode_GRID4_SEG10 = 0x00, Disp_Mode_GRID5_SEG9 = 0x01, Disp_Mode_GRID6_SEG8 = 0x02, } Disp_Mode_t; 3.2写数据地址模式该指令用来设置数据写和读,B1和B0位不允许设置01或11。具体如下图所示: 为了移植方便,在我们的显示函数声明部分,将所以可能的选项枚举出来,具体代码如下: //写数据模式 typedef enum { Write_Data_Addr_Fix = 0x44, Write_Data_Addr_Auto_Add = 0x40, } Write_Data_Addr_Mode_t; 3.3显示控制命令设置该指令用来设置显示的开关以及显示亮度调节。共有8级辉度可供选择进行调节。如下图所示: 为了移植方便,在我们的显示函数声明部分,将所以可能的选项枚举出来,具体代码如下: //灰度等级 typedef enum { Brightness_level_0 = 0x80, Brightness_level_1 = 0x88, Brightness_level_2 = 0x89, Brightness_level_3 = 0x8A, Brightness_level_4 = 0x8B, Brightness_level_5 = 0x8C, Brightness_level_6 = 0x8D, Brightness_level_7 = 0x8E, Brightness_level_8 = 0x8F, } Brightness_level_t; 3.4显示寄存器地址该寄存器存储通过串行接口接收从外部器件传送到TM1620的数据,最多有效地址从00H-0BH共12字节单元, 分别与芯片SEG和GRID管脚对应,具体分配如下图:写LED显示数据的时候,按照显示地址从低位到高位,数据字节从低位到高位操作
为了移植方便,在我们的显示函数声明部分,将所以可能的选项枚举出来,具体代码如下: //显示寄存器地址 typedef enum { Disp_SFR_Addr_Num = (uint8_t)12, Disp_SFR_Addr_00H = 0xC0, Disp_SFR_Addr_01H = 0xC1, Disp_SFR_Addr_02H = 0xC2, Disp_SFR_Addr_03H = 0xC3, Disp_SFR_Addr_04H = 0xC4, Disp_SFR_Addr_05H = 0xC5, Disp_SFR_Addr_06H = 0xC6, Disp_SFR_Addr_07H = 0xC7, Disp_SFR_Addr_08H = 0xC8, Disp_SFR_Addr_09H = 0xC9, Disp_SFR_Addr_0AH = 0xCA, Disp_SFR_Addr_0BH = 0xCB, } Disp_SFR_Addr_t;注意: 芯片显示寄存器在上电瞬间其内部保存的值可能是随机不确定的,此时客户直接发送开屏命令,将有可能出现显示乱码。所以我司建议客户对显示寄存器进行一次上电清零操作,即上电后向12位显存地址(00H-0BH)中全部写入数据0x00。 3.5数码管显示驱动关于小数点是否启动,也将其封装起来,代码如下: typedef enum { Disp_DP_OFF = 0x01, Disp_DP_ON = 0x02, } Disp_DP_Status_t; 4.软件编程 4.1串口高低电平配置为了方便串口数据传输,我们使用宏定义 将串口的读写重新定义,具体代码如下: //TM1620穿行通讯口 #define SET_STB HAL_GPIO_WritePin(TM1620_STB_GPIO_Port,TM1620_STB_Pin,GPIO_PIN_SET) #define CLR_STB HAL_GPIO_WritePin(TM1620_STB_GPIO_Port,TM1620_STB_Pin,GPIO_PIN_RESET) #define SET_DIN HAL_GPIO_WritePin(TM1620_DIN_GPIO_Port,TM1620_DIN_Pin,GPIO_PIN_SET) #define CLR_DIN HAL_GPIO_WritePin(TM1620_DIN_GPIO_Port,TM1620_DIN_Pin,GPIO_PIN_RESET) #define SET_CLK HAL_GPIO_WritePin(TM1620_CLK_GPIO_Port,TM1620_CLK_Pin,GPIO_PIN_SET) #define CLR_CLK HAL_GPIO_WritePin(TM1620_CLK_GPIO_Port,TM1620_CLK_Pin,GPIO_PIN_RESET) 4.2数码管译码配置没有单独配置小数点,函数内部需要小数点的话,单独加上即可。 uint8_t Disp_Decode[16] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}; //数码管译码 0 - 9 4.3写入函数
根据时序图写函数,首先在传输八位数据之前,需要将STB置零拉低,因为是使用库函数,有一定的延时,所不用额外加延时函数,开始一个一个bit传的时候也需要拉低CLK,拉高CLK,用每个bit位与1&从而确定每个bit是高低电平,发出信号。具体代码如下: static void TM1620_Write_Byte(uint8_t dat) { uint8_t i = 0; //参考数据手册时序图 CLR_STB; for(i=0;i> 1; //移位,准备下一个bit //时钟上升沿发送下一个数据 SET_CLK; __nop(); } } 4.4初始化TIM1620函数芯片显示寄存器在上电瞬间其内部保存的值可能是随机不确定的,此时客户直接发送开屏命令,将有可能出现显示乱码 ,所以要进行清零操作,因为芯片内部有配置可以自动地址增加,具体如下图示: 具体配置代码如下: static void TM1620_Init() { uint8_t i = 0; //设置显示模式 TM1620_Write_Byte(Disp_Mode_GRID6_SEG8); SET_STB; //地址自动增加 TM1620_Write_Byte(Write_Data_Addr_Auto_Add); SET_STB; //清除显示寄存器 TM1620_Write_Byte(Disp_SFR_Addr_00H); //设置首地址 for(i=0;i 0x0F) { System.Assert_Failed(); } //设置显示模式 TM1620_Write_Byte(Disp_Mode_GRID6_SEG8); SET_STB; //地址固定 TM1620_Write_Byte(Write_Data_Addr_Fix); SET_STB; //写地址 TM1620_Write_Byte(Disp_NUM); //写数据 if(Disp_DP_Status == Disp_DP_ON) TM1620_Write_Byte(Disp_Decode[Dat] + 0x80); else TM1620_Write_Byte(Disp_Decode[Dat]); SET_STB; //显示 TM1620_Write_Byte(Display.Brightness); SET_STB; } 4.6运行函数 static void Run() { static uint32_t Cnt = 0; //数码管显示计数值 Display.Disp(Disp_NUM_1,Cnt%10, Disp_DP_OFF); //个位 Display.Disp(Disp_NUM_2,Cnt/10%10, Disp_DP_OFF); //十位 Display.Disp(Disp_NUM_3,Cnt/100%10, Disp_DP_OFF); //百位 Display.Disp(Disp_NUM_4,Cnt/1000%10, Disp_DP_OFF); //千位 Display.Disp(Disp_NUM_5,Cnt/10000%10,Disp_DP_OFF); //万位 Display.Disp(Disp_NUM_6,Cnt/100000, Disp_DP_OFF); //十万位 //更新计数值 if(++Cnt > 999999) Cnt = 0; //延时50ms HAL_Delay(50); } 4.7回调函数-按键控制亮度 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if(GPIO_Pin == KEY1_Pin) { LED.LED_Flip(LED2); switch(Display.Brightness) { case Brightness_level_1: Display.Brightness = Brightness_level_2; break; case Brightness_level_2: Display.Brightness = Brightness_level_3; break; case Brightness_level_3: Display.Brightness = Brightness_level_4; break; case Brightness_level_4: Display.Brightness = Brightness_level_5; break; case Brightness_level_5: Display.Brightness = Brightness_level_6; break; case Brightness_level_6: Display.Brightness = Brightness_level_7; break; case Brightness_level_7: Display.Brightness = Brightness_level_8; break; case Brightness_level_8: Display.Brightness = Brightness_level_1; break; default: Display.Brightness = Brightness_level_3; } } }
|
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |