目录

  • 华大单片机LCD简介
  • LCD 主要特性
  • LCD 框图
  • LCD 驱动波形
  • LCD Bias 产生电路
    • 内部电阻模式
    • 外部电容模式
    • 外部电阻模式
    • LCD三种驱动方式对比
  • LCD显示模式
    • LCD 显示模式 0 (MODE = 0)
    • LCD 显示模式 1 (MODE = 1)
  • LCD驱动讲解
    • LCD屏真值表
    • 开发板接口电路
    • LCD屏参数
    • 建立LCD映射表
    • 写在结尾

华大单片机LCD简介

华大单片机LCD 控制器是一款适用于单色无源液晶显示器(LCD)的数字控制器/驱动器,以HC32L136K8TA为例,最多具有8 个公用端子(COM)和 40 个区段端子(SEG),用以驱动 160 (4x40)或 288 (8x36)个 LCD 图像元素。其它型号端子的确切数量取决于数据手册中所述的器件引脚。


LCD 主要特性

  • 高度灵活的帧速率控制。
  • 支持静态、1/2、1/3、1/4、1/6 和 1/8 占空比。
  • 支持 1/2、1/3 偏置。
  • 多达 16 个寄存器的 LCD 数据 RAM。
  • 可通过软件配置 LCD 的对比度。
  • 3 种驱动波形生成方式
    – 内部电阻分压、外部电阻分压,外部电容分压方式
    – 可通过软件配置内部电阻分压方式的功耗,从而匹配 LCD 面板所需的电容电荷
  • 支持低功耗模式:LCD 控制器可在 Active、Sleep、DeepSleep 模式下进行显示。
  • 可配置帧中断。
  • 支持 LCD 闪烁功能且可配置多种闪烁频率
  • 未使用的 LCD 区段和公共引脚可配置为数字或模拟功能。

LCD 框图


LCD 驱动波形

LCD 支持 5 种占空比(Duty)的驱动波形:静态、1/2、1/3、1/4、1/6 和 1/8,由LCD_CR0.Duty 进行设置。LCD 支持 2 种偏置(Bias)的驱动波形:1/2、1/3,由LCD_CR0.Bias 进行设置。建议的组合方式如下表所示:


LCD Bias 产生电路

LCD 的 Bias 电压具有 3 种来源:内部电阻分压、外部电阻分压、外部电容分压。当选择内部电阻分压时,芯片会自动切换内部的电路以产生符合 Bias 和 Duty 的电压。当选择外部电阻分压或外部电容分压时,需要用户在芯片的外围引脚搭建相关电路。

内部电阻模式

内部电阻模式 VLCDH,VLCD1~VLCD3 可以作为 LCD SEG 输出或者 IO 端口使用。内部电阻模式,LCD 的驱动电压由 CR0.Contrast 控制,如下表所示:

由于内部电阻驱动方式,无需外部电路支持。当选择内部电阻分压时,芯片会自动切换到内部的电路,这种模式驱动能力较弱。
当选择1/2bias时,大功耗/中功耗/小功耗的电阻分别为 240K/360K/720K;
当选择1/3bias时,大功耗/中功耗/小功耗的电阻分别为 360K/540K/1080K。
通过内部LCD_CR0中的Contrast调整电压使得VLCD电压 = LCD屏电压。

外部电容模式

外部电阻模式


注意:
– Rx 为可调电阻,用于调节 LCD 显示对比度。
– 根据使用 LCD 屏幕选择合适的电阻 R。

LCD三种驱动方式对比

内部电阻方式 外部电阻方式 外部电容方式
功耗(仅LCD驱动)
不包括LCD屏
Type 3.3uA 根据外部电阻决定 0.5uA
驱动电路 无需外接 见外部电阻模式图 见外部电容模式图
IO管脚 COM+SEG COM+SEG
+4个VLCD1~4
COM+SEG
+4个VLCD1~4
驱动效果 一般 较好
LCD电压 可以根据内部寄存器调整 依据外部电阻Rx来调整 无法调整,VLCD电压等于VDD电压

LCD显示模式

华大单片机根据把SEG或COM放在寄存器的方式不同分为显示模式0(MODE = 0)和显示模式1(MODE =1)。下面都以1/4Duty为例列出两种显示模式。

LCD 显示模式 0 (MODE = 0)

LCD 显示模式 1 (MODE = 1)


LCD驱动讲解

下面以芯缘意码HC32LFx3x-STK-V2.0开发板为例,讲解如何使用华大MCU HC32L136K8TA来驱动显示LCD段码屏。

LCD屏真值表

