断码液晶驱动原理:
1. 第一步:
段码液晶屏最重要的参数:占空比、工作电压、偏压比。这三个参数都是非常重要的,都必须要满足。
2. 第二步:
驱动的方式:我们根据 LCD 的驱动原理可以知道,LCD的像素点上面只能够加上 AC的电压,LCD显示器的对比度则是由 COM脚上的电压值减去 SEG 脚上的电压值来决定,当这个电压差在大于 LCD 饱和电压时就能够打开像素点,小于 LCD 时就能关闭像素点了,LCD 型的MCU 已经由内建的 LCD 驱动电路自动产生出LCD驱动信号了,因此只需要 I/O 口能仿真输出该驱动的信号,就能够完成 LCD 的驱动了。
段码液晶屏主要是有两种引脚,COM和SEG,和数码管比较像,但是,压差必须要是交替变化的,例:第一时刻是正向的3V,那么第二时刻就必须要是反向的3V,注意一点,如果你给段码液晶屏通直流电,那么不用多久这个屏幕就会报废,所以千万要注意。
我们以1/4D,1/2B为例子
在COM的输出较高的时候,如果要屏幕亮,那么SEG就要输出低,那么在COM输出低的时候,SEG就要输出高了,保证COM和SEG的压差大于1/2B工作电压就可以正常显示了
3. 控制方式
在LCD的参数中有几个重要参数,duty,bias,driver voltage。duty表示扫描周期一般为与com引脚个数有关,bias表示偏压,偏压1/3表示把VDD分三份,电压差越大越亮,bias与com引脚个数也有关系,因为com脚越多周期越短,为了保持亮度一致,需要提高选通和不选通的电压差。需要分更多份电压。。。
LCD屏幕引脚定义:
(注:上面的蓝色数字是硬件连接的段)
LCD驱动编写注意事项:
- 显示冲突
HAL_LCD_Write(LCD_HandleTypeDef *hlcd, uint32_t RAMRegisterIndex, uint32_t RAMRegisterMask, uint32_t Data)函数中的RAMRegisterMask掩码是为了解决LCD显示冲突的问题,32位中只有该位为0则会对该位进行操作。
举个栗子:
如果掩码为:0xFFFFFFFE,也就是对段0进行操作
更新显示后,
然后再对掩码为:0xFFFFFFFD,也就是要对段1进行操作,
更新显示后,则对上一次的显示无影响
但是如果第二次的掩码为:0xFFFFFFFC,则第二次操作就是对段0和段1两位进行更新
如果第一次让段0显示,第二次让段0不显示,则在掩码为0xFFFFFFFC的第二次更新后会覆盖第一次的操作
简单来说,如果要想把所有的段分开操作,后续操作不影响上次操作,那么在更新LCD显示的时候就一定要只对要操作的段就行操作,也就是掩码 要取正确。
- 初始化问题
hlcd.Init.VoltageSource = LCD_VOLTAGESOURCE_INTERNAL;
hlcd.Init.Contrast = LCD_CONTRASTLEVEL_5;
CubeMX生成驱动的时候,网上说电压源要选择外部电压源,选择内部电压源可能会初始化卡死,
那是因为hlcd.Init.Contrast = LCD_CONTRASTLEVEL_5;的值设置的小了,不足够驱动LCD显示,只要把这个值变大,内部电压源足够驱动LCD时就可以选择内部电压源了。
- CubeMX生成源码注意事项:
- LCD的时钟源和RTC公用同一个时钟源,所以初始化时要把RTC时钟激活,如下图
- 按照ST官网的例程配置的LCD如下图:
源码版本V.01
内容:显示华氏度,摄氏度、图标等(部分掩码计算错误,导致部分图标显示冲突,V1.2已解决显示冲突的问题)
extern LCD_HandleTypeDef hlcd;
typedef enum
{
Temp_C,
Temp_F,
Buzzer,
Body,
WuTi,
BLUE,
LOGO
}ICON;
//COM口定义
#define COM1 LCD_RAM_REGISTER4
#define COM2 LCD_RAM_REGISTER2
#define COM3 LCD_RAM_REGISTER0
#define COM4 LCD_RAM_REGISTER6
//段定义
#define SEG_Temp_C 15
#define SEG_Temp_F 15
#define SEG_Buzzer 15
#define SEG_Body 21
#define SEG_WuTi 4
#define SEG_BLUE 21
#define SEG_Battery1 21
#define SEG_Battery2 21
#define SEG_Battery3 10
#define SEG_Battery 15
#define SEG_LOGO 5
#define SEG_B 0
#define SEG_S 2
#define SEG_G 10
#define SEG_P 12
//COM口定义
#define COM_Temp_C COM4
#define COM_Temp_F COM3
#define COM_Buzzer COM2
#define COM_Body COM2
#define COM_WuTi COM1
#define COM_BLUE COM1
#define COM_Battery1 COM4
#define COM_Battery2 COM3
#define COM_Battery3 COM1
#define COM_Battery COM1
#define COM_LOGO COM1
//掩码定义
#define Mask_Temp_C 0xFFFF7FFF
#define Mask_Temp_F 0xFFFF7FFF
#define Mask_Buzzer 0xFFFF7FFF
#define Mask_Body 0xFFDFFFFF
#define Mask_WuTi 0xFFFFFFEF
#define Mask_BLUE 0xFFDFFFFF
#define Mask_Battery1 0xFFDFFFFF
#define Mask_Battery2 0xFFDFFFFF
#define Mask_Battery3 0xFFFFFBFF
#define Mask_Battery 0xFFFF7FFF
#define Mask_LOGO 0xFFFFFFEF
#define Mask_B 0xFFFFFFFC
#define Mask_S 0xFFFFFFF3
#define Mask_G 0xFFFFF2FF
#define Mask_P 0xFFFF5FFF
#define Mask_Point 0xFFFFEFFF
void lcd_temp_set(uint32_t temp);
void lcd_uint_set(uint32_t unit);
void lcd_bat_set(uint32_t bat_level);
void lcd_voice_set(uint32_t voice);
void lcd_temp_state_set(uint8_t en);
void lcd_unit_state_set(uint8_t en);
void lcd_bat_state_set(uint8_t en);
void lcd_voice_state_set(uint8_t en);
void MX_LCD_Init(void);
void HAL_LCD_MspInit(LCD_HandleTypeDef* lcdHandle);
void Display_Temp_C(float tempC);
void Display_Temp_F(float tempF);
void Display_Power(uint8_t grade);
void Diaplay_Icon(ICON icon,uint8_t status);
void Disp_BW(uint8_t num);
/*
LCD_RAM_REGISTER0——>COM3
LCD_RAM_REGISTER2——>COM2
LCD_RAM_REGISTER4——>COM1
LCD_RAM_REGISTER6——>COM4
*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
LCD_HandleTypeDef hlcd;
/* LCD init function */
void MX_LCD_Init(void)
{
hlcd.Instance = LCD;
hlcd.Init.Prescaler = LCD_PRESCALER_2;
hlcd.Init.Divider = LCD_DIVIDER_31;
hlcd.Init.Duty = LCD_DUTY_1_4;
hlcd.Init.Bias = LCD_BIAS_1_3;
hlcd.Init.VoltageSource = LCD_VOLTAGESOURCE_INTERNAL;
hlcd.Init.Contrast = LCD_CONTRASTLEVEL_5;
hlcd.Init.DeadTime = LCD_DEADTIME_2;
hlcd.Init.PulseOnDuration = LCD_PULSEONDURATION_7;
hlcd.Init.HighDrive = LCD_HIGHDRIVE_0;
hlcd.Init.BlinkMode = LCD_BLINKMODE_OFF;
hlcd.Init.BlinkFrequency = LCD_BLINKFREQUENCY_DIV8;
hlcd.Init.MuxSegment = LCD_MUXSEGMENT_DISABLE;
if (HAL_LCD_Init(&hlcd) != HAL_OK)
{
Error_Handler();
}
}
void HAL_LCD_MspInit(LCD_HandleTypeDef* lcdHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(lcdHandle->Instance==LCD)
{
/* USER CODE BEGIN LCD_MspInit 0 */
/* USER CODE END LCD_MspInit 0 */
/* LCD clock enable */
__HAL_RCC_LCD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**LCD GPIO Configuration
PC3 ------> LCD_SEG21
PA1 ------> LCD_SEG0
PA2 ------> LCD_SEG1
PA3 ------> LCD_SEG2
PA6 ------> LCD_SEG3
PA7 ------> LCD_SEG4
PC4 ------> LCD_SEG22
PB0 ------> LCD_SEG5
PB1 ------> LCD_SEG6
PB10 ------> LCD_SEG10
PB11 ------> LCD_SEG11
PB12 ------> LCD_SEG12
PB14 ------> LCD_SEG14
PB15 ------> LCD_SEG15
PA8 ------> LCD_COM0
PA9 ------> LCD_COM1
PA10 ------> LCD_COM2
PB9 ------> LCD_COM3
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN LCD_MspInit 1 */
/* USER CODE END LCD_MspInit 1 */
}
}
void HAL_LCD_MspDeInit(LCD_HandleTypeDef* lcdHandle)
{
if(lcdHandle->Instance==LCD)
{
/* USER CODE BEGIN LCD_MspDeInit 0 */
/* USER CODE END LCD_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_LCD_CLK_DISABLE();
/**LCD GPIO Configuration
PC3 ------> LCD_SEG21
PA1 ------> LCD_SEG0
PA2 ------> LCD_SEG1
PA3 ------> LCD_SEG2
PA6 ------> LCD_SEG3
PA7 ------> LCD_SEG4
PC4 ------> LCD_SEG22
PB0 ------> LCD_SEG5
PB1 ------> LCD_SEG6
PB10 ------> LCD_SEG10
PB11 ------> LCD_SEG11
PB12 ------> LCD_SEG12
PB14 ------> LCD_SEG14
PB15 ------> LCD_SEG15
PA8 ------> LCD_COM0
PA9 ------> LCD_COM1
PA10 ------> LCD_COM2
PB9 ------> LCD_COM3
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3|GPIO_PIN_4);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_9);
/* USER CODE BEGIN LCD_MspDeInit 1 */
/* USER CODE END LCD_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
/*******************************************************************************
* Function Name : ConvertNum
* Description : 查找输入参数对应的字符编码
* Inputs : InputNum--显示字符
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
const uint16_t mask[4]={0xF000,0x0F00,0x00F0,0x000F};
const uint8_t offset[4]={12,8,4,0};
const uint16_t Num_Map[10]={0x2323,0x0220,0x2132,0x2232,0x0231,0x2213,0x2313,0x0223,0x2333,0x2233};
//以0为例分析
void ConvertNum(uint8_t buff[4],int InputNum)
{
uint16_t Num, tmp = 0;
uint8_t i;
if((InputNum>=0)&&(InputNum<=9))//InputNum=0
{
Num=Num_Map[InputNum];//Num=0x2323
}
else
{
Num=0;//Num=0x0000;
}
for(i = 0;i < 4; i++)
{
tmp = Num & mask[i]; //tmp=0x2000,tmp=0x0300,tmp=0x0020,tmp=0x0003
buff[i] = (uint8_t)(tmp >> offset[i]);//buff[0]=0x02,buff[1]=0x03,buff[0]=0x02,buff[0]=0x03
}
}
/*******************************************************************************
* Function Name : Disp_BW(uint8_t num)
* Description : 显示百位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Disp_BW(uint8_t num)
{
uint8_t num_buf[4];
ConvertNum(num_buf,num);
HAL_LCD_Write(&hlcd, COM1, Mask_B, num_buf[0]<<SEG_B);//0x0001 0000 0000 0000
HAL_LCD_Write(&hlcd, COM2, Mask_B, num_buf[1]<<SEG_B);//0x0100 1000 0000 1000
HAL_LCD_Write(&hlcd, COM3, Mask_B, num_buf[2]<<SEG_B);//0x0100 1000 0000 1000
HAL_LCD_Write(&hlcd, COM4, Mask_B, num_buf[3]<<SEG_B);//0x0000 0000 0000 0000
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Display_Temp_C(float temp)
* Description : 显示小数类型温度,摄氏度
* Inputs : 温度
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Display_Temp_C(float tempC)
{
/*
1.提取temp的每一位
2.把每一位转换为数组
3.将每一位显示出来
#define SEG_S 3
#define SEG_G 5
#define SEG_P 7
RAM0写入的数据为:Buff_S[0]<<SEG_S|Buff_G[0]<<SEG_G|Buff_P[0]<<SEG_P
RAM2写入的数据为:Buff_S[1]<<SEG_S|Buff_G[1]<<SEG_G|Buff_P[1]<<SEG_P
RAM4写入的数据为:Buff_S[2]<<SEG_S|Buff_G[2]<<SEG_G|Buff_P[2]<<SEG_P
RAM6写入的数据为:Buff_S[3]<<SEG_S|Buff_G[3]<<SEG_G|Buff_P[3]<<SEG_P
*/
uint8_t Buff_S[4],Buff_G[4],Buff_P[4];
int Temp=0;
uint8_t Shi=0,Ge=0,Point=0;
uint8_t Num_For_Point=0;//再次处理十分位数据所用
Temp=tempC*10; //将带一位小数的float类型的温度转换为三位数的int型变量
Point=Temp%10; //去温度的小数位
Ge=Temp%100/10; //去温度的个位
Shi=Temp/100; //取温度的十位
ConvertNum(Buff_P,Point);
ConvertNum(Buff_G,Ge);
ConvertNum(Buff_S,Shi); //将三位数字转化为可以显示的数组
/*由于十分位的两个段并不是连续的,所以在此再次对十分位要显示的数据进行处理*/
for(Num_For_Point=0;Num_For_Point<4;Num_For_Point++)
{
if(Buff_P[Num_For_Point]==0x03)
{
Buff_P[Num_For_Point]=0x05;
}
else if(Buff_P[Num_For_Point]==0x02)
{
Buff_P[Num_For_Point]=0x04;
}
}
/**************************************************************************/
HAL_LCD_Clear(&hlcd);
//显示整数
HAL_LCD_Write(&hlcd, COM1, Mask_S&Mask_G&Mask_P, Buff_S[0]<<SEG_S|Buff_G[0]<<SEG_G|Buff_P[0]<<SEG_P|1<<12);
HAL_LCD_Write(&hlcd, COM2, Mask_S&Mask_G&Mask_P, Buff_S[1]<<SEG_S|Buff_G[1]<<SEG_G|Buff_P[1]<<SEG_P);
HAL_LCD_Write(&hlcd, COM3, Mask_S&Mask_G&Mask_P, Buff_S[2]<<SEG_S|Buff_G[2]<<SEG_G|Buff_P[2]<<SEG_P);
HAL_LCD_Write(&hlcd, COM4, Mask_S&Mask_G&Mask_P, Buff_S[3]<<SEG_S|Buff_G[3]<<SEG_G|Buff_P[3]<<SEG_P);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Display_Temp_F(float temp)
* Description : 显示小数类型温度,华氏度
* Inputs : 摄氏度温度
* Outputs : None
* Return : None
* Notes : 摄氏度 = (华氏度 - 32°F) ÷ 1.8
*******************************************************************************/
void Display_Temp_F(float tempF)
{
/*
1.提取temp的每一位
2.把每一位转换为数组
3.将每一位显示出来
#define SEG_S 3
#define SEG_G 5
#define SEG_P 7
RAM0写入的数据为:Buff_S[0]<<SEG_S|Buff_G[0]<<SEG_G|Buff_P[0]<<SEG_P
RAM2写入的数据为:Buff_S[1]<<SEG_S|Buff_G[1]<<SEG_G|Buff_P[1]<<SEG_P
RAM4写入的数据为:Buff_S[2]<<SEG_S|Buff_G[2]<<SEG_G|Buff_P[2]<<SEG_P
RAM6写入的数据为:Buff_S[3]<<SEG_S|Buff_G[3]<<SEG_G|Buff_P[3]<<SEG_P
*/
uint8_t Buff_S[4],Buff_G[4],Buff_P[4];
int TempF=0;
uint8_t Bai=0,Shi=0,Ge=0,Point=0;
uint8_t Num_For_Point=0;//再次处理十分位数据所用
TempF=((int)(tempF*18)+320); //将带一位小数的float类型的温度转换为三位数的int型变量
if(TempF>1000||TempF==1000)
{
Point=TempF%10; //去温度的小数位
Ge=TempF%100/10; //去温度的个位
Shi=TempF%1000/100;
Bai=TempF/1000; //取温度的最高位
}
else
{
Point=TempF%10; //去温度的小数位
Ge=TempF%100/10; //去温度的个位
Shi=TempF/100; //取温度的十位
}
ConvertNum(Buff_P,Point);
ConvertNum(Buff_G,Ge);
ConvertNum(Buff_S,Shi); //将三位数字转化为可以显示的数组
/*由于十分位的两个段并不是连续的,所以在此再次对十分位要显示的数据进行处理*/
for(Num_For_Point=0;Num_For_Point<4;Num_For_Point++)
{
if(Buff_P[Num_For_Point]==0x03)
{
Buff_P[Num_For_Point]=0x05;
}
else if(Buff_P[Num_For_Point]==0x02)
{
Buff_P[Num_For_Point]=0x04;
}
}
/**************************************************************************/
HAL_LCD_Clear(&hlcd);
//显示整数
HAL_LCD_Write(&hlcd, COM1, Mask_S&Mask_G&Mask_P, Buff_S[0]<<SEG_S|Buff_G[0]<<SEG_G|Buff_P[0]<<SEG_P|1<<12);
HAL_LCD_Write(&hlcd, COM2, Mask_S&Mask_G&Mask_P, Buff_S[1]<<SEG_S|Buff_G[1]<<SEG_G|Buff_P[1]<<SEG_P);
HAL_LCD_Write(&hlcd, COM3, Mask_S&Mask_G&Mask_P, Buff_S[2]<<SEG_S|Buff_G[2]<<SEG_G|Buff_P[2]<<SEG_P);
HAL_LCD_Write(&hlcd, COM4, Mask_S&Mask_G&Mask_P, Buff_S[3]<<SEG_S|Buff_G[3]<<SEG_G|Buff_P[3]<<SEG_P);
HAL_LCD_UpdateDisplayRequest(&hlcd);
if(Bai)
Disp_BW(Bai);
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* Inputs : 枚举类型ICON中的图标名称
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Diaplay_Icon(ICON icon,uint8_t status)
{
if(icon==Temp_C)
{
HAL_LCD_Write(&hlcd, COM_Temp_C, Mask_Temp_C, status<<SEG_Temp_C);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Temp_F)
{
HAL_LCD_Write(&hlcd, COM_Temp_F, Mask_Temp_F, status<<SEG_Temp_F);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Buzzer)
{
HAL_LCD_Write(&hlcd, COM_Buzzer, Mask_Buzzer, status<<SEG_Buzzer);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Body)
{
HAL_LCD_Write(&hlcd, COM_Body, Mask_Body, status<<SEG_Body);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==WuTi)
{
HAL_LCD_Write(&hlcd, COM_WuTi, Mask_WuTi, status<<SEG_WuTi);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==BLUE)
{
HAL_LCD_Write(&hlcd, COM_BLUE, Mask_BLUE, status<<SEG_BLUE);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==LOGO)
{
HAL_LCD_Write(&hlcd, COM_LOGO, Mask_LOGO, status<<SEG_LOGO);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* Inputs : 电量等级:0/1/2/3
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Display_Power(uint8_t grade)
{
switch(grade)
{
case 0:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 0<<SEG_Battery1);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 1:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 2:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 3:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);//0x0000 0000 0000 0011
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 1<<SEG_Battery3);//0x0000 0000 0000 0011
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
default:
break;
}
}
改版完善:(V1.2)
修改内容:
- 去掉摄氏度、华氏度显示函数,改为显示数字
- 修改计算错误的掩码(错误的掩码将导致显示冲突,也就是后显示的会把之前要显示的内容覆盖掉)
- 加入显示LO、HI、‘----字样
/*
LCD_RAM_REGISTER0——>COM3
LCD_RAM_REGISTER2——>COM2
LCD_RAM_REGISTER4——>COM1
LCD_RAM_REGISTER6——>COM4
*/
/* USER CODE BEGIN 0 */
static void ConvertNum(uint8_t buff[4],int InputNum);
static void Disp_PW(uint8_t num);
static void Disp_GW(uint8_t num);
static void Disp_SW(uint8_t num);
static void Disp_BW(uint8_t num);
/* USER CODE END 0 */
LCD_HandleTypeDef hlcd;
/* LCD init function */
void MX_LCD_Init(void)
{
hlcd.Instance = LCD;
hlcd.Init.Prescaler = LCD_PRESCALER_2;
hlcd.Init.Divider = LCD_DIVIDER_31;
hlcd.Init.Duty = LCD_DUTY_1_4;
hlcd.Init.Bias = LCD_BIAS_1_3;
hlcd.Init.VoltageSource = LCD_VOLTAGESOURCE_INTERNAL;
hlcd.Init.Contrast = LCD_CONTRASTLEVEL_5;
hlcd.Init.DeadTime = LCD_DEADTIME_2;
hlcd.Init.PulseOnDuration = LCD_PULSEONDURATION_7;
hlcd.Init.HighDrive = LCD_HIGHDRIVE_0;
hlcd.Init.BlinkMode = LCD_BLINKMODE_OFF;
hlcd.Init.BlinkFrequency = LCD_BLINKFREQUENCY_DIV8;
hlcd.Init.MuxSegment = LCD_MUXSEGMENT_DISABLE;
if (HAL_LCD_Init(&hlcd) != HAL_OK)
{
Error_Handler();
}
}
void HAL_LCD_MspInit(LCD_HandleTypeDef* lcdHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(lcdHandle->Instance==LCD)
{
/* USER CODE BEGIN LCD_MspInit 0 */
/* USER CODE END LCD_MspInit 0 */
/* LCD clock enable */
__HAL_RCC_LCD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**LCD GPIO Configuration
PC3 ------> LCD_SEG21
PA1 ------> LCD_SEG0
PA2 ------> LCD_SEG1
PA3 ------> LCD_SEG2
PA6 ------> LCD_SEG3
PA7 ------> LCD_SEG4
PC4 ------> LCD_SEG22
PB0 ------> LCD_SEG5
PB1 ------> LCD_SEG6
PB10 ------> LCD_SEG10
PB11 ------> LCD_SEG11
PB12 ------> LCD_SEG12
PB14 ------> LCD_SEG14
PB15 ------> LCD_SEG15
PA8 ------> LCD_COM0
PA9 ------> LCD_COM1
PA10 ------> LCD_COM2
PB9 ------> LCD_COM3
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN LCD_MspInit 1 */
/* USER CODE END LCD_MspInit 1 */
}
}
void HAL_LCD_MspDeInit(LCD_HandleTypeDef* lcdHandle)
{
if(lcdHandle->Instance==LCD)
{
/* USER CODE BEGIN LCD_MspDeInit 0 */
/* USER CODE END LCD_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_LCD_CLK_DISABLE();
/**LCD GPIO Configuration
PC3 ------> LCD_SEG21
PA1 ------> LCD_SEG0
PA2 ------> LCD_SEG1
PA3 ------> LCD_SEG2
PA6 ------> LCD_SEG3
PA7 ------> LCD_SEG4
PC4 ------> LCD_SEG22
PB0 ------> LCD_SEG5
PB1 ------> LCD_SEG6
PB10 ------> LCD_SEG10
PB11 ------> LCD_SEG11
PB12 ------> LCD_SEG12
PB14 ------> LCD_SEG14
PB15 ------> LCD_SEG15
PA8 ------> LCD_COM0
PA9 ------> LCD_COM1
PA10 ------> LCD_COM2
PB9 ------> LCD_COM3
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3|GPIO_PIN_4);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_9);
/* USER CODE BEGIN LCD_MspDeInit 1 */
/* USER CODE END LCD_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
const uint16_t mask[4]={0xF000,0x0F00,0x00F0,0x000F};
const uint8_t offset[4]={12,8,4,0};
const uint16_t Num_Map[15]={0x2323,0x0220,0x2132,0x2232,0x0231,0x2213,0x2313,0x0222,0x2333,0x2233,0x0010,0x0331,0x0200,0x2101,0x2310};
// 0 1 2 3 4 5 6 7 8 9 ---- H
/*******************************************************************************
* Function Name : ConvertNum
* Description : 查找输入参数对应的字符编码
* Inputs : InputNum--显示字符
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
static void ConvertNum(uint8_t buff[4],int InputNum)
{
uint16_t Num, tmp = 0;
uint8_t i;
if((InputNum>=0)&&(InputNum<=15))
{
Num=Num_Map[InputNum];
}
else
{
Num=0;
}
for(i = 0;i < 4; i++)
{
tmp = Num & mask[i];
buff[i] = (uint8_t)(tmp >> offset[i]);
}
}
/*******************************************************************************
* Function Name : Disp_BW(uint8_t num)
* Description : 显示百位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
static void Disp_BW(uint8_t num)
{
uint8_t num_buf[4];
ConvertNum(num_buf,num);
HAL_LCD_Write(&hlcd, COM1, Mask_B, num_buf[0]<<SEG_B);
HAL_LCD_Write(&hlcd, COM2, Mask_B, num_buf[1]<<SEG_B);
HAL_LCD_Write(&hlcd, COM3, Mask_B, num_buf[2]<<SEG_B);
HAL_LCD_Write(&hlcd, COM4, Mask_B, num_buf[3]<<SEG_B);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_SW(uint8_t num)
* Description : 显示十位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
static void Disp_SW(uint8_t num)
{
uint8_t num_buf[4];
ConvertNum(num_buf,num);
HAL_LCD_Write(&hlcd, COM1, Mask_S, num_buf[0]<<SEG_S);
HAL_LCD_Write(&hlcd, COM2, Mask_S, num_buf[1]<<SEG_S);
HAL_LCD_Write(&hlcd, COM3, Mask_S, num_buf[2]<<SEG_S);
HAL_LCD_Write(&hlcd, COM4, Mask_S, num_buf[3]<<SEG_S);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_GW(uint8_t num)
* Description : 显示个位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : 由于BT3和个位显示有冲突,所以在此处理
*******************************************************************************/
static void Disp_GW(uint8_t num)
{
uint8_t num_buf[4];
ConvertNum(num_buf,num);
HAL_LCD_Write(&hlcd, COM1, Mask_G|Mask_Battery3, num_buf[0]<<SEG_G);
HAL_LCD_Write(&hlcd, COM2, Mask_G|Mask_Battery3, num_buf[1]<<SEG_G);
HAL_LCD_Write(&hlcd, COM3, Mask_G|Mask_Battery3, num_buf[2]<<SEG_G);
HAL_LCD_Write(&hlcd, COM4, Mask_G|Mask_Battery3, num_buf[3]<<SEG_G);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_PW(uint8_t num)
* Description : 显示十分位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : 由于十分位的两个段并不是连续的,所以在此再次对十分位要显示的数据进行处理
*******************************************************************************/
static void Disp_PW(uint8_t num)
{
uint8_t num_buf[4];
uint8_t Num_For_Point=0;//再次处理十分位数据所用
ConvertNum(num_buf,num);
/*由于十分位的两个段并不是连续的,所以在此再次对十分位要显示的数据进行处理*/
for(Num_For_Point=0;Num_For_Point<4;Num_For_Point++)
{
if(num_buf[Num_For_Point]==0x3)
{
num_buf[Num_For_Point]=0x5;
}
else if(num_buf[Num_For_Point]==0x2)
{
num_buf[Num_For_Point]=0x4;
}
}
HAL_LCD_Write(&hlcd, COM1, Mask_P, num_buf[0]<<SEG_P);
HAL_LCD_Write(&hlcd, COM2, Mask_P, num_buf[1]<<SEG_P);
HAL_LCD_Write(&hlcd, COM3, Mask_P, num_buf[2]<<SEG_P);
HAL_LCD_Write(&hlcd, COM4, Mask_P, num_buf[3]<<SEG_P);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Display_Num(float temp)
* Description : 显示小数
* Inputs : 小数
* Outputs : None
* Return : None
* Notes :
*******************************************************************************/
void Display_Num(float temp)
{
uint16_t Num=0;
uint8_t Bai=0,Shi=0,Ge=0,Point=0;
Num=(int)(temp*10.0);
if(Num<1000)
{
Shi=Num/100;
Ge=Num%100/10;
Point=Num%10;
Disp_SW(Shi);
Disp_GW(Ge);
Disp_PW(Point);
Diaplay_Icon(POINT,1);//显示小数点
}
else
{
Bai=Num/1000;
Shi=Num%1000/100;
Ge=Num%100/10;
Point=Num%10;
Disp_BW(Bai);
Disp_SW(Shi);
Disp_GW(Ge);
Disp_PW(Point);
Diaplay_Icon(POINT,1);//显示小数点
}
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* icon : 枚举类型ICON中的图标名称
* status : 枚举类型ICON中的图标显示状态
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Diaplay_Icon(ICON icon,uint8_t status)
{
if(icon==Temp_C)
{
HAL_LCD_Write(&hlcd, COM_Temp_C, Mask_Temp_C, status<<SEG_Temp_C);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Temp_F)
{
HAL_LCD_Write(&hlcd, COM_Temp_F, Mask_Temp_F, status<<SEG_Temp_F);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Buzzer)
{
HAL_LCD_Write(&hlcd, COM_Buzzer, Mask_Buzzer, status<<SEG_Buzzer);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Body)
{
HAL_LCD_Write(&hlcd, COM_Body, Mask_Body, status<<SEG_Body);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==WuTi)
{
HAL_LCD_Write(&hlcd, COM_WuTi, Mask_WuTi, status<<SEG_WuTi);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==BLUE)
{
HAL_LCD_Write(&hlcd, COM_BLUE, Mask_BLUE, status<<SEG_BLUE);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==LOGO)
{
HAL_LCD_Write(&hlcd, COM_LOGO, Mask_LOGO, status<<SEG_LOGO);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==POINT)
{
HAL_LCD_Write(&hlcd, COM_POINT, Mask_Point, status<<SEG_Point);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==HIGH)
{
if(status)
{
Disp_SW(11);//显示H
Disp_GW(12);//显示I
}
else
{
Disp_SW(21);//清除显示HI
Disp_GW(22);
}
}
else if(icon==LOW)
{
if(status)
{
Disp_SW(13);//显示L
Disp_GW(14);//显示O
}
else
{
Disp_SW(21);//清除显示LO
Disp_GW(22);
}
}
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* Inputs : 电量等级:0/1/2/3
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Display_Power(uint8_t grade)
{
switch(grade)
{
case 0:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 0<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 1:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 2:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 3:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 1<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 4:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 0<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 0<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
default:
break;
}
}
/*******************************************************************************
* Function Name : Clear_Temp_C(float temp)
* Description : 清除温度显示
* Inputs : None
* Outputs : None
* Return : None
* Notes : 传送非(0-10)的ID即显示为空,ID=10为"- - - -"
*******************************************************************************/
void Clear_Temp_C(void)
{
Disp_BW(10);
Disp_SW(10);
Disp_GW(10);
Disp_PW(10);
}
/*******************************************************************************
* Function Name : Display_All(void)
* Description : 显示全屏
* Inputs : None
* Outputs : None
* Return : None
* Notes : NONE
*******************************************************************************/
void Display_All(void)
{
Display_Power(3);//显示电量
Diaplay_Icon(Temp_C,1);//显示所有图标
Diaplay_Icon(Temp_F,1);
Diaplay_Icon(Buzzer,1);
Diaplay_Icon(Body,1);
Diaplay_Icon(WuTi,1);
Diaplay_Icon(BLUE,1);
Diaplay_Icon(LOGO,1);
Disp_BW(8); //显示四个8
Disp_SW(8);
Disp_GW(8);
Disp_PW(8);
}
void lcd_init(void)
{
MX_LCD_Init();
HAL_LCD_MspInit(&hlcd);
}
typedef enum
{
Temp_C,
Temp_F,
Buzzer,
Body,
WuTi,
BLUE,
LOGO,
POINT,
HIGH,
LOW
}ICON;
//COM口定义
#define COM1 LCD_RAM_REGISTER4
#define COM2 LCD_RAM_REGISTER2
#define COM3 LCD_RAM_REGISTER0
#define COM4 LCD_RAM_REGISTER6
//段定义
#define SEG_Temp_C 15
#define SEG_Temp_F 15
#define SEG_Buzzer 15
#define SEG_Body 21
#define SEG_WuTi 4
#define SEG_BLUE 21
#define SEG_Battery1 21
#define SEG_Battery2 21
#define SEG_Battery3 10
#define SEG_Battery 15
#define SEG_LOGO 5
#define SEG_B 0
#define SEG_S 2
#define SEG_G 10
#define SEG_P 12
#define SEG_Point 12
//COM口定义
#define COM_Temp_C COM4
#define COM_Temp_F COM3
#define COM_Buzzer COM2
#define COM_Body COM2
#define COM_WuTi COM1
#define COM_BLUE COM1
#define COM_Battery1 COM4
#define COM_Battery2 COM3
#define COM_Battery3 COM1
#define COM_Battery COM1
#define COM_LOGO COM1
#define COM_POINT COM1
//掩码定义
#define Mask_Temp_C 0xFFFF7FFF
#define Mask_Temp_F 0xFFFF7FFF
#define Mask_Buzzer 0xFFFF7FFF
#define Mask_Body 0xFFDFFFFF
#define Mask_WuTi 0xFFFFFFEF
#define Mask_BLUE 0xFFDFFFFF
#define Mask_Battery1 0xFFDFFFFF
#define Mask_Battery2 0xFFDFFFFF
#define Mask_Battery3 0xFFFFFEFF
#define Mask_Battery 0xFFFF7FFF
#define Mask_LOGO 0xFFFFFFDF
#define Mask_B 0xFFFFFFFC
#define Mask_S 0xFFFFFFF3
#define Mask_G 0xFFFFF3FF
#define Mask_P 0xFFFFAFFF
#define Mask_Point 0xFFFFEFFF
void lcd_init(void);
void Display_Num(float temp);
void Display_Power(uint8_t grade);
void Diaplay_Icon(ICON icon,uint8_t status);
void Clear_Temp_C(void);
void Display_All(void);
再次优化V1.3
优化内容:
- 解决V1.2中BT3与个位数显示冲突问题
- 修改字符Map
- 生成单独的LCD驱动程序
/**
******************************************************************************
* File Name : LCD.c
* Description : This file provides code for the configuration
* of the LCD instances.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "lcd.h"
/* USER CODE BEGIN 0 */
static void ConvertNum(uint8_t buff[4],int InputNum);
static void Disp_PW(uint8_t num);
static void Disp_GW(uint8_t num);
static void Disp_SW(uint8_t num);
static void Disp_BW(uint8_t num);
/* USER CODE END 0 */
LCD_HandleTypeDef hlcd;
/* LCD init function */
void MX_LCD_Init(void)
{
hlcd.Instance = LCD;
hlcd.Init.Prescaler = LCD_PRESCALER_2;
hlcd.Init.Divider = LCD_DIVIDER_31;
hlcd.Init.Duty = LCD_DUTY_1_4;
hlcd.Init.Bias = LCD_BIAS_1_3;
hlcd.Init.VoltageSource = LCD_VOLTAGESOURCE_INTERNAL;
hlcd.Init.Contrast = LCD_CONTRASTLEVEL_5;
hlcd.Init.DeadTime = LCD_DEADTIME_2;
hlcd.Init.PulseOnDuration = LCD_PULSEONDURATION_7;
hlcd.Init.HighDrive = LCD_HIGHDRIVE_0;
hlcd.Init.BlinkMode = LCD_BLINKMODE_OFF;
hlcd.Init.BlinkFrequency = LCD_BLINKFREQUENCY_DIV8;
hlcd.Init.MuxSegment = LCD_MUXSEGMENT_DISABLE;
if (HAL_LCD_Init(&hlcd) != HAL_OK)
{
Error_Handler();
}
}
void HAL_LCD_MspInit(LCD_HandleTypeDef* lcdHandle)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(lcdHandle->Instance==LCD)
{
/* USER CODE BEGIN LCD_MspInit 0 */
/* USER CODE END LCD_MspInit 0 */
/* LCD clock enable */
__HAL_RCC_LCD_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**LCD GPIO Configuration
PC3 ------> LCD_SEG21
PA1 ------> LCD_SEG0
PA2 ------> LCD_SEG1
PA3 ------> LCD_SEG2
PA6 ------> LCD_SEG3
PA7 ------> LCD_SEG4
PC4 ------> LCD_SEG22
PB0 ------> LCD_SEG5
PB1 ------> LCD_SEG6
PB10 ------> LCD_SEG10
PB11 ------> LCD_SEG11
PB12 ------> LCD_SEG12
PB14 ------> LCD_SEG14
PB15 ------> LCD_SEG15
PA8 ------> LCD_COM0
PA9 ------> LCD_COM1
PA10 ------> LCD_COM2
PB9 ------> LCD_COM3
*/
GPIO_InitStruct.Pin = GPIO_PIN_3|GPIO_PIN_4;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_9;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF1_LCD;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN LCD_MspInit 1 */
/* USER CODE END LCD_MspInit 1 */
}
}
void HAL_LCD_MspDeInit(LCD_HandleTypeDef* lcdHandle)
{
if(lcdHandle->Instance==LCD)
{
/* USER CODE BEGIN LCD_MspDeInit 0 */
/* USER CODE END LCD_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_LCD_CLK_DISABLE();
/**LCD GPIO Configuration
PC3 ------> LCD_SEG21
PA1 ------> LCD_SEG0
PA2 ------> LCD_SEG1
PA3 ------> LCD_SEG2
PA6 ------> LCD_SEG3
PA7 ------> LCD_SEG4
PC4 ------> LCD_SEG22
PB0 ------> LCD_SEG5
PB1 ------> LCD_SEG6
PB10 ------> LCD_SEG10
PB11 ------> LCD_SEG11
PB12 ------> LCD_SEG12
PB14 ------> LCD_SEG14
PB15 ------> LCD_SEG15
PA8 ------> LCD_COM0
PA9 ------> LCD_COM1
PA10 ------> LCD_COM2
PB9 ------> LCD_COM3
*/
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_3|GPIO_PIN_4);
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_6
|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
HAL_GPIO_DeInit(GPIOB, GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_10|GPIO_PIN_11
|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_9);
/* USER CODE BEGIN LCD_MspDeInit 1 */
/* USER CODE END LCD_MspDeInit 1 */
}
}
/* USER CODE BEGIN 1 */
const uint16_t mask[4]={0xF000,0x0F00,0x00F0,0x000F};
const uint8_t offset[4]={12,8,4,0};
const uint16_t Num_Map[15]={0x1323,0x0220,0x1132,0x1232,0x0231,0x1213,0x1313,0x0222,0x1333,0x1233,0x0010,0x0331,0x0200,0x1101,0x1310};
// 0 1 2 3 4 5 6 7 8 9 ---- H
/*******************************************************************************
* Function Name : ConvertNum
* Description : 查找输入参数对应的字符编码
* Inputs : InputNum--显示字符
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
static void ConvertNum(uint8_t buff[4],int InputNum)
{
uint16_t Num, tmp = 0;
uint8_t i;
if((InputNum>=0)&&(InputNum<=15))
{
Num=Num_Map[InputNum];
}
else
{
Num=0;
}
for(i = 0;i < 4; i++)
{
tmp = Num & mask[i];
buff[i] = (uint8_t)(tmp >> offset[i]);
}
}
/*******************************************************************************
* Function Name : Disp_BW(uint8_t num)
* Description : 显示百位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Disp_BW(uint8_t num)
{
uint8_t num_buf[4];
ConvertNum(num_buf,num);
HAL_LCD_Write(&hlcd, COM1, Mask_B_COM1, num_buf[0]<<SEG_B_COM1);
HAL_LCD_Write(&hlcd, COM2, Mask_B, num_buf[1]<<SEG_B);
HAL_LCD_Write(&hlcd, COM3, Mask_B, num_buf[2]<<SEG_B);
HAL_LCD_Write(&hlcd, COM4, Mask_B, num_buf[3]<<SEG_B);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_SW(uint8_t num)
* Description : 显示十位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Disp_SW(uint8_t num)
{
uint8_t num_buf[4];
ConvertNum(num_buf,num);
HAL_LCD_Write(&hlcd, COM1, Mask_S_COM1, num_buf[0]<<SEG_S_COM1);
HAL_LCD_Write(&hlcd, COM2, Mask_S, num_buf[1]<<SEG_S);
HAL_LCD_Write(&hlcd, COM3, Mask_S, num_buf[2]<<SEG_S);
HAL_LCD_Write(&hlcd, COM4, Mask_S, num_buf[3]<<SEG_S);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_GW(uint8_t num)
* Description : 显示个位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : 由于BT3和个位显示有冲突,所以在此处理
*******************************************************************************/
void Disp_GW(uint8_t num)
{
uint8_t num_buf[4];
ConvertNum(num_buf,num);
HAL_LCD_Write(&hlcd, COM1, Mask_G_COM1, num_buf[0]<<SEG_G_COM1);
HAL_LCD_Write(&hlcd, COM2, Mask_G, num_buf[1]<<SEG_G);
HAL_LCD_Write(&hlcd, COM3, Mask_G, num_buf[2]<<SEG_G);
HAL_LCD_Write(&hlcd, COM4, Mask_G, num_buf[3]<<SEG_G);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_PW(uint8_t num)
* Description : 显示十分位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : 由于十分位的两个段并不是连续的,所以在此再次对十分位要显示的数据进行处理
*******************************************************************************/
void Disp_PW(uint8_t num)
{
uint8_t num_buf[4];
uint8_t Num_For_Point=0;//再次处理十分位数据所用
ConvertNum(num_buf,num);
/*由于十分位的两个段并不是连续的,所以在此再次对十分位要显示的数据进行处理*/
for(Num_For_Point=1;Num_For_Point<4;Num_For_Point++)
{
if(num_buf[Num_For_Point]==0x3)
{
num_buf[Num_For_Point]=0x5;
}
else if(num_buf[Num_For_Point]==0x2)
{
num_buf[Num_For_Point]=0x4;
}
}
HAL_LCD_Write(&hlcd, COM1, Mask_P_COM1, num_buf[0]<<SEG_P_COM1);
HAL_LCD_Write(&hlcd, COM2, Mask_P, num_buf[1]<<SEG_P);
HAL_LCD_Write(&hlcd, COM3, Mask_P, num_buf[2]<<SEG_P);
HAL_LCD_Write(&hlcd, COM4, Mask_P, num_buf[3]<<SEG_P);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Display_Num(float temp)
* Description : 显示小数
* Inputs : 小数
* Outputs : None
* Return : None
* Notes :
*******************************************************************************/
void Display_Num(float temp)
{
uint16_t Num=0;
uint8_t Bai=0,Shi=0,Ge=0,Point=0;
Num=(int)(temp*10.0);
if(Num<1000)
{
Shi=Num/100;
Ge=Num%100/10;
Point=Num%10;
Disp_SW(Shi);
Disp_GW(Ge);
Disp_PW(Point);
Diaplay_Icon(POINT,1);//显示小数点
}
else
{
Bai=Num/1000;
Shi=Num%1000/100;
Ge=Num%100/10;
Point=Num%10;
Disp_BW(Bai);
Disp_SW(Shi);
Disp_GW(Ge);
Disp_PW(Point);
Diaplay_Icon(POINT,1);//显示小数点
}
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* icon : 枚举类型ICON中的图标名称
* status : 枚举类型ICON中的图标显示状态
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Diaplay_Icon(ICON icon,uint8_t status)
{
if(icon==Temp_C)
{
HAL_LCD_Write(&hlcd, COM_Temp_C, Mask_Temp_C, status<<SEG_Temp_C);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Temp_F)
{
HAL_LCD_Write(&hlcd, COM_Temp_F, Mask_Temp_F, status<<SEG_Temp_F);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Buzzer)
{
HAL_LCD_Write(&hlcd, COM_Buzzer, Mask_Buzzer, status<<SEG_Buzzer);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Body)
{
HAL_LCD_Write(&hlcd, COM_Body, Mask_Body, status<<SEG_Body);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==WuTi)
{
HAL_LCD_Write(&hlcd, COM_WuTi, Mask_WuTi, status<<SEG_WuTi);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==BLUE)
{
HAL_LCD_Write(&hlcd, COM_BLUE, Mask_BLUE, status<<SEG_BLUE);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==LOGO)
{
HAL_LCD_Write(&hlcd, COM_LOGO, Mask_LOGO, status<<SEG_LOGO);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==POINT)
{
HAL_LCD_Write(&hlcd, COM_POINT, Mask_Point, status<<SEG_Point);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==HIGH)
{
if(status)
{
Disp_SW(11);//显示H
Disp_GW(12);//显示I
}
else
{
Disp_SW(21);//清除显示HI
Disp_GW(22);
}
}
else if(icon==LOW)
{
if(status)
{
Disp_SW(13);//显示L
Disp_GW(14);//显示O
}
else
{
Disp_SW(21);//清除显示LO
Disp_GW(22);
}
}
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* Inputs : 电量等级:0/1/2/3
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Display_Power(uint8_t grade)
{
switch(grade)
{
case 0:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 0<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 1:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 2:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 3:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 1<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 1<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
case 4:
HAL_LCD_Write(&hlcd, COM_Battery, Mask_Battery, 0<<SEG_Battery);
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 0<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
HAL_LCD_UpdateDisplayRequest(&hlcd);
break;
default:
break;
}
}
/*******************************************************************************
* Function Name : Clear_Temp_C(float temp)
* Description : 清除温度显示
* Inputs : None
* Outputs : None
* Return : None
* Notes : 传送非(0-10)的ID即显示为空,ID=10为"- - - -"
*******************************************************************************/
void Clear_Temp_C(void)
{
Disp_BW(20);
Disp_SW(20);
Disp_GW(20);
Disp_PW(20);
}
/*******************************************************************************
* Function Name : Display_All(void)
* Description : 显示全屏
* Inputs : None
* Outputs : None
* Return : None
* Notes : NONE
*******************************************************************************/
void Display_All(void)
{
Display_Power(3);//显示电量
Diaplay_Icon(Temp_C,1);//显示所有图标
Diaplay_Icon(Temp_F,1);
Diaplay_Icon(Buzzer,1);
Diaplay_Icon(Body,1);
Diaplay_Icon(WuTi,1);
Diaplay_Icon(BLUE,1);
Diaplay_Icon(LOGO,1);
Disp_BW(8); //显示四个8
Disp_SW(8);
Disp_GW(8);
Disp_PW(8);
}
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
/**
******************************************************************************
* File Name : LCD.h
* Description : This file provides code for the configuration
* of the LCD instances.
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __lcd_H
#define __lcd_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern LCD_HandleTypeDef hlcd;
/* USER CODE BEGIN Private defines */
typedef enum
{
Temp_C,
Temp_F,
Buzzer,
Body,
WuTi,
BLUE,
LOGO,
POINT,
HIGH,
LOW
}ICON;
//COM口定义
#define COM1 LCD_RAM_REGISTER4
#define COM2 LCD_RAM_REGISTER2
#define COM3 LCD_RAM_REGISTER0
#define COM4 LCD_RAM_REGISTER6
//段定义
#define SEG_Temp_C 15
#define SEG_Temp_F 15
#define SEG_Buzzer 15
#define SEG_Body 21
#define SEG_WuTi 4
#define SEG_BLUE 21
#define SEG_Battery1 21
#define SEG_Battery2 21
#define SEG_Battery3 10
#define SEG_Battery 15
#define SEG_LOGO 5
#define SEG_B 0
#define SEG_B_COM1 1
#define SEG_S 2
#define SEG_S_COM1 3
#define SEG_G 10
#define SEG_G_COM1 11
#define SEG_P 12
#define SEG_P_COM1 14
#define SEG_Point 12
//COM口定义
#define COM_Temp_C COM4
#define COM_Temp_F COM3
#define COM_Buzzer COM2
#define COM_Body COM2
#define COM_WuTi COM1
#define COM_BLUE COM1
#define COM_Battery1 COM4
#define COM_Battery2 COM3
#define COM_Battery3 COM1
#define COM_Battery COM1
#define COM_LOGO COM1
#define COM_POINT COM1
//掩码定义
#define Mask_Temp_C 0xFFFF7FFF
#define Mask_Temp_F 0xFFFF7FFF
#define Mask_Buzzer 0xFFFF7FFF
#define Mask_Body 0xFFDFFFFF
#define Mask_WuTi 0xFFFFFFEF
#define Mask_BLUE 0xFFDFFFFF
#define Mask_Battery1 0xFFDFFFFF
#define Mask_Battery2 0xFFDFFFFF
#define Mask_Battery3 0xFFFFFBFF
#define Mask_Battery 0xFFFF7FFF
#define Mask_LOGO 0xFFFFFFDF
#define Mask_B 0xFFFFFFFC
#define Mask_B_COM1 0xFFFFFFFD
#define Mask_S 0xFFFFFFF3
#define Mask_S_COM1 0xFFFFFFF7
#define Mask_G 0xFFFFF3FF
#define Mask_G_COM1 0xFFFFF7FF
#define Mask_P 0xFFFFAFFF
#define Mask_P_COM1 0xFFFFBFFF
#define Mask_Point 0xFFFFEFFF
/* USER CODE END Private defines */
void MX_LCD_Init(void);
/* USER CODE BEGIN Prototypes */
void Display_Num(float temp);
void Display_Power(uint8_t grade);
void Diaplay_Icon(ICON icon,uint8_t status);
void Clear_Temp_C(void);
void Display_All(void);
/* USER CODE END Prototypes */
#ifdef __cplusplus
}
#endif
#endif /*__ lcd_H */
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
另一种显示方式:(更方便,彻底解决显示冲突的问题,不用考虑显示冲突的问题)
/* USER CODE BEGIN 1 */
uint8_t A=0,B=0,C=0,D=0,E=0,F=0,G=0;
/*******************************************************************************
* Function Name : ConvertNum
* Description : 根据输入的数字将对应的段进行操作,点亮或者熄灭
* Inputs : 输入的数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
static void ConvertNum(uint8_t InputNum)
{
switch(InputNum)
{
case 0://显示0
A=B=C=D=E=F=1;
G=0;
break;
case 1://显示1
B=C=1;
A=D=E=F=G=0;
break;
case 2://显示2
C=F=0;
A=B=D=E=G=1;
break;
case 3://显示3
E=F=0;
A=B=C=D=G=1;
break;
case 4://显示4
A=E=D=0;
B=C=F=G=1;
break;
case 5://显示5
B=E=0;
A=C=D=F=G=1;
break;
case 6://显示6
B=0;
A=C=D=E=F=G=1;
break;
case 7://显示7
E=D=G=F=0;
A=B=C=1;
break;
case 8://显示8
A=B=C=D=E=F=G=1;
break;
case 9://显示9
E=0;
A=B=C=D=F=G=1;
break;
case 10://显示H
A=D=0;
B=C=E=F=G=1;
break;
case 11://显示I
C=1;
A=B=D=E=F=G=0;
break;
case 12://显示L
D=E=F=1;
A=B=C=G=0;
break;
case 13://显示O
A=B=F=0;
C=D=G=1;
break;
case 14://显示-
G=1;
A=B=C=D=E=F=0;
break;
case 15://显示为空,即不显示
A=B=C=D=E=F=G=0;
break;
case 16://全部显示
A=B=C=D=E=F=G=1;
break;
default:
A=B=C=D=E=F=G=0;
break;
}
}
/*******************************************************************************
* Function Name : Disp_BW(void)
* Description : 非零数据则百位显示1,如果输入0则不显示
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Disp_BW(uint8_t num)
{
if(num)
{
HAL_LCD_Write(&hlcd, COM1, Mask_B, 1<<SEG_B);
}
else
{
HAL_LCD_Write(&hlcd, COM1, Mask_B, 0<<SEG_B);
}
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_SW(uint8_t num)
* Description : 显示十位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Disp_SW(uint8_t num)
{
ConvertNum(num);
HAL_LCD_Write(&hlcd, COM1, Mask_S_COM1, A<<SEG_S_COM1);
HAL_LCD_Write(&hlcd, COM2, Mask_S, F<<SEG_S|B<<SEG_S_COM1);
HAL_LCD_Write(&hlcd, COM3, Mask_S, G<<SEG_S|C<<SEG_S_COM1);
HAL_LCD_Write(&hlcd, COM4, Mask_S, E<<SEG_S|D<<SEG_S_COM1);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_GW(uint8_t num)
* Description : 显示个位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : 由于BT3和个位显示有冲突,所以在此处理
*******************************************************************************/
void Disp_GW(uint8_t num)
{
ConvertNum(num);
HAL_LCD_Write(&hlcd, COM1, Mask_G_COM1, A<<SEG_G_COM1);
HAL_LCD_Write(&hlcd, COM2, Mask_G, F<<SEG_G|B<<SEG_G_COM1);
HAL_LCD_Write(&hlcd, COM3, Mask_G, G<<SEG_G|C<<SEG_G_COM1);
HAL_LCD_Write(&hlcd, COM4, Mask_G, E<<SEG_G|D<<SEG_G_COM1);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Disp_PW(uint8_t num)
* Description : 显示十分位数字
* Inputs : 数字
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Disp_PW(uint8_t num)
{
ConvertNum(num);
HAL_LCD_Write(&hlcd, COM1, Mask_P_COM1, A<<SEG_P_COM1);
HAL_LCD_Write(&hlcd, COM2, Mask_P, F<<SEG_P|B<<SEG_P_COM1);
HAL_LCD_Write(&hlcd, COM3, Mask_P, G<<SEG_P|C<<SEG_P_COM1);
HAL_LCD_Write(&hlcd, COM4, Mask_P, E<<SEG_P|D<<SEG_P_COM1);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* icon : 枚举类型ICON中的图标名称
* status : 枚举类型ICON中的图标显示状态
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Diaplay_Icon(ICON icon,uint8_t status)
{
if(icon==Temp_C)
{
HAL_LCD_Write(&hlcd, COM_Temp_C, Mask_Temp_C, status<<SEG_Temp_C);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Temp_F)
{
HAL_LCD_Write(&hlcd, COM_Temp_F, Mask_Temp_F, status<<SEG_Temp_F);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Buzzer)
{
HAL_LCD_Write(&hlcd, COM_Buzzer, Mask_Buzzer, status<<SEG_Buzzer);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Body)
{
HAL_LCD_Write(&hlcd, COM_Body, Mask_Body, status<<SEG_Body);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==TiWen)
{
HAL_LCD_Write(&hlcd, COM_TiWen, Mask_TiWen, status<<SEG_TiWen);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==POINT)
{
HAL_LCD_Write(&hlcd, COM_Point, Mask_Point, status<<SEG_Point);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==Mode)
{
HAL_LCD_Write(&hlcd, COM_Mode, Mask_Mode, status<<SEG_Mode);
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
else if(icon==HIGH)
{
Disp_BW(0);
Disp_SW(15);//清除显示(显示为空)
if(status)
{
Disp_GW(10);//显示H
Disp_PW(11);//显示I
}
else
{
Disp_BW(0);
Disp_SW(15);//清除显示(显示为空)
}
}
else if(icon==LOW)
{
Disp_BW(0);
Disp_SW(15);//清除显示(显示为空)
if(status)
{
Disp_GW(12);//显示L
Disp_PW(13);//显示O
}
else
{
Disp_BW(0);
Disp_SW(15);//清除显示(显示为空)
}
}
}
/*******************************************************************************
* Function Name : Display_Num(float temp)
* Description : 显示小数
* Inputs : 小数
* Outputs : None
* Return : None
* Notes :
*******************************************************************************/
void Display_Num(float InputNum)
{
uint16_t DispNum=0;
uint8_t Bai=0,Shi=0,Ge=0,Point=0;
DispNum=(int)(InputNum*10);
if(DispNum<1000)
{
Bai=0;
Shi=DispNum/100;
Ge=DispNum%100/10;
Point=DispNum%10;
}
else
{
Bai=DispNum/1000;
Shi=DispNum%1000/100;
Ge=DispNum%100/10;
Point=DispNum%10;
}
Disp_BW(Bai);
Disp_SW(Shi);
Disp_GW(Ge);
Disp_PW(Point);
Diaplay_Icon(POINT,1);//显示小数点
}
/*******************************************************************************
* Function Name : Diaplay_Icon(ICON icon)
* Description : 显示图标
* Inputs : 电量等级:1/2/3
* Outputs : None
* Return : None
* Notes : None
*******************************************************************************/
void Display_Power(uint8_t grade)
{
switch(grade)
{
case 1:
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
break;
case 2:
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
break;
case 3:
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 1<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 1<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 1<<SEG_Battery3);
break;
case 4:
HAL_LCD_Write(&hlcd, COM_Battery1, Mask_Battery1, 0<<SEG_Battery1);
HAL_LCD_Write(&hlcd, COM_Battery2, Mask_Battery2, 0<<SEG_Battery2);
HAL_LCD_Write(&hlcd, COM_Battery3, Mask_Battery3, 0<<SEG_Battery3);
break;
default:
break;
}
HAL_LCD_UpdateDisplayRequest(&hlcd);
}
/*******************************************************************************
* Function Name : Clear_Temp_C(float temp)
* Description : 清除温度显示
* Inputs : None
* Outputs : None
* Return : None
* Notes : 传送非(0-10)的ID即显示为空,ID=10为"- - - -"
*******************************************************************************/
void Clear_Temp_C(void)
{
Disp_BW(0);
Disp_SW(15);
Disp_GW(15);
Disp_PW(15);
Diaplay_Icon(POINT,0);//不显示小数点
}
// "- - - -"
void lcd_temp_invalid(void)
{
Disp_BW(0);
Disp_SW(14);
Disp_GW(14);
Disp_PW(14);
}
/* USER CODE END 1 */
typedef enum
{
Temp_C,
Temp_F,
Buzzer,
Body,
TiWen,
Mode,
POINT,
HIGH,
LOW,
}ICON;
//COM口定义
#define COM1 LCD_RAM_REGISTER0
#define COM2 LCD_RAM_REGISTER2
#define COM3 LCD_RAM_REGISTER4
#define COM4 LCD_RAM_REGISTER6
//段定义
#define SEG_Temp_C 7
#define SEG_Temp_F 7
#define SEG_Buzzer 8
#define SEG_Body 24
#define SEG_TiWen 7
#define SEG_Battery1 8
#define SEG_Battery2 8
#define SEG_Battery3 8
#define SEG_Mode 7
#define SEG_B 9
#define SEG_S 9
#define SEG_S_COM1 25
#define SEG_G 24
#define SEG_G_COM1 15
#define SEG_P 14
#define SEG_P_COM1 12
#define SEG_Point 14
//COM口定义
#define COM_Temp_C COM2
#define COM_Temp_F COM3
#define COM_Buzzer COM1
#define COM_Body COM1
#define COM_TiWen COM1
#define COM_Battery1 COM2
#define COM_Battery2 COM4
#define COM_Battery3 COM3
#define COM_Mode COM4
#define COM_Point COM1
//掩码定义
#define Mask_Temp_C 0xFFFFFF7F//第7位为掩码(只对第7位操作)
#define Mask_Temp_F 0xFFFFFF7F//第7位为掩码(只对第7位操作)
#define Mask_Buzzer 0xFFFFFEFF//第8位为掩码(只对第8位操作)
#define Mask_Body 0xFEFFFFFF//第24位为掩码(只对第24位操作)
#define Mask_TiWen 0xFFFFFF7F//第7位为掩码(只对第7位操作)
#define Mask_Battery1 0xFFFFFEFF//第8位为掩码(只对第8位操作)
#define Mask_Battery2 0xFFFFFEFF//第8位为掩码(只对第8位操作)
#define Mask_Battery3 0xFFFFFEFF//第8位为掩码(只对第8位操作)
#define Mask_Mode 0xFFFFFF7F//第7位为掩码(只对第7位操作)
#define Mask_B 0xFFFFFDFF//第9位为掩码(只对第9位操作)
#define Mask_S 0xFDFFFDFF//第25、9位为掩码(只对第25、9位操作)
#define Mask_S_COM1 0xFDFFFFFF//第25位为掩码(只对第25位操作)
#define Mask_G 0xFEFF7FFF//第15、24位为掩码(只对第25、24位操作)
#define Mask_G_COM1 0xFFFF7FFF//第15位为掩码(只对第15位操作)
#define Mask_P 0xFFFFAFFF//第14、12位为掩码(只对第14、12位操作)
#define Mask_P_COM1 0xFFFFEFFF//第12位为掩码(只对第12位操作)
#define Mask_Point 0xFFFFBFFF//第14位为掩码(只对第14位操作)