首页 > 评测 > 使用MM32L0130 SLCD驱动LCD显示
使用MM32L0130 SLCD驱动LCD显示
- [导读]
- 本帖最后由 MM灵灵灵 于 2022-10-26 09:20 编辑 使用MM32L0130 SLCD驱动LCD显示 灵动股份推出的MM32L0130系列MCU具有片上SLCD液晶显示控制器,SLCD 驱动器是用于单色无源液晶显示器(SLCD)的数字驱动器,具
本帖最后由 MM灵灵灵 于 2022-10-26 09:20 编辑
灵动股份推出的MM32L0130系列MCU具有片上SLCD液晶显示控制器,SLCD 驱动器是用于单色无源液晶显示器(SLCD)的数字驱动器,具有多达 8 个公共端和多达 63 个分段端, SLCD 引脚最多为 64 个,因此最多可驱动 240(60x4)或 448(56x8)个段码。驱动段码的最终数量由产品规格书中设备引脚的数目决定。
一. SLCD介绍
1.1 SLCD功能框图
SLCD 驱动模块包括以下几个基本的子模块,如下图所示。
- 显示数据寄存器
- SLCD 输出驱动引脚
- 时钟产生单元,包括时钟预分频器、帧时钟分频器、电荷泵时钟分频器和闪烁时钟分频器
- 闪烁控制器
- 内置升压电荷泵和偏置电压生成单元
- 时序控制和波形发生器
- 示帧率灵活控制
- 兼容 APB 接口
- 支持静态、 1/2、 1/3、 1/4、 1/6 和 1/8 占空比
- 支持 1/2、 1/3 和 1/4 偏置电压设置
- 为了存储显示数据,内置了 16*32bit 显示数据寄存器
- 通过软件来调整 SLCD 输出电压,来调节对比度
- 外围电路简单,不需要模拟器件支持
- 两种调整显示对比度的方法
- 支持以下低功耗模式:低功耗运行模式,睡眠模式,低功耗睡眠模式,停止模式,深度停止模式,待机模式;在不需要显示的时候,可以完全关闭 SLCD 驱动以达到降低功耗的目的
- 支持相位反转模式,降低功耗和 EMI
- 每一帧显示开始的时候,通过中断信号与软件同步,更新显示数据
- 闪烁功能
2)在静态、 1/2、 1/3、 1/4 占空比模式下可以闪烁显示任意段码
3)软件选择闪烁频率,支持闪烁频率 0.5Hz, 1Hz, 2Hz 或 4Hz
- 灵活的引脚复用功能,可以配置任意 LCD 驱动引脚成为 COM 或者 SEG 功能;SLCD 的驱动引脚在没有被配置成 SLCD 功能的时候,可以作为 GPIO 引脚来使用
- SLCD 驱动电平(VLCDrail1, VLCDrail2, VLCDrail3, VLCDrail4)的去耦合功能
- 支持低功耗驱动波形
- 支持 DMA 传输
- 支持中断
时钟产生模块为波形发生模块和电荷泵模块提供各自所需的时钟,其结构如下:
三. 实验
3.1 硬件设计
本次实验使用MM32L0130片上SLCD驱动LCD液晶屏显示。硬件使用灵动股份设计的EVB-L0136开发板,板载LCD接口可以适配GDC0689液晶屏,GDC0689具有半透和反射两种模式,6位8字、6点视角、宽温,适用于工业设备等产品。GDC0689液晶屏全显效果图如下:
EVB-L0136开发板LCD模块原理图如下:
3.2 程序设计
例程主要用到GDC0689液晶屏的数码管部分进行计数显示,以最右边的数码管作为小数部分,其余数码管作为整数部分,从最低位开始累加计数,满十就向前一位进1。
灵动股份设计了MM32F0130 SLCD相关的库函数以及API函数,容易理解和使用,代码较多,这里不再进行赘述,仅对部分主要程序进行分析。
3.21 SLCD测试函数
void slcd_test(void)
{
slcd_init();
while(1) {
LCD_DisplayDataUpdate();
DELAY_Ms(100);
}
}
3.22 SLCD初始化函数
void slcd_init()函数主要代码:
使能PWR、BKP时钟
RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWR, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1ENR_BKP, ENABLE);
使能SLCD时钟,软件复位SLCD
RCC_SLCD_ClockCmd(SLCD, ENABLE);
SLCD_DeInit();
SLCD的时钟源选择LSI,配置LSI时钟频率为40KHZ。
RCC_LSICLKConfig(RCC_LSICLKSource_40KHz);
RCC_LSICmd(ENABLE);
RCC_SLCDCLKConfig(RCC_SLCDCLKSource_LSI);
LSI作为SLCD时钟源,对应时钟预分频系数为4,分频系数为16
else if(slcd_clk_source_freq <= LSI_VALUE) {
pre_value = SLCD_Prescaler_4;
div_value = SLCD_Divider_16;
}
初始化SLCD结构体,配置1/4偏置、1/3占空比,VDD作为SLCD电源使能
slcd_struct.SLCD_Divider = div_value;
slcd_struct.SLCD_Duty = SLCD_Duty_1_4;
slcd_struct.SLCD_Bias = SLCD_Bias_1_3;
slcd_struct.SLCD_VoltageSource = SLCD_VoltSrcCapCharggDownVdd;
SLCD_Init(&slcd_struct);
SLCD pin对应的GPIO配置为SEG或COM,并使能
SLCD_IO_Config(&(SEGorCOM[0]));
//must call after SLCD_init
配合SLCD COM索引寄存器
SLCD_COM_IndexInit(&(SCLD_COM_Index[0]));
配置电荷泵时钟分频为1024
SLCD_ChargePumpClockDivConfig(SLCD_ChargePumpClock_Div1024);
正常驱动波形
SLCD_LowPowerDriveCmd(DISABLE);
配置无死区插入,当在两帧之间插入死区时,SEG和COM信号电压为零
SLCD_DeadTimeConfig(SLCD_DeadTime_0);
清除显示数据寄存器
LCD_Clear();
关闭SLCD闪烁模式,闪烁时钟分频系数为512
SLCD_BlinkConfig(SLCD_BlinkMode_Off, SLCD_BlinkFrequency_Div512);
配置SLCD闪烁索引
SLCD_BLINK_IndexInit(SCLD_BLINK_Index);
3.23 LCD更新显示数据函数
LCD_DisplayDataUpdate()函数主要代码:
if(Number1 < 10) {
LCD_DisplayNumber1(0, ' ', 0);
LCD_DisplayNumber1(1, ' ', 0);
LCD_DisplayNumber1(2, ' ', 0);
LCD_DisplayNumber1(3, ' ', 0);
LCD_DisplayNumber1(4, '0', 1);
LCD_DisplayNumber1(5, '0' + Number1, 0);
}
else if(Number1 < 100) {
LCD_DisplayNumber1(0, ' ', 0);
LCD_DisplayNumber1(1, ' ', 0);
LCD_DisplayNumber1(2, ' ', 0);
LCD_DisplayNumber1(3, ' ', 0);
LCD_DisplayNumber1(4, '0' + ((Number1 / 10) % 10), 1);
LCD_DisplayNumber1(5, '0' + ((Number1 / 1 ) % 10), 0);
}
......(省略余下代码)
- Index表示选中的数码管索引,对应6个数码管,可选值为0,1,2,3,4,5
- ch表示要显示的数字,为char类型
- Point表示该数码管是否显示Dp字段,显示则为1,否则为0
举例:代码中LCD_DisplayNumber1(5, '0' + Number1, 0)表示选中第5个数码管(最右),显示内容是Number的值,不显示Dp字段。
3.24 LCD显示函数
LCD_DisplayNumber1()函数主要代码:
{
u8 i;
char TAB[6][8][4] = { // (1)
{"5A ", "5B ", "5C ", "5D ", "5E ", "5F ", "5G ", "DP5"},
{"6A ", "6B ", "6C ", "6D ", "6E ", "6F ", "6G ", "DP6"},
{"7A ", "7B ", "7C ", "7D ", "7E ", "7F ", "7G ", "DP7"},
{"8A ", "8B ", "8C ", "8D ", "8E ", "8F ", "8G ", "DP8"},
{"9A ", "9B ", "9C ", "9D ", "9E ", "9F ", "9G ", "DP9"},
{"10A", "10B", "10C", "10D", "10E", "10F", "10G", " "},
};
u8 COMn = 0xFF, SEGn = 0xFF;
u8 Code = LCD_SearchCode(ch); // (2)
if(Code != 0xFF) {
for(i = 0; i < 7; i++) {
LCD_SearchName(TAB[Index], &COMn, &SEGn); // (3)
if((COMn != 0xFF) && (SEGn != 0xFF)) {
LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], (Code >> i) & 0x01); // (4)
}
}
LCD_SearchName(TAB[Index][7], &COMn, &SEGn); // (5)
if((COMn != 0xFF) && (SEGn != 0xFF)) {
LCD_WriteBit(COMn, LCD_SEG_Table[SEGn][0], LCD_SEG_Table[SEGn][1], Point); // (6)
}
}
}
- 定义三维字符数组TAB[6][8][4],其中[6]对应6位“8”字,[8]对应“8”字的8段(含DP段),[4]表示元素的长度,对应各段的名称。
- 形参ch表示要显示的数字,为char类型,LCD_SearchCode(char ch)函数用来遍历LCD_CODE_Table[38],如果传入的参数ch和LCD_CODE_Table.ch相等,则返回LCD_CODE_Table.Data,即该数字对应的段选信号。
- LCD_SearchName(TAB[Index], &COMn, &SEGn)函数遍历所有COM口(4)和SEG口(22),如果TAB[Index]和LCD_NAME_Table[j]相等,则获取COMn和SEGn的值,然后返回。
- 获取COMn对应的显示数据寄存器索引,根据段选信号,给显示数据寄存器赋值。
- 获取Dp段对应的COMn和SEGn的值,然后返回。
- 获取COMn对应的显示数据寄存器索引,根据Dp段选信号,给显示数据寄存器赋值。
- 本文系21ic原创,未经许可禁止转载!
网友评论
- 联系人:巧克力娃娃
- 邮箱:board@21ic.com
- 我要投稿
-
欢迎入驻,开放投稿
-
人均百万?英伟达中国员工收入曝光! 2024-08-29
-
《黑神话:悟空》玩家硬盘升级攻略:提升游戏体验,畅享3A大作 2024-08-29
-
数睿数据参加《系统与软件工程 低代码开发平台通用技术要求》国家标准编制 2024-08-29
- NRF52810蓝牙数字耳机找人定制
预算:¥30005天前
- 125KW模块式PCS软硬件外包开发
预算:¥1100000015小时前
- 12V汽车启动电源项目BMS设计
预算:¥50000023小时前
- 数据可视化软件 开发
预算:¥5000023小时前
- PLC项目调试修改
预算:¥100001天前
- 起动电机控制器开发
预算:¥1100001天前