开发板接口电路


管脚配置代码

/********************************************************************************** \brief  初始化外部GPIO引脚**** \return 无******************************************************************************/
void App_PortCfg(void)
{Gpio_SetAnalogMode(GpioPortA, GpioPin9);  //COM0Gpio_SetAnalogMode(GpioPortA, GpioPin10); //COM1Gpio_SetAnalogMode(GpioPortA, GpioPin11); //COM2Gpio_SetAnalogMode(GpioPortA, GpioPin12); //COM3   Gpio_SetAnalogMode(GpioPortA, GpioPin8);  //SEG0Gpio_SetAnalogMode(GpioPortC, GpioPin9);  //SEG1Gpio_SetAnalogMode(GpioPortC, GpioPin8);  //SEG2Gpio_SetAnalogMode(GpioPortC, GpioPin7);  //SEG3Gpio_SetAnalogMode(GpioPortC, GpioPin6);  //SEG4Gpio_SetAnalogMode(GpioPortB, GpioPin15); //SEG5Gpio_SetAnalogMode(GpioPortB, GpioPin14); //SEG6Gpio_SetAnalogMode(GpioPortB, GpioPin13); //SEG7
}

LCD屏参数


LCD参数配置

/********************************************************************************** \brief  配置LCD**** \return 无******************************************************************************/
void App_LcdCfg(void)
{stc_lcd_cfg_t LcdInitStruct;stc_lcd_segcom_t LcdSegCom;LcdSegCom.u32Seg0_31 = 0xffffff00;                              ///< 配置LCD_POEN0寄存器 开启SEG0~SEG7LcdSegCom.stc_seg32_51_com0_8_t.seg32_51_com0_8 = 0xffffffff;   ///< 初始化LCD_POEN1寄存器 全部关闭输出端口LcdSegCom.stc_seg32_51_com0_8_t.segcom_bit.Com0_3 = 0;          ///< 使能COM0~COM3LcdSegCom.stc_seg32_51_com0_8_t.segcom_bit.Mux = 1;             ///< Mux=0,Seg32_35=0,BSEL=1表示:选择外部电容工作模式,内部电阻断路LcdSegCom.stc_seg32_51_com0_8_t.segcom_bit.Seg32_35 = 0xf;Lcd_SetSegCom(&LcdSegCom);                                      ///< LCD COMSEG端口配置LcdInitStruct.LcdBiasSrc = LcdExtCap;                           ///< 电容分压模式,需要外部电路配合LcdInitStruct.LcdDuty = LcdDuty4;                               ///< 1/4dutyLcdInitStruct.LcdBias = LcdBias3;                               ///< 1/3 BIASLcdInitStruct.LcdCpClk = LcdClk2k;                              ///< 电压泵时钟频率选择2kHzLcdInitStruct.LcdScanClk = LcdClk128hz;                         ///< LCD扫描频率选择128HzLcdInitStruct.LcdMode = LcdMode0;                               ///< 选择模式0LcdInitStruct.LcdClkSrc = LcdRCL;                               ///< LCD时钟选择RCLLcdInitStruct.LcdEn   = LcdEnable;                              ///< 使能LCD模块Lcd_Init(&LcdInitStruct);
}

建立LCD映射表

  1. 我们可以根据屏的真值表来完成笔段定义,把表中的PIN5和PIN6定义为一个字节,PIN5为低位。其它PIN定义方法相同。宏定义代码如下:
#define LCDSEG_A 0x01
#define LCDSEG_B 0x10
#define LCDSEG_C 0x40
#define LCDSEG_D 0x80
#define LCDSEG_E 0x04
#define LCDSEG_F 0x02
#define LCDSEG_G 0x20
#define LCDPOINT1P 0x08
#define LCDPOINT2P 0x08
#define LCDPOINT3P 0x08
#define LCDPOINT4P 0x08
  1. 根据笔段定义完成显示数值的定义。如数字0为笔段LCDSEG_A+LCDSEG_B+LCDSEG_C+LCDSEG_D+LCDSEG_E+LCDSEG_F,其它的数值或字母使用同样的方法都可以定义。现在做0~F的定义如下:
