敏矽微电子Cortex-M0学习笔记06——段式LCD液晶实例

cathy的头像
cathy 发布于:周一, 12/05/2022 - 18:26 ,关键词:

相关文章:

敏矽微电子Cortex-M0学习笔记01——芯片简介

敏矽微电子Cortex-M0学习笔记02——Cortex-M0开发环境的建立及调试

敏矽微电子Cortex-M0学习笔记03——时钟系统设计例程

敏矽微电子Cortex-M0学习笔记04——GPIO详解及应用实例

敏矽微电子Cortex-M0学习笔记05——端口外部中断实例

1、LCD显示驱动概述

在上一章节GPIO中断的学习中,我们通过LCD液晶来显示中断的发生次数,很直观的知道了程序的运行情况,但这也只是LCD的一个小应用。在以后的学习和开发中,LCD作为显示单元,会愈发显示出它的重要性。那么接下来就开始介绍ME32F030的LCD驱动。学习前先对其做个简单的概述。

ME32F030的LCD 显示驱动通过自动地创建交流段和公共电压信号来直接驱动 LCD。它可以支持静态,1/2,1/3,1/4,1/5 和 1/6 占空比 的 LCD 面板。.最多可以支持 6 个公共电压端和 16 个段组合(共计 96)的 LCD 显示面板。

主要特征有:

• 多达 96 个点(6x16)

• 可配置公共电压信号(Common) 0-5

• 可配置段电压信号(Segment) 0-16

• 支持静态,1/2 偏压和 1/3 偏压电压

• 六种显示模式:静态,1/2 占空比,1/3 占空比,1/4 占空比,1/5 占空比或 1/6 占空比

• 可配置的帧频率

• 在数字模式下,支持 8 个 7 段 LED

其对应的复用管脚映射图如下:

1.png

图1 LCD寄存器0

2、LCD驱动寄存器

液晶显示的驱动还是比较饶的,因此肯定会有专门的LCD驱动寄存器,来辅助完成LCD液晶的驱动工作。ME32F030的LCD液晶驱动寄存器总览如图所示:

2.png

图2 LCD寄存器0

2-1 LCD控制寄存器0

查看LCD控制寄存器的列表,获知LCD驱动是支持 LCD 输出和 LED 输出两种工作模式的。因此要根据自己的实际情况使能相应的功能。这里需要注意的是,在 LED 模式下,LEDINV位决定着共阴极/共阳极显示,一定要根据实际电路进行选择。

3.png3-1.png

图3 LCD寄存器0

2-2 LCD控制寄存器1

在使能了相应的驱动工作方式后,就需要对控制模式以及输出参数进行设置。有LCD显示占空比选择、偏压选择、扫描周期频率需要配置。

4.png

图4 LCD控制寄存器1

2-3 数据映射寄存器

需要让LCD显示期望的数据时,只要向数据映射寄存器0~3写入相应的值即可。随后就会按预先设定自动输出到相应的 LCD 管脚上。

2-4 LCD驱动使能控制器0

该寄存器决定着LCD COM0~5的输出控制,相应的BIT位置1来使能对应的COM。

5.png

图5 LCD使能寄存器0

2-5 LCD驱动使能控制器1

该寄存器决定着LCD Segment0~16的输出控制,相应的BIT位置1来使能对应的 Segment。

6.png

图6 LCD使能寄存器1

3、LCD驱动函数

在例程LIB->common->Drivers->Source文件夹内有lcd.c文件,这个就是提供的LCD驱动文件,里面包含了一些基本的驱动函数,使用起来十分方便。下面会对每个函数进行讲解。

3-1 LCD初始化

在每段源代码的后面,笔者对其进行一下注释,方便大家快速掌握和使用这个函数。这个函数的4个参数的意义如下:

Mode:LCD的输出模式,可选LCD_MODE、LED_MODE。

Duty:显示占空比,可选DUTY_1 ~ DUTY_8.

Biasanod:LCD输出模式下代表偏置电压,可选LCD_BIAS_3(1/3偏压)、LCD_BIAS_2(1/2偏压)。LED输出模式下代表共正极/共负极选择。

Finhz:COM扫描周期频率,手册推荐80-100Hz。

    void LCD_Init (uint8_t mode,uint8_t duty, uint8_t biasanode, uint8_t finhz)
{
SYSCON->SYSAHBCLKCTRL_b.LCD_CLK=1;  //LCD时钟使能
SYSCON->PRESETCTRL_b.LCD_RST_N=0;   //LCD复位操作
SYSCON->PRESETCTRL_b.LCD_RST_N=1;
//disable output

LCD->LCDOUTEN0=0;  //LCD COM口初始化(禁止输出)
LCD->LCDOUTEN1=0;  //LCD SEG口初始化(禁止输出)
//set duty

LCD->LCDCTRL1_b.DUTY=duty;  //LCD 显示占空比
if ((finhz>0)&&(duty>0))
LCD->LCDCTRL1_b.FREQDIV=SystemCoreClock/(duty*finhz); //LCD COM扫描周期频率

if (mode==LCD_MODE)
{
SYSCON->PDRUNCFG_b.LCD_PD=0;     //LCD 电压发生器上电
LCD->LCDCTRL1_b.BIAS=biasanode;  //偏置电压选择
LCD->LCDCTRL0_b.LCDEN=1;         //选择为 LCD输出模式
LCD->LCDCTRL0_b.LEDEN=0;         
}
  else if (mode==LED_MODE)
{
SYSCON->PDRUNCFG_b.LCD_PD=1;     //LCD 电压发生器掉电
LCD->LCDCTRL0_b.LEDINV=biasanode;//LED共正极/共负极选择
LCD->LCDCTRL0_b.LEDEN=1;         //选择为 LED输出模式
LCD->LCDCTRL0_b.LCDEN=0;
}
return;
}

