芯查查logo
  • 物料选型
  • 数据服务
    1. 新产品
    2. 查替代
    3. 丝印反查
    4. 查品牌
    5. PCN/PDN
    6. 查方案
    7. 查代理
    8. 数据合作
  • SaaS/方案
      SaaS产品
    1. 供应链波动监测预警
    2. 半导体产业链地图
    3. 智能BOM管家
    4. 解决方案
    5. 汽车电子
    6. 政府机构
    7. 数据API
  • 商城
  • 行业资讯
    1. 资讯
    2. 直播
  • 论坛社区
    1. 论坛
    2. 学习
    3. 测评中心
    4. 活动中心
    5. 积分商城
  • 查一下
RA4L1-SENSOR+02:成功驱动板载的LCD屏幕
原创 发布时间:15:30
版块:
瑞萨电子
简介:驱动板载的LCD断码屏。

LCD段码屏(又称段式LCD或段码显示屏)是一种常见的液晶显示技术,主要用于显示简单的数字、字符或固定图形。以下是其核心特点和工作原理的详细说明:

一:LCD基本知识分享:

1. 基本结构

分段显示:屏幕由多个独立的“段”(Segment)组成,每个段对应显示内容的一部分(如数字的某一段笔画、符号或简单图标)。

背电极(COM)与段电极(SEG):通过交叉矩阵控制,每个段的亮灭由对应的电极信号决定。

固定图案:显示内容需预先设计(如计算器、电子表上的数字),无法动态变化。

2. 工作原理

驱动方式:采用静态驱动或动态驱动(多路复用),通过施加电压改变液晶排列,控制光线透过与否。

对比度高:通常为单色(如蓝底白字、黑底灰字),依赖背光或环境光。

低功耗:仅在切换段状态时耗电,适合电池供电设备。

3:RA4L1板载的LCD资料:

液晶显示(LCD)是嵌入式系统中常见的人机交互方式,广泛应用于工业控制、智能家电、医疗设备和消费电子产品。Renesas RA4L1 微控制器(MCU)内置 Segment LCD Controller (SLCDC),可直接驱动 静态、1/2、1/3、1/4 Bias 的段式 LCD 显示屏,无需额外的 LCD 驱动芯片。这种集成方案不仅降低了硬件成本,还简化了设计。

Renesas RA4L1 的 SLCDC 模块提供了一种高效、低功耗、低成本的 LCD 显示方案。通过 FSP 提供的 r_slcdc 驱动,开发者可以快速初始化 LCD,轻松控制显示内容。在实际项目中,合理配置 COM/SEG 引脚、优化时钟和对比度设置,可以进一步提升 LCD 显示效果。

二:开发板图片如下所示:

开发板资料的LCD知识如下所示:

要将 LCD 屏幕的引脚正确映射到 RA MCU 的 SLCDC(Segment LCD Controller)驱动引脚,需要按照 LCD 的 COM(公共端) 和 SEG(段) 分配关系,将其连接到 MCU 的相应 SLCDC 引脚。LCD映射到 MCU 的 SLCDC 驱动引脚

通过上图,一个数码管驱动需要两个位选来确定,这种和数码管驱动有点区别,大家在驱动的时候,需要格外的注意;

板载的LED的原理图如下所示:

三:软件配置:

打开FSP库,对所使用的IO口进行配置;

代码编写流程如下所示:

以第一个数码管驱动做简单的结合扫

在 SLCDC (Segment LCD Controller) 驱动 LCD 数码管时,每个段 (SEGx) 需要与多个公共端 (COMx) 进行组合,以控制哪些段应该点亮。

从第11个段开始,由于只有4个COM,将4个数据写入SLCDC的段寄存器,驱动LCD显示对应图案或数字。

1B 段 和 1C 段 分别映射到:

● 1B → SEG11, COM1

● 1C → SEG11, COM2

要点亮 1B (COM1) 和 1C (COM2),所以需要设置:

● COM1 = 1(对应第 1 位)

● COM2 = 1(对应第 2 位)

● 其他 COM0 和 COM3 = 0

这里只有COM1和COM2需要驱动,对应十六进制为0x6,驱动代码如下所示。

下方代码R_SLCDC_Write中,0代表从 SEG0 开始写入数据,数组segment_data_num1长度sizeof(segment_data_num1),为11。在SEG11写入0x6。

用计算器的二进值确定一下,断码需要点亮时,发送的数据;

R_SLCDC_Write()函数:

R_SLCDC_Write() 的作用是向段式LCD控制器(SLCDC)写入一系列的数据,以控制LCD的显示内容。

数据被写入SLCDC内部的段数据寄存器中,从而控制LCD各段的亮灭状态。