#define CHAR_0   LCDSEG_A+LCDSEG_B+LCDSEG_C+LCDSEG_D+LCDSEG_E+LCDSEG_F
#define CHAR_1   LCDSEG_B+LCDSEG_C
#define CHAR_2   LCDSEG_A+LCDSEG_B+LCDSEG_D+LCDSEG_E+LCDSEG_G
#define CHAR_3   LCDSEG_A+LCDSEG_B+LCDSEG_C+LCDSEG_D+LCDSEG_G
#define CHAR_4   LCDSEG_B+LCDSEG_C+LCDSEG_F+LCDSEG_G
#define CHAR_5   LCDSEG_A+LCDSEG_C+LCDSEG_D+LCDSEG_F+LCDSEG_G
#define CHAR_6   LCDSEG_A+LCDSEG_C+LCDSEG_D+LCDSEG_E+LCDSEG_F+LCDSEG_G
#define CHAR_7   LCDSEG_A+LCDSEG_B+LCDSEG_C
#define CHAR_8   LCDSEG_A+LCDSEG_B+LCDSEG_C+LCDSEG_D+LCDSEG_E+LCDSEG_F+LCDSEG_G
#define CHAR_9   LCDSEG_A+LCDSEG_B+LCDSEG_C+LCDSEG_D+LCDSEG_F+LCDSEG_G
#define CHAR_A   LCDSEG_A+LCDSEG_B+LCDSEG_C+LCDSEG_E+LCDSEG_F+LCDSEG_G
#define CHAR_b   LCDSEG_C+LCDSEG_D+LCDSEG_E+LCDSEG_F+LCDSEG_G
#define CHAR_C   LCDSEG_A+LCDSEG_D+LCDSEG_E+LCDSEG_F
#define CHAR_d   LCDSEG_B+LCDSEG_C+LCDSEG_D+LCDSEG_E+LCDSEG_G
#define CHAR_E   LCDSEG_A+LCDSEG_D+LCDSEG_E+LCDSEG_F+LCDSEG_G
#define CHAR_F   LCDSEG_A+LCDSEG_E+LCDSEG_F+LCDSEG_G
  1. 建立MCU LCD模块映射表。

    通过上面的图我们可以知道,我们选择LCD 显示模式 0 (MODE = 0)时,要在LCD屏1的位置显示数字0,需要把装有PIN5和PIN6组成的一个字节数据按高4位和低4位拆成两个字节,分别装入MCU的LCDRAM中才可以显示 ,其它位置的显示道理相同,因此我们可以做出如下的映射数组
