【屏幕模块 - 笔记】深圳市晶联讯电子 液晶模块 JLX19296G-915-BN
最近工作在用这款屏幕,折腾两星期后差不多摸透了,写下笔记给日后的自己,和有需要的人.
一、屏幕介绍
- 型号 : JLX19296G-915-BN , 这个型号属于裸屏,焊接式 FPC,没有自带字库.尺寸为
192*96
. - 特点 : 能串行也能并行通讯, 多种显示扫描方向,有单色和灰度,能亮和不亮背光.对比度设置.
- 实现 : 我实现的是硬件串行; 扫描方向是
自上到下,从左到右,低位在上
; 单色;亮不亮背光取决于有没有给背光供电,有就亮,没有就不亮. - 相关 : 官网链接 http://www.jlxlcd.cn/html/zh-detail-877.html ; pdf 说明文档也在里面下载.
- 注意 : 不同型号的引脚不太一样,初始化的部分参数不一样,其它差不多(虽然我没用过多款,但是对比pdf手册感觉是一样的 )
二、代码解析
不说废话,直接按着代码一步步解说 .
1. 单片机通讯引脚 的 初始化
- 这部分主要是gpio的初始化,不同单片机平台的api接口不一样,自行测试更换.建议一开始拿着裸机的spi例程修改,事半功倍.
- 只有两点需要 注意 的:
- 模块正常工作时,复位引脚接高电平,需要复位就拉低,保持,再拉高.如果悬空或没有接高电平,就不能使用,惨痛的教训!!!
- 串行通讯使用spi协议,感觉pdf的时序图,是在时钟线scl从低电平跳变高电平时读取sda的数据,从pdf自带例程的模拟通讯实现也能看出来.
时钟线先保持低电平,改变数据线,时钟线跳变拉高读取数据
; 在硬件spi设置中就是模式0 (CPOL=0; CPHA=0)
.波特率的设置根据单片机不同,可以自己算也可以自己试,我是从快到慢一个个试.
推荐笔记 : SPI总线传输的4种模式 https://www.cnblogs.com/gmpy/p/12461461.html
/******************************************************************************** 局部宏定义******************************************************************************/
#if 1 // 外部实现
#define lcd_cs1(x) Spi_SetCS(M0P_SPI1, x);Gpio_WriteOutputIO(PORT_S3_SSEL, PIN_S3_SSEL, x) //CS
#define lcd_reset(x) ;//RST lcd_reset(0) lcd_reset(1) // 使用时不需要复位,就不接
#define lcd_sclk(x) Gpio_WriteOutputIO(PORT_S3_SCLK, PIN_S3_SCLK, x) //串行时钟 lcd_sclk(0) lcd_sclk(1)
#define lcd_rs(x) Gpio_WriteOutputIO(PORT_S3_MISO, PIN_S3_MISO, x) //RS lcd_rs(0) lcd_rs(1)
#define lcd_sid(x) Gpio_WriteOutputIO(PORT_S3_MOSI, PIN_S3_MOSI, x) //串行数据 lcd_sid(0) lcd_sid(1)
#endif/******************************************************************************** 函数实现-全局(“外部”)和局部(“静态”)******************************************************************************//** // 外部实现********************************************************************************* \brief 板级引脚初始化** \retval None******************************************************************************/
static void gpio_bsp_init(void)
{// 具体实现略,不同单片机平台不一样,不赘述.// 初始化 gpio 引脚// 初始化 spi 外设 模式0,波特率自行测试// 注意 该屏幕的spi通讯并不需要输入, // MISO 引脚被用作输出,输出高电平代表MOSI输出数据,输出低电平代表MOSI输出指令// 如果控模块电源引脚,别忘记打开;// 复位引脚必须接高电平
}/** // 外部实现********************************************************************************* \brief 板级延时** \param i 延时毫秒** \retval None******************************************************************************/
static void lcd_jlx19296_delay_ms(int i)
{delay10us(i*10);
}/** // 外部实现********************************************************************************* \brief 板级模块复位** \param i 延时毫秒** \retval None******************************************************************************/
static void lcd_jlx19296_reset(void)
{// 如果没有复位操作就将复位引脚接高电平,才能正常工作!!!!!lcd_reset(0);lcd_jlx19296_delay_ms(100);lcd_reset(1);lcd_jlx19296_delay_ms(100);
}/** // 外部实现********************************************************************************* \brief 发送指令** \param data1 8位/1字节的指令** \retval None******************************************************************************/
static void lcd_jlx19296_cmd(uint32_t data1)
{lcd_cs1(0);lcd_rs(0);// 模拟spi的方法/*for(int i=0; i<8; i++) {lcd_sclk(0); // 时钟线先保持低电平if(data1&0x80) lcd_sid(1); // 改变数据线else lcd_sid(0);lcd_sclk(1); // 时钟线跳变拉高,读取数据线data1<<=1;}*/// 硬件spi的方法while(Spi_GetStatus(M0P_SPI1, SpiTxe) == FALSE); //发送缓冲器器空标志Spi_SendData(M0P_SPI1, data1);lcd_cs1(1);
}/** // 外部实现********************************************************************************* \brief 发送数据** \param data1 8位/1字节的数据** \retval None******************************************************************************/
static void lcd_jlx19296_data(uint32_t data1)
{lcd_cs1(0);lcd_rs(1) ;// 模拟spi的方法/*for(int i=0; i<8; i++){lcd_sclk(0); // 时钟线先保持低电平if(data1&0x80) lcd_sid(1); // 改变数据线else lcd_sid(0);lcd_sclk(1); // 时钟线跳变拉高,读取数据线data1<<=1;}*/// 硬件spi的方法while(Spi_GetStatus(M0P_SPI1, SpiTxe) == FALSE); //发送缓冲器器空标志Spi_SendData(M0P_SPI1, data1);lcd_cs1(1);
}
2. 屏幕模块 的 初始化
这部分就是拷贝pdf例程的内容的了,我对比多个型号的pdf例程,和指令表内容, 发现模块初始化这部分内容,不同型号的例程存在坑爹的赋值粘贴嫌疑 ,也就是有部分注释没改或没有用的多余内容,但不影响使用.
可以屏幕说明pdf有附带中文指令表说明,网上也有
ST75256 (屏幕内嵌的主控芯片)
说明手册的中文版,可以对照查看.这部分我无聊的将每个指令都化作宏定义,查看手册表明注释和分类.如下.最后总结需要重点关注的内容:
- 数据扫描方向
Data_Scan_Direction_0
: 决定了扫描方向 自上到下,从左到右. - 数据格式选择
Data_Format_Select
: 决定了 低位在上. - 显示模式
Display_Mode_0
: 决定了单色模式. - 设置对比度
Set_Vop_0
: 决定屏幕整体显示偏黑还是偏透明. - 显示控制
Display_Control_0
: (重点) 我起初将这个误以为是对比度,修改后导致显示坐标发生整体偏移,所以这部分内容不要修改,直接拷贝例程最好.
- 如果你初始化成功会看到屏幕是"
雪花屏
"的效果,之后调用清屏即可.如果你初始化后屏幕没有任何显示,代表初始化失败了,可能没成功通讯,检查通讯引脚,模块电源,还有复位引脚有没有接高电平.
/******************************************************************************** 全局宏定义 // https://max.book118.com/html/2017/1025/137875607.shtm******************************************************************************/
// 1. 设置扩展指令
#define Extension_Command(EXT1, EXT0) ((0x30)|(((EXT1)&0x1)<<3)|(((EXT0)&0x1)<<0))
// ======================= 指令 1 =======================
// 2. 显示开/关 设置LCD显示器 DSP=0;显示关闭 DSP=1;显示打开
#define Display_ON_OFF(DSP) ((0xAE)|(((DSP)&0x1)<<0))
// 3. 反转显示 设置反向显示 INV=0;正常显示 INV=1;反向显示
#define Inverse_Display(INV) ((0xA6)|(((INV)&0x1)<<0))
// 4. 所有像素开/关 设置所有像素模式 AP=0;全像素关闭模式 AP=1;全像素开启模式
#define All_Pixel_ON_OFF(AP) ((0x22)|(((AP)&0x1)<<0))
// 5. 显示控制 CLD;设置CL驱动频率 DT;点空比 LF/FI;帧周期
#define Display_Control_0() (0xCA)
#define Display_Control_1(CLD) ((0x00)|(((CLD)&0x1)<<2))
#define Display_Control_2(DT) ((0x00)|(((DT)&0xFF)<<0))
#define Display_Control_3(LF, FI) ((0x00)|(((LF)&0xF)<<0)|(((FI)&0x1)<<4)|(((LF)&0x10)<<1))
// 6. 省电 设置省电模式 SLP=0;退出休眠模式 SLP=1;进入休眠模式
#define Power_Save(SLP) ((0x94)|(((SLP)&0x1)<<0))
// 7. 设置页面地址 起始页面地址;00H<=YS<=28H 结束页面地址;YS<=YE<=28H
#define Set_Page_Address_0() (0x75)
#define Set_Page_Address_1(YS) ((0x00)|(((YS)&0xFF)<<0))
#define Set_Page_Address_2(YE) ((0x00)|(((YE)&0xFF)<<0))
// 8. 设置列地址 起始列地址;00H<=XS<=FFH 结束列地址;XS<=XE<=FFH
#define Set_Column_Address_0() (0x15)
#define Set_Column_Address_1(XS) ((0x00)|(((XS)&0xFF)<<0))
#define Set_Column_Address_2(XE) ((0x00)|(((XE)&0xFF)<<0))
// 9. 数据扫描方向 设置正/反显示地址 和 地址扫描方向
#define Data_Scan_Direction_0() (0xBC)
#define Data_Scan_Direction_1(MV, MX, MY) ((0x00)|(((MV)&0x1)<<2)|(((MX)&0x1)<<1)|(((MY)&0x1)<<0))
// 10. 写数据 循环写数据
#define Write_Data_0() (0x5C)
#define Write_Data_1(DATA) ((0x00)|(((DATA)&0xFF)<<0))
// 20. 电源控制 功率电路操作 =0;OFF =1;ON
#define Power_Control_0() (0x20)
#define Power_Control_1(VB,VF,VR) ((0x00)|(((VB)&0x1)<<3)|(((VF)&0x1)<<1)|(((VR)&0x1)<<0))
// 21. 设置VOP 设置对比度 微调对比度,可调范围0x00~0x3f,共64级 粗调对比度,可调范围0x00~0x07,共8级
#define Set_Vop_0() (0x81)
#define Set_Vop_1(VOP) ((0x00)|(((VOP)&0x3F)<<0))
#define Set_Vop_2(VOP) ((0x00)|(((VOP)&0x7)<<0))
// 27. 数据格式选择 DO=0;高位在前 DO=1;低位在前
#define Data_Format_Select(DO) ((0X8)|(((DO)&0x1)<<2))
// 28. 显示模式 设置显示模式 DM=0;单色(默认) DM=1;4级灰度模式
#define Display_Mode_0() (0xF0)
#define Display_Mode_1(DM) ((0x10)|(((DM)&0x1)<<0))
// ======================= 指令 2 =======================
// 31.设定灰度 GL;设置轻灰色级别 GD;设定暗灰色等级
#define Set_Gray_Level_0() (0x20)
#define Set_Gray_Level_1(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_2(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_3(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_4(GL) ((0x00)|(((GL)&0x1F)<<0))
#define Set_Gray_Level_5(GL) ((0x00)|(((GL)&0x1F)<<0))
#define Set_Gray_Level_6(GL) ((0x00)|(((GL)&0x1F)<<0))
#define Set_Gray_Level_7(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_8(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_9(GD) ((0x00)|(((GD)&0x1F)<<0))
#define Set_Gray_Level_10(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_11(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_12(GD) ((0x00)|(((GD)&0x1F)<<0))
#define Set_Gray_Level_13(GD) ((0x00)|(((GD)&0x1F)<<0))
#define Set_Gray_Level_14(GD) ((0x00)|(((GD)&0x1F)<<0))
#define Set_Gray_Level_15(HD) ((0x00)|(((HD)&0x1F)<<0))
#define Set_Gray_Level_16(HD) ((0x00)|(((HD)&0x1F)<<0))
// 32. LCD偏压比设置 BE;升压电容频率 BS;偏压比,
#define Analog_Circuit_Set_0() (0x32)
#define Analog_Circuit_Set_1() (0x00)
#define Analog_Circuit_Set_2(BE) ((0x00)|(((BE)&0x3)<<0))
#define Analog_Circuit_Set_3(BS) ((0x00)|(((BS)&0x7)<<0))
// 35. 自动读取控制 设置自动读取指令 XARD=0;启用自动读取 XARD=1;禁用自动读取
#define Auto_Read_Control_0() (0xD7)
#define Auto_Read_Control_1(XARD) ((0x8F)|(((XARD)&0x1)<<4))
// 42. 帧速率 此指令比较重要,不加此指令升压会慢 0.5s 帧速率设置在不同的温度范围
#define Set_Frame_Rate_0() (0xF0)
#define Set_Frame_Rate_1(FRA) ((0x00)|(((FRA)&0x1F)<<0))
#define Set_Frame_Rate_2(FRB) ((0x00)|(((FRB)&0x1F)<<0))
#define Set_Frame_Rate_3(FRC) ((0x00)|(((FRC)&0x1F)<<0))
#define Set_Frame_Rate_4(FRD) ((0x00)|(((FRD)&0x1F)<<0))
// ======================= 指令 3 =======================
// 用不到
// ======================= 指令 4 =======================
// 用不到/*********************************************************************************** \brief 模块初始化** \retval None******************************************************************************/
void lcd_jlx19296_init(void)
{gpio_bsp_init();lcd_jlx19296_delay_ms(100);lcd_jlx19296_reset(); // 奇葩的屏幕,复位引脚要一直处于高电平lcd_jlx19296_cmd(Extension_Command(0,0)); // EXT1=0,EXT0=0,表示选择了“扩展指令表 1” lcd_jlx19296_cmd(Power_Save(0)); // 退出睡眠 lcd_jlx19296_cmd(Extension_Command(0,1)); // EXT1=0,EXT0=1,表示选择了“扩展指令表 2” lcd_jlx19296_cmd(Auto_Read_Control_0()); // 自动读取设置 指令lcd_jlx19296_data(Auto_Read_Control_1(1)); // 自动读取禁用lcd_jlx19296_cmd(Analog_Circuit_Set_0()); // LCD 偏压比设置 指令lcd_jlx19296_data(Analog_Circuit_Set_1()); // 振荡频率的调整 lcd_jlx19296_data(Analog_Circuit_Set_2(1)); // 升压电容器的频率->6KHz lcd_jlx19296_data(Analog_Circuit_Set_3(3)); // Bias=1/11 lcd_jlx19296_cmd(Set_Frame_Rate_0()); // 帧速率 帧速率设置在不同的温度范围lcd_jlx19296_data(Set_Frame_Rate_1(0xF)); // 此指令比较重要,不加此指令升压会慢 0.5slcd_jlx19296_data(Set_Frame_Rate_2(0xF)); lcd_jlx19296_data(Set_Frame_Rate_3(0xF)); lcd_jlx19296_data(Set_Frame_Rate_4(0xF)); /*lcd_jlx19296_cmd(Set_Gray_Level_0()); // 灰度设置 lcd_jlx19296_data(Set_Gray_Level_1(0x01)); // 没有用到灰度,也是摆设lcd_jlx19296_data(Set_Gray_Level_2(0x03)); lcd_jlx19296_data(Set_Gray_Level_3(0x05));lcd_jlx19296_data(Set_Gray_Level_4(0x07)); lcd_jlx19296_data(Set_Gray_Level_5(0x09)); lcd_jlx19296_data(Set_Gray_Level_6(0x0b)); lcd_jlx19296_data(Set_Gray_Level_7(0x0d)); lcd_jlx19296_data(Set_Gray_Level_8(0x10)); lcd_jlx19296_data(Set_Gray_Level_9(0x11)); lcd_jlx19296_data(Set_Gray_Level_10(0x13)); lcd_jlx19296_data(Set_Gray_Level_11(0x15)); lcd_jlx19296_data(Set_Gray_Level_12(0x17)); lcd_jlx19296_data(Set_Gray_Level_13(0x19)); lcd_jlx19296_data(Set_Gray_Level_14(0x1b)); lcd_jlx19296_data(Set_Gray_Level_15(0x1d)); lcd_jlx19296_data(Set_Gray_Level_16(0x1f));*/lcd_jlx19296_cmd(Extension_Command(0,0)); // EXT1=0,EXT0=0,表示选择了“扩展指令表 1” /*lcd_jlx19296_cmd(Set_Column_Address_0()); // 设置列地址lcd_jlx19296_data(Set_Column_Address_1(0x00)); // 在这里设置行列坐标貌似是摆设,没有用lcd_jlx19296_data(Set_Column_Address_1(0xC0));lcd_jlx19296_cmd(Set_Page_Address_0()); // 设置页面地址lcd_jlx19296_data(Set_Page_Address_1(0x00)); lcd_jlx19296_data(Set_Page_Address_2(0x60));*/lcd_jlx19296_cmd(Data_Scan_Direction_0()); // 数据扫描方向 lcd_jlx19296_data(Data_Scan_Direction_1(1, 0, 0)); // DATA 0x04h (MV =1, MX=0, MY=0)lcd_jlx19296_cmd(Data_Format_Select(1)); // 数据格式选择, 1 是低位在前 D0-D7, 0 是高位在前 D7-D0 lcd_jlx19296_cmd(Display_Mode_0()); // 显示模式 lcd_jlx19296_data(Display_Mode_1(0)); // 如果设为 1:表示选择 4 灰度级模式,如果设为 0:表示选择黑白模式 lcd_jlx19296_cmd(Display_Control_0()); // 显示控制 lcd_jlx19296_data(Display_Control_1(0)); // 设置 CL 驱动频率:CLD=0 lcd_jlx19296_data(Display_Control_2(0X5F)); // 0X5F // 占空比:Duty=128 lcd_jlx19296_data(Display_Control_3(0x10, 0)); // N 行反显:Nline=off lcd_jlx19296_cmd(Set_Vop_0()); // 设置对比度,“0x81”不可改动,紧跟着的 2 个数据是可改的,但“先微调后粗调”这个顺序别乱了 lcd_jlx19296_data(Set_Vop_1(0x14)); // 0x7 // 0x14 // 0x22 // 对比度微调,可调范围 0x00~0x3f,共 64 级 lcd_jlx19296_data(Set_Vop_2(0x03)); // 0x03 // 对比度粗调,可调范围 0x00~0x07,共 8 级 lcd_jlx19296_cmd(Power_Control_0()); // 电源控制lcd_jlx19296_data(Power_Control_1(1,1,1)); // D0=regulator ; D1=follower ; D3=booste, on:1 off:0 lcd_jlx19296_delay_ms(100); lcd_jlx19296_cmd(Display_ON_OFF(1)); // 打开显示
}
3. 屏幕显示
首先就是设置显示区域,也就是行列坐标的起始和结束点.然后输入写数据.这部分操作和大部分屏幕操作类似.清屏函数就是设置全屏区域,然后输入空数据.
值得 注意 的是显示区域的设置, 屏幕内嵌的主控芯片
ST75256
规定,纵向坐标是 8个像素点1组 .也就说192*96的屏幕,横向x坐标输入范围是0~191
,而纵向y坐标输入范围则是0~11
(96/8=12组). 这意味着刷新时是8行1组像素点一起刷新的,如果想交叉组显示内容就颇为麻烦.
这款除了单色外,还支持四级灰度显示,貌似设置显示区域的部分不变.输入数据的部分需要加倍输入.
如果你在初始化时,修改了
显示控制 Display_Control_0
的参数,那设置坐标就会发生偏移,而且刷新速度大大减低.如果你发现刷新速度肉眼可见的慢,纵向y坐标范围不是0~11
,而是8~19
.那你可以怀疑是不是这里个参数初始化错了.
- 然后就是控制单个点显示内容了.如果一时不理解显示方向,就用修改清屏函数然后单步调试,再用纸笔笔画一下就理解了.
/*********************************************************************************** \brief 设置显示的区域 设置行列地址** \param xs 开始列地址 0~191** \param xe 结束列地址** \param ys 开始行地址 0~11** \param ye 结束行地址** \retval None******************************************************************************/
static void lcd_jlx19296_address(uint32_t xs,uint32_t xe,uint32_t ys,uint32_t ye)
{ xs = xs-0;xe = xe-0;ys = ys+0;ye = ye+0; // ======================= 特别说明 =======================
// 根据实测,
// y的取值范围是 0~11,共12行,
// x的取值范围是 0~191,共192列,
// 如果发生偏移,是 Display_Control_0 指令参数有误,要按照例程来,调整对比度不是调整这个
// ======================= 特别说明 =======================lcd_jlx19296_cmd(Set_Column_Address_0()); // 设置列地址lcd_jlx19296_data(Set_Column_Address_1(xs));lcd_jlx19296_data(Set_Column_Address_1(xe));lcd_jlx19296_cmd(Set_Page_Address_0()); // 设置页面地址lcd_jlx19296_data(Set_Page_Address_1(ys)); // 注意,页地址是以4为单位lcd_jlx19296_data(Set_Page_Address_2(ye));lcd_jlx19296_cmd(Write_Data_0()); // 写数据 循环写数据
}/*********************************************************************************** \brief 清屏** \retval None******************************************************************************/
void lcd_jlx19296_clear_screen(void)
{// 设置显示区域lcd_jlx19296_address(0,191,0,11); // 输入显示数据for(int i=0; i<192; i++){for(int j=0; j<12; j++){lcd_jlx19296_data(Write_Data_1(0x00));}}
}/*********************************************************************************** \brief 显示一个字符** \param x x坐标 (0~191)** \param y y坐标 (0~95)** \param x_size x尺寸 (5/8/16/32)** \param y_size y尺寸 (8/16/32)** \param data 数组数据** \retval None******************************************************************************/
void lcd_jlx19296_char(uint32_t x, uint32_t y, uint32_t x_size, uint32_t y_size, const uint8_t *data)
{uint32_t index = 0;// 计算正确的xy坐标x = (x > 191) ? (191) : (x);y = (y > 95) ? (95/8) : (y/8);x_size = (x_size == 5 || x_size == 8 || x_size == 16 || x_size == 32) ? (x_size) : (5);y_size = (y_size == 8 || y_size == 16 || y_size == 32) ? (y_size/8-1) : (8/8-1);// 设置显示区域lcd_jlx19296_address(x, x+x_size, y, y+y_size); // 输入显示数据for (int i=0; i<x_size; i++)for (int j=0; j<=y_size; j++)lcd_jlx19296_data(Write_Data_1(data[index++]));
}
4. 字符取模
- 最后推荐一下字符取模, 使用
PCtoLCD2002
即可,功能多操作易.就是小尺寸的取模会不正常,比如5*8.推测作者是直接将字符图片像素化输出,并没有专门的优化.
看了一下介绍才发现,这工具是一个学生的毕设作品,真棒,感谢这位大神的无私奉献.
可以选择不同字体来优化显示效果.(忘记我选的那种了,各位自己根据喜欢到字库里挑吧 ).
最后的最后说明一下中文字符串在单片机里的编码,我才知道,原来ide能编译中文字符串,如果输入中文字符串,在单片机程序中是以三字节为单位的,不同于ascii的一字节.
- 这时有个方向问题,众所周知,字符串是倒序的,即 高位在右边,低位在左边 . 比如字符串
uint8_t str[2] = "12"
,str[0] = '1' (0x31)
,str[1] = '2' (0x32)
. 如果用16位类型读取就是0x3231
,而不是0x3132
.之前使用都没感觉什么问题.- 如果是中文字符串,占三个字节, 就会有个奇葩现象, 比如
uint8_t str[] = "我"
, 假设str[0] = 0xFE
,str[1] = 0xFB
,str[2] = 0x23
, 用32位类型读取就是0x0023FBFE
. 直接这样判断用好像没问题.但是!!!- 中文如果不是按字符串,而是按字符赋值, 比如
uint32_t str = '我'
,那str的值就是0x00FEEB23
. 结果会反过来,这样判断就不成立了!!! 特别有趣 ,一定要注意.- 我使用时统一按字符串赋值,单个字符也是字符串形式,这样就不用担心了.
- 推荐一下我使用的字库形式,使用结构体嵌套共用体+数组的形式.
- 从取模软件导出数据,使用python脚本处理数据格式,得到想要的格式.一键搞定字库问题.
吐槽一下,python中处理中文字符串是占2个字节的.不知道这个怎么设置,单片机也占2个比较好,使用的中文不多,2个字节完全够用.
/*********************************************************************************** \brief 点阵字符数据 5*8 结构体定义******************************************************************************/
typedef struct st_lattice_data_5x8
{union{uint8_t bit_8[4]; // 如果是 ascii 占用1个字节, 否者占用3个字节uint32_t bit_32; }encoding; // 当前字符编码uint8_t lattice_data[5*8/8]; // 当前字符大小 5x8 所需的字节数量
} st_lattice_data_5x8_t;static const st_lattice_data_5x8_t lf_ascii_5x8[] = {{" ",{0x00,0x00,0x00,0x00,0x00}}, /* " ",0x20 */
{"!",{0x00,0x00,0xBE,0x00,0x00}}, /* "!",0x21 */
... /* 略 */ ...
};// 注意上赋值字符串,不能赋值字符,不然中文字符判断不对.其它尺寸的结构体依次定义即可.
【屏幕模块 - 笔记】深圳市晶联讯电子 液晶模块 JLX19296G-915-BN相关推荐
- 晶联讯JLX12864G-086-PC-3S LCD显示屏 C51驱动代码
晶联讯JLX12864G-086-PC-3S LCD显示屏 C51驱动代码 //7.1.2 例程:以下为串行方式显示汉字及 ASCII 字符的例程: //液晶屏型号:JLX12864G-086-PC- ...
- 微信又有大更新!新增多款铃声、腾讯电子签等功能
7月14日,微信更新了8.0.8正式版. 本次更新,微信终于带来了大家一直以来呼声很高的功能--可以自主选择的消息提示音. 在最新版本微信中,用户可以自主更换新消息提示音和视频通话的来电铃声了. 目前 ...
- web开发权威,一个合格的初级前端工程师需要掌握的模块笔记
学习路线 第一阶段:网页制作 HTML:常用标签,锚点,列表标签,表单标签,表格标签,标签分类,标签语义化,注释,字符实体 CSS:CSS介绍,全局样式,行内样式,内联样式,选择器,字体样式值,文本样 ...
- 初学前端,学习路线图必不可少,更有【95页】初级前端模块笔记!
前言 在初学前端的时候,我们总会遇到一些问题,我们可以在网上看到很多关于前端的这些问题: 你们都是怎么学web前端的? 零基础,怎么自学好前端? 前端需要学多久,都学哪些知识? 想成为一名合格的前端工 ...
- 深圳市区块链电子发票系统累计开票超5800万张
8月10日,区块链电子发票迎来在深圳落地三周年.三年来,国家税务总局深圳市税务局不断深化区块链电子发票的应用推广,实现了"交易即开票.全信息上链.全流程打通",提升了税收管理服务科 ...
- 一个合格的初级前端工程师需要掌握的模块笔记
一个合格的初级前端工程师需要掌握的模块笔记 文章目录 一个合格的初级前端工程师需要掌握的模块笔记 前言 Web模块 html基本结构 标签属性 事件属性 文本标签 多媒体标签 列表 表格 表单标签 其 ...
- 微信推出“腾讯电子签”具有提醒对方还钱
有没有过这种尴尬,借人钱之后,不好意思开口要回来.别急,试试这个催收不用自己来.其实是一个名为[腾讯电子签]的小程序,主要用于管理各种收据.双方签订租房合同等等.据说,这个功能在朋友间借款的时候,特别 ...
- arduino使用晶联讯jlx12864
arduino使用晶联讯jlx12864 1.说明 我买的是JLX12864G-086,IC为UC1701X(看商品详情).其实之前就买过他家的大尺寸液晶屏,但当时就不会用导致浪费了几十块(试过了u8 ...
- 深圳市晶光华电子有限公司 - 晶振选型的四个重要参数是什么?
文章目录 参考 晶振,全称晶体振荡器,它能够产生中央处理器(CPU)执行指令所必须要的时钟频率信号,CPU 一切指令的执行都是建立在这个基础上的,时钟信号频率越高,通常 CPU 的运行速度也就越快. ...
最新文章
- 【STM32】输入捕获程序
- 切割固定长度字符串的方法_木质踢脚线安装的施工方法
- GMQ集团推出全球创新型金融衍生品交易平台
- linux prc 时区,授时时区问题解决
- 3个多月,近3000人参与的源码共读,诚邀加入~
- C++primer 第 3 章 字符串、向量和数组 3 . 3 标准库类型vector
- css文字溢出部分在另一个div显示(代码篇)
- SubSonic的配置及运用
- MATLABnbsp;std()nbsp;标准偏差函数
- java计算机毕业设计商品货物信息管理系统源码+系统+数据库+lw文档+mybatis+运行部署
- 远程控制计算机无法粘贴,Windwos服务器远程桌面不能复制粘贴的解决方法
- 论文导读|《Exploiting Rich Syntactic Information for Semantic Parsing with Graph-to-Sequence Model》
- mysql原理(1) mysql底层数据结构
- 【前端换肤】前端换肤方案
- PerfLib 2.0 计数器 removal 失败,退出代码为 2。命令行: C:\Windows\system32\unlodctr.exe /m:hkengperfctr.xml
- Python金融大数据分析——第11章 统计学(1)正态性检验 笔记
- 一个隐藏文件夹的方法
- Exp2 后门原理与实践 20164321 王君陶
- 国标流媒体服务器可以接入海康摄像头吗?是否会有断流问题?
- 腾讯QQ登录服务器域名IP地址端口列表
热门文章
- 统计建模与R软件 薛毅 陈立萍 清华大学出版社第四章课后答案
- zk - zookeeper主节点、从节点、客户端三者之间的交互
- android 带箭头提示框,三种带箭头提示框总结实例
- Java集成流行的打印插件lodop
- Bootstrap【第二章】全局CSS之排版代码表格
- influxdb连续查询
- WiFi-ESP8266入门http(3-3)网页认证上网-post请求-ESP8266程序
- wlan网页登录认证原理
- PPT制作技巧汇总之图形对象与多媒体应用(office 2007)
- 2019考研 | 天津大学计算机专硕复试131.25分考研经历与经验总结(复试)