fsp_err_t R_SLCDC_Write (slcdc_ctrl_t * const p_ctrl,
uint8_t const        start_segment,
uint8_t const      * p_data,
uint8_t const        segment_count)
{
slcdc_instance_ctrl_t * p_instance_ctrl = (slcdc_instance_ctrl_t *) p_ctrl;

fsp_err_t err = FSP_SUCCESS;

#if (SLCDC_CFG_PARAM_CHECKING_ENABLE)
FSP_ASSERT(p_instance_ctrl);
FSP_ASSERT(p_data);
FSP_ERROR_RETURN(SLCDC_CLOSED != p_instance_ctrl->open, FSP_ERR_NOT_OPEN);

if ((BSP_FEATURE_SLCDC_MAX_NUM_SEG <= start_segment) ||
(((uint8_t) (BSP_FEATURE_SLCDC_MAX_NUM_SEG)) < (start_segment + segment_count)))
{
return FSP_ERR_INVALID_ARGUMENT;
}

#else
FSP_PARAMETER_NOT_USED(p_instance_ctrl);
#endif

/* Display data is stored in the LCD segment data register array */
for (uint8_t seg = start_segment; (seg - start_segment) < segment_count; seg++)
{
R_SLCDC->SEG[seg] = *p_data;
p_data++;
}

return err;
}

这里我所使用的驱动函数是:

R_SLCDC_Modify() 是用于修改单个段寄存器中的部分位的函数,属于 SLCDC 驱动的精细控制接口

fsp_err_t R_SLCDC_Modify (slcdc_ctrl_t * const p_ctrl,
uint8_t const        segment,
uint8_t const        data,
uint8_t const        data_mask)
{
slcdc_instance_ctrl_t * p_instance_ctrl = (slcdc_instance_ctrl_t *) p_ctrl;

#if (SLCDC_CFG_PARAM_CHECKING_ENABLE)
FSP_ASSERT(p_instance_ctrl);
FSP_ERROR_RETURN(SLCDC_CLOSED != p_instance_ctrl->open, FSP_ERR_NOT_OPEN);

if (BSP_FEATURE_SLCDC_MAX_NUM_SEG <= segment)
{
return FSP_ERR_INVALID_ARGUMENT;
}

#else
FSP_PARAMETER_NOT_USED(p_instance_ctrl);
#endif

/* Mask and write data to segment */
R_SLCDC->SEG[segment] = (R_SLCDC->SEG[segment] & (uint8_t) (~(data_mask))) | data;

return FSP_SUCCESS;
}

修改底层的驱动函数,完成对数字的驱动显示:

void OneDisNumber(char number)
{
switch (number)
{
case 0 :           //准备并写入段显示数据,第一个数码管显示0
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0xD, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x7, 0xF);
break ;
case 1 :           //准备并写入段显示数据,第一个数码管显示1
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0x0, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x6, 0xF);
break ;
case 2 :           //准备并写入段显示数据,第一个数码管显示2
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0xE, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x3, 0xF);
break ;
case 3 :           //准备并写入段显示数据,第一个数码管显示3
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0xA, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x7, 0xF);
break ;
case 4 :           //准备并写入段显示数据,第一个数码管显示4
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0x3, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x6, 0xF);
break ;
case 5 :           //准备并写入段显示数据,第一个数码管显示5
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0xB, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x5, 0xF);
break ;
case 6 :           //准备并写入段显示数据,第一个数码管显示6
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0xF, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x5, 0xF);
break ;
case 7 :           //准备并写入段显示数据,第一个数码管显示7
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0x0, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x7, 0xF);
break ;
case 8 :           //准备并写入段显示数据,第一个数码管显示8
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0xF, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x7, 0xF);
break ;
case 9 :           //准备并写入段显示数据,第一个数码管显示9
R_SLCDC_Modify(&g_slcdc0_ctrl, 3, 0xB, 0xF);
R_SLCDC_Modify(&g_slcdc0_ctrl, 11, 0x7, 0xF);
break ;
default :
break ;
}
}

在主程序添加,对一个第一个数码管的驱动显示部分:

data++;
if(data >=10) data = 0 ;
OneDisNumber(data);
SencoendDisNumber(data);
R_BSP_SoftwareDelay (2000, BSP_DELAY_UNITS_MILLISECONDS);

四:实物测试如下所示:

开源社区
15:30
  • 举报
😁😂😃😄😅😆😉😊😋😌😍😏😒😓😔😖😘😚😜😝😞😠😡😢😣😤😥😨😩😪😫😭😰😱😲😳😵😷😸😹😺😻😼😽😾😿🙀🙅🙆🙇🙈🙉🙊🙋🙌🙍🙎🙏✂✅✈✉✊✋✌✏✒✔✖✨✳✴❄❇❌❎❓❔❕❗❤➕➖➗➡➰🚀🚃🚄🚅🚇🚉🚌🚏🚑🚒🚓🚕🚗🚙🚚🚢🚤🚥🚧🚨🚩🚪🚫🚬🚭🚲🚶🚹🚺🚻🚼🚽🚾🛀Ⓜ🅰🅱🅾🅿🆎🆑🆒🆓🆔🆕
@好友

全部评论

加载中
游客登录通知
已选择 0 人
自定义圈子
移动
发布帖子
发布动态
发布问答
发布者
聪聪哥哥
最新帖子
RA4L1-SENSOR+04:使用消息队列创建任务调度RA4L1-SENSOR+02:成功驱动板载的LCD屏幕RA4L1-SENSOR+01:环境搭建,点亮板载LED2025年无人机行业概览报告芯片丝印反查全攻略:从基础识别到高阶应用技巧解析
热门版块
查看更多
每日打卡
问型号
问技术
问行情
电子元器件
硬件资源下载区
汽车电子工程师论坛
工业电子专区
新手入门指南
专家问答

点赞

收藏

分享

微信扫码
分享给好友

评论