const uint16_t u16DisTable[] = {((CHAR_0 & 0xf0) <<4 | (CHAR_0 & 0x0f)),  //0 ((CHAR_1 & 0xf0) <<4 | (CHAR_1 & 0x0f)),  //1 ((CHAR_2 & 0xf0) <<4 | (CHAR_2 & 0x0f)),  //2((CHAR_3 & 0xf0) <<4 | (CHAR_3 & 0x0f)),  //3 ((CHAR_4 & 0xf0) <<4 | (CHAR_4 & 0x0f)),  //4 ((CHAR_5 & 0xf0) <<4 | (CHAR_5 & 0x0f)),  //5 ((CHAR_6 & 0xf0) <<4 | (CHAR_6 & 0x0f)),  //6 ((CHAR_7 & 0xf0) <<4 | (CHAR_7 & 0x0f)),  //7 ((CHAR_8 & 0xf0) <<4 | (CHAR_8 & 0x0f)),  //8 ((CHAR_9 & 0xf0) <<4 | (CHAR_9 & 0x0f)),  //9 ((CHAR_A & 0xf0) <<4 | (CHAR_A & 0x0f)),  //A ((CHAR_b & 0xf0) <<4 | (CHAR_b & 0x0f)),  //b ((CHAR_C & 0xf0) <<4 | (CHAR_C & 0x0f)),  //C ((CHAR_d & 0xf0) <<4 | (CHAR_d & 0x0f)),  //d ((CHAR_E & 0xf0) <<4 | (CHAR_E & 0x0f)),  //E ((CHAR_F & 0xf0) <<4 | (CHAR_F & 0x0f)),  //F };
  1. 定义数据类型。由于每个LCDRAM都是32位的的寄存器,里面装的是LCD中两个位置的数据 ,要是直接改变其中的显示数据不是很方便,我们使用共用体来定义成我们方便操作的数据类型,定义如下:
 /******************************************************************************** \brief LCDRAM*****************************************************************************/
typedef union{uint8_t  u8_dis[4];uint16_t u16_dis[2];uint32_t u32_dis;
}un_Ram_Data;

我们之前做的只是数字和字母的映射,特殊点我们并没有映射,现在我们可以做下特殊点的定义如下

 /******************************************************************************** \brief LCD特殊点*****************************************************************************/
typedef union{uint32_t LcdSegTotle;struct{uint8_t LcdSeg_1P:1;uint8_t LcdSeg_2P:1;uint8_t LcdSeg_3P:1;uint8_t LcdSeg_4P:1;}stc_Lcd_SP;
}un_Lcd_SP;
  1. LCD显示。上面的工作都做完后只要写个简单的LCD显示函数就可以完成LCD的显示工作了。显示代码如下:
void App_LcdDis(uint8_t *u8LcdDisData , un_Lcd_SP *punLcdSp)
{un_Ram_Data unRamData[2];un_Lcd_SP unLcdSP;unLcdSP = *punLcdSp;unRamData[0].u16_dis[0] = u16DisTable[*u8LcdDisData++];         //取LCD屏第一个位置显示内容unRamData[0].u16_dis[1] = u16DisTable[*u8LcdDisData++];         //取LCD屏第二个位置显示内容unRamData[1].u16_dis[0] = u16DisTable[*u8LcdDisData++];         //取LCD屏第三个位置显示内容unRamData[1].u16_dis[1] = u16DisTable[*u8LcdDisData];           //取LCD屏第四个位置显示内容if ( unLcdSP.LcdSegTotle )                                      //检查是否要显示特殊点{if(unLcdSP.stc_Lcd_SP.LcdSeg_1P){unRamData[0].u8_dis[0] |= LCDPOINT1P ;                  //显示第一个位置的特殊点}if(unLcdSP.stc_Lcd_SP.LcdSeg_2P){unRamData[0].u8_dis[2] |= LCDPOINT2P ;                  //显示第二个位置的特殊点}if(unLcdSP.stc_Lcd_SP.LcdSeg_3P){unRamData[1].u8_dis[0] |= LCDPOINT3P ;                  //显示第三个位置的特殊点}if(unLcdSP.stc_Lcd_SP.LcdSeg_4P){unRamData[1].u8_dis[2] |= LCDPOINT4P ;                  //显示第四个位置的特殊点}}   Lcd_WriteRam(0,unRamData[0].u32_dis);  ///< 赋值寄存器LCDRAM0   调用官方的库Lcd_WriteRam(1,unRamData[1].u32_dis);  ///< 赋值寄存器LCDRAM1
}
  1. 主程序如下:
int32_t main(void)
{uint8_t   u8LcdData[4] = {0x00};un_Lcd_SP unLcdSP;Sysctrl_ClkSourceEnable(SysctrlClkRCL,TRUE);            ///< 使能RCL时钟Sysctrl_SetRCLTrim(SysctrlRclFreq32768);                ///< 配置内部低速时钟频率为32.768kHzSysctrl_SetPeripheralGate(SysctrlPeripheralLcd,TRUE);   ///< 开启LCD时钟Sysctrl_SetPeripheralGate(SysctrlPeripheralGpio,TRUE);  ///< 开启GPIO时钟DDL_ZERO_STRUCT(unLcdSP);App_PortCfg();                                           ///< LCD端口配置App_LcdCfg();                                            ///< LCD模块配置Lcd_ClearDisp();                                         ///< 清屏     调用官方库清屏u8LcdData[0] = 9;                                        //显示 9527           u8LcdData[1] = 5;u8LcdData[2] = 2;u8LcdData[3] = 7;unLcdSP.stc_Lcd_SP.LcdSeg_1P = 0;unLcdSP.stc_Lcd_SP.LcdSeg_2P = 0;unLcdSP.stc_Lcd_SP.LcdSeg_3P = 0;unLcdSP.stc_Lcd_SP.LcdSeg_4P = 0;    App_LcdDis(u8LcdData , &unLcdSP);while(1);
}

程序运行结果如下图

写在结尾

就我们自己来说,使用最多的屏就是1/4duty和1/3bias的LCD屏,自己在做产品的时候不同的产品使用的屏真值表会不同,我们用几分钟更改下笔段的宏定义,LCD屏直接显示成功。当然,现在我们自己家的产品在做笔段宏定义时按屏的类型做条件编译来定义,使用屏的时候只要做下屏的类型宏定义就可以直接使用,这样更方便。


关注微信公众号『芯缘意码』,查看更多内容,回复“加群”加入技术交流群。
淘宝 店铺 搜索 『芯缘意码』,购买开发学习板仿真器。


华大单片机HC32L136笔段式段码LCD显示相关推荐

  1. 【解决方案】STM32L152单片机驱动段码LCD屏,执行HAL_LCD_Init函数失败返回HAL_TIMEOUT,长时间卡在LCD_FLAG_RDY的while循环里面的解决办法

    STM32L152单片机驱动段码LCD屏,HAL_LCD_Init函数执行失败,卡在LCD_FLAG_RDY里面,函数返回HAL_TIMEOUT /*!< Wait Until the LCD ...

  2. 怎么点亮段码屏_段码LCD液晶屏驱动方法

    TFT 液晶屏: http://www.hzjingxian.com 段码 LCD 液晶屏驱动方法 段码 LCD 液晶屏驱动方法 首先,不要以为用单片机来驱动就以为段码屏是直流驱动的,其实,段码屏是交 ...

  3. 段码LCD屏幕的驱动方法

    大家平常在生活之中见到最多的可能就是段码液晶屏了,它有着普通数码管的特征,又有着点阵液晶屏的特征,已经固定的图形,既省成本而且又好看,那么,我们今天来一起试一试! 首先,大家都不要以为使用单片机来驱动 ...

  4. 华大单片机HC32L136定时器时间如何计算

    目录 介绍 定时器的时钟 模式 0 计数定时器功能 与定时器0模式0有关的寄存器及相应位 定时器时间计算 配置流程 定时器0配置初始化代码 定时器0中断服务函数 主程序中调用调用定时器0并运行 简便计 ...

  5. 国产超低功耗华大单片机HC32L136开发板上手入门

    今天介绍下国产超低功耗华大单片机HC32L136开发板上手后的入门操作(开发板可以在华大MCU应用交流群:164973950 免费申请).HC32L136开发板(如下图所示)分为板载调试模块(左半部分 ...

  6. 基于单片机病房呼叫系统数码管显示房号设计-基于单片机工业生产现场的光照强度控制设计-基于单片机多功能智能台灯设计-基于单片机二维码LCD显示设计-基于单片机多功能时钟闹钟万年历控制系统设计【毕设分享】

    1641基于单片机病房呼叫系统数码管显示房号设计 设计思路:此设计实现的功能通过按键模拟房号,当按键按下时会将房号编号发送到数目管上进行显示,并通过声光进行提示.包含的电路有:数码管显示电路.按键电路 ...

  7. 段码LCD液晶屏如何斑马条改PIN脚?

    至于段码LCD液晶屏的常用的连接方式我们都是知道的,一般客户也都是根据自身的产品需求在开模打样的时候就已经确定好了本产品的连接方式了. 而有些客户在针对样品验证的快速简便和批量产品的成本管控的不同需求 ...

  8. LCD高抗干扰液晶段码屏显示驱动芯片:VK2C21A/B/BA/C/D 大量应用于音箱/音响面板LCD显示驱动

    产品品牌:VINKA/永嘉微/永嘉微电 产品型号:VK2C21A/B/C/D/VK2C21BA 封装形式:SOP28/24/20.NSOP16.SSOP24(新封装) 概述: VK2C21是一个点阵式 ...

  9. 怎么点亮段码屏_段码LCD液晶屏参考程序

    段码液晶参考程序 ;程序清单 ;********************************************************************************* ;文 ...

最新文章

  1. Global.asax详解
  2. refineFace 笔记
  3. mysql 视图列信息_MySQL 中获取用户表、用户视图、用户表中列信息
  4. 跟我一起写 Makefile(十三)
  5. 中南继续教育学院计算机绘图,求答案~~机电一体化,计算机绘图
  6. java枚举的例子_Java枚举例子
  7. 【搜索引擎基础知识1】搜索引擎基本架构
  8. MAC 修改文件夹以及子文件夹和子文件权限 以及 修改文件夹owner
  9. Spring Cloud Sleuth+Zipkin 构建微服务链路跟踪系统
  10. SUSHI区块奖励将根据此前提案在3月降至每区块40枚
  11. 《31天重构》4:下置方法
  12. js中style.display=无效的解决方法
  13. 自定义ImageView实现圆形图片
  14. Windows 系统优化大全(完整)
  15. 马氏距离进行离群值检测
  16. Text-CNN 文本分类
  17. mixin 和 mixins 区别 ?
  18. SVD计算旋转,平移矩阵
  19. 从营销的角度看宜家成功的秘诀
  20. 中枢模式发生器(CPG)

热门文章

  1. VB socket编程入门
  2. EXCEL去重统计(条件去重复计数)
  3. 佳能ix4000ix5000打印机清零
  4. Code Composer Studio(CCS)新建project
  5. Verilog——补码转换
  6. 笔记本电池9针脚图解_上柴Econtrols天然气发动机控制系统原理图解
  7. 最新,2022中科院分区发生修改,新增1区期刊数十本(附修改版目录)
  8. 商城项目-商品规格参数管理
  9. PHP实现基于文本的莫斯电码生成器
  10. 油品调和计算软件_油品调和计算