3-2 LCD输出使能

这段函数控制着LCD的COM端口和SEGMEN端口的输出使能,可以根据实际需求来进行配置。比如开发板使用了COM0~COM3,SEG0~SEG7。因此comchannel参数的低4位都是置1的,即输入参数应该为0xF。同理,segchannel的低8位都是置1的,即输入参数应该为0xFF。

    void LCD_EnableOutput(uint8_t comchannel, uint16_t segchannel)
{
LCD->LCDOUTEN0_b.LCDCOMEN=comchannel;
LCD->LCDOUTEN1_b.LCDSEGEN=segchannel;
return;
}

3-3 LCD功能关闭

这段函数的作用是关闭LCD外设功能,通过LCD电压发生器,并且关闭其时钟。

    void LCD_Deinit(void)
{
SYSCON->PDRUNCFG_b.LCD_PD=1;       //LCD 电压发生器掉电
SYSCON->SYSAHBCLKCTRL_b.LCD_CLK=0; //LCD 时钟关闭
return;
}

3-4 LCD全显

这段函数的功能是数据映射寄存器全部置位,从而全部显示。

    void LCD_LightFullScreen(void)
{
LCD->MEMMAP0=0xFFFFFFFF;
LCD->MEMMAP1=0xFFFFFFFF;
LCD->MEMMAP2=0xFFFFFFFF;
LCD->MEMMAP3=0xFFFFFFFF;
return;
}

3-5 LCD清屏

这段函数的功能是数据映射寄存器全部清0,从而快速清屏。

    void LCD_ClearScreen(void)
{
LCD->MEMMAP0=0;
LCD->MEMMAP1=0;
LCD->MEMMAP2=0;
LCD->MEMMAP3=0;
return;
}

4、端口中断例程

介绍完LCD常用的驱动函数,接下来用个小例程来演示LCD的驱动。测试程序的代码如下:

    void lcd_PortInit(void)
{
//initial LCD pin
PB_2_INIT  (PB_2_LCD_COM0  );//LCD_COM0:PB_2
PB_10_INIT (PB_10_LCD_COM1 );//LCD_COM1:PB_10
PB_11_INIT (PB_11_LCD_COM2 );//LCD_COM2:PB_11
PB_6_INIT  (PB_6_LCD_COM3  );//LCD_COM3:PB_6 

PB_12_INIT (PB_12_LCD_SEG0 );//LCD_SEG0:PB_12
PB_13_INIT (PB_13_LCD_SEG1 );//LCD_SEG1:PB_13
PB_14_INIT (PB_14_LCD_SEG2 );//LCD_SEG2:PB_14
PB_15_INIT (PB_15_LCD_SEG3 );//LCD_SEG3:PB_15
PA_8_INIT  (PA_8_LCD_SEG4  );//LCD_SEG4:PA_8
PA_9_INIT  (PA_9_LCD_SEG5  );//LCD_SEG5:PA_9
PA_10_INIT (PA_10_LCD_SEG6 );//LCD_SEG6:PA_10
PA_11_INIT (PA_11_LCD_SEG7 );//LCD_SEG7:PA_11
} 

int main(void)
{
uint32_t number = 0;
uint32_t lcd[10]={0xD07,0x500,0xB05,0xF01,0x702,0xE03,0xE07,0x501,0xF07,0x703};//0~9 LCD真值表

lcd_PortInit();//LCD端口初始化
LCD_Init(LCD_MODE, DUTY_4, LCD_BIAS_3, 100);//LCD 驱动初始化
LCD_EnableOutput(0xF, 0xFF);//使能LCD输出

while(1)
{
LCD->MEMMAP0 = (lcd[number]<<16)|lcd[number];
LCD->MEMMAP1 = (lcd[number]<<16)|lcd[number];
if (number++==11)
number=0;
SYS_DelaymS(1000);
}
}

程序第一步先执行lcd_PortInit函数来复用LCD端口。端口复用完成后就是LCD_Init函数,这个在前面讲解过。我们选择的是LCD输出模式,1/4占空比输出,1/3偏压,100Hz的COM刷新率。完成初始化的配置后,就可以使能LCD的输出了。

测试用的显示程序是让液晶在0~9之间不停的循环显示。效果图如下:

全0显示:

7.png

图7 LCD显示全0

全9显示:

8.png

图8 LCD显示全9

来源:敏矽MCU

免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理(联系邮箱:cathy@eetrend.com)。

围观 36