1
完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
|
|
相关推荐
1个回答
|
|
华大单片机LCD简介
华大单片机LCD 控制器是一款适用于单色无源液晶显示器(LCD)的数字控制器/驱动器,以HC32L136K8TA为例,最多具有8 个公用端子(COM)和 40 个区段端子(SEG),用以驱动 160 (4x40)或 288 (8x36)个 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三种驱动方式对比 [tr]内部电阻方式外部电阻方式外部电容方式[/tr]
华大单片机根据把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); //COM0 Gpio_SetAnalogMode(GpioPortA, GpioPin10); //COM1 Gpio_SetAnalogMode(GpioPortA, GpioPin11); //COM2 Gpio_SetAnalogMode(GpioPortA, GpioPin12); //COM3 Gpio_SetAnalogMode(GpioPortA, GpioPin8); //SEG0 Gpio_SetAnalogMode(GpioPortC, GpioPin9); //SEG1 Gpio_SetAnalogMode(GpioPortC, GpioPin8); //SEG2 Gpio_SetAnalogMode(GpioPortC, GpioPin7); //SEG3 Gpio_SetAnalogMode(GpioPortC, GpioPin6); //SEG4 Gpio_SetAnalogMode(GpioPortB, GpioPin15); //SEG5 Gpio_SetAnalogMode(GpioPortB, GpioPin14); //SEG6 Gpio_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~SEG7 LcdSegCom.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~COM3 LcdSegCom.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/4duty LcdInitStruct.LcdBias = LcdBias3; ///< 1/3 BIAS LcdInitStruct.LcdCpClk = LcdClk2k; ///< 电压泵时钟频率选择2kHz LcdInitStruct.LcdScanClk = LcdClk128hz; ///< LCD扫描频率选择128Hz LcdInitStruct.LcdMode = LcdMode0; ///< 选择模式0 LcdInitStruct.LcdClkSrc = LcdRCL; ///< LCD时钟选择RCL LcdInitStruct.LcdEn = LcdEnable; ///< 使能LCD模块 Lcd_Init(&LcdInitStruct); } 建立LCD映射表
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 }; 定义数据类型。由于每个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; 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 } 主程序如下: int32_t main(void) { uint8_t u8LcdData[4] = {0x00}; un_Lcd_SP unLcdSP; Sysctrl_ClkSourceEnable(SysctrlClkRCL,TRUE); ///< 使能RCL时钟 Sysctrl_SetRCLTrim(SysctrlRclFreq32768); ///< 配置内部低速时钟频率为32.768kHz Sysctrl_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屏直接显示成功。当然,现在我们自己家的产品在做笔段宏定义时按屏的类型做条件编译来定义,使用屏的时候只要做下屏的类型宏定义就可以直接使用,这样更方便。 |
|||
|
|||
只有小组成员才能发言,加入小组>>
2549 浏览 0 评论
1152浏览 2评论
750浏览 1评论
503浏览 0评论
269浏览 0评论
433浏览 0评论
小黑屋| 手机版| Archiver| 德赢Vwin官网 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-23 03:16 , Processed in 1.504263 second(s), Total 69, Slave 61 queries .
Powered by 德赢Vwin官网 网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
德赢Vwin官网 观察
版权所有 © 湖南华秋数字科技有限公司
德赢Vwin官网 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号