打印
[STM32F1]

STM32F103点亮6800时序12864点阵液晶屏

[复制链接]
366|19
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
前言

由于公司原液晶产品芯片停产,领导研究决定更换液晶产品芯片为STM32F103ZET6。作为一名刚毕业参加工作的研发人员,领导把这个项目的软件研发任务交给我。对我来说这是一项富有挑战的任务,也感谢领导的信任。所以点亮12864液晶屏作为我进入公司研发参与的第一个项目的一个重要环节。
攻克STM32技术手册

由于之前对STM32系列芯片基本没有接触,首先使用野火的开发板对STM32的例程进行学习。通过例程和技术手册,对这款芯片的基本操作有了一定的基础。当然在这里要提到的是,看技术手册一定要结合例程。STM32有自己的固件库,我们在适用固件库操作板件的同时最好找到固件库函数源码,再结合技术手册研究一下这个固件库函数是怎么实现的。这不仅能快速的让你掌握技术手册的精髓,而且还能让你在硬件功能的调试上事半功倍,俗话说知己知彼百战不殆嘛!

使用特权

评论回复
评论
个百zz分点个 2023-3-29 16:33 回复TA
———————————————— 版权声明:本文为CSDN博主「DemandStorm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_44703307/article/details/103852442 
沙发
个百zz分点个|  楼主 | 2023-3-29 16:33 | 只看该作者
攻克12864液晶屏硬件操作基础

由于这个项目的硬件和软件是分开的,我起初对硬件原理也不是太关注,直到我开始操作液晶屏才发现写驱动的一定也要对硬件的接线以及基本原理很了解。
还有一点就是我使用的这个12864液晶屏,是利用四个片选信号选择左边显示和右边显示。具体的硬件引脚如图所示:



本液晶是6800时序操作,有四个片选信号只支持串行通信。

使用特权

评论回复
板凳
个百zz分点个|  楼主 | 2023-3-29 16:34 | 只看该作者
片选信号

12864液晶屏是由两个64*64的正方形液晶屏拼成,内部有左边和右边两个显存芯片。所以需要有片选信号来选择左边显示和右边显示。由表可知片选信号有四个:CSA,CSB,CS1,CS2。
1、选择左边:CS1高电平、CSA低电平
2、选择右边:CS2高电平、CSB低电平
我看其他的12864液晶,基本都是两个片选信号,一个高电平选择左边,一个高电平选择右边。这款液晶四个片选的操作,我也是很不解。还有一个比较重要的是我们选择左右的时候一次只能选择一个,选完之后就要把CSA和CS1重新置回原电平。如果误操作同时选两边会导致一个也选不上。片选部分代码如下:
void Lcd_Write_Data_Left(uint8  data)
{
    LCD_CS_LEFT();//选择左片液晶
    LCM_WrData(data);//写数据
    DelayZ(50);
    LCD_CS_LEFTOUT();//退出选择左片液晶
}
void Lcd_Write_Data_Right(uint8  data)
{
    LCD_CS_RIGHT();//选择右片液晶
    LCM_WrData(data);//写数据
    DelayZ(50);
    LCD_CS_RIGHTOUT();//退出选择右片液晶
}
void Lcd_Write_Com_Left(uint8  command)
{
    LCD_CS_LEFT();
    LCM_WrCommand(command);//写命令
    DelayZ(50);
    LCD_CS_LEFTOUT();
}
void Lcd_Write_Com_Right(uint8  command)
{
    LCD_CS_RIGHT();
    LCM_WrCommand(command); //写命令
    DelayZ(50);
    LCD_CS_RIGHTOUT();
}

使用特权

评论回复
地板
个百zz分点个|  楼主 | 2023-3-29 16:34 | 只看该作者
这里的代码中LCD_CS_LEFT()函数封装的就是CSA高电平、CS1低电平的操作。而写数据和写命令的操作也是通过STM32的IO口操作以及配合液晶的写数据寄存器写命令寄存器控制的。具体操作参照下节。

使用特权

评论回复
5
个百zz分点个|  楼主 | 2023-3-29 16:34 | 只看该作者
写命令写数据

要想使液晶点亮,选完左边右边后,写命令和写数据才是最重要的步骤。假如我们事先约定只使用左半片液晶,我们选完左边的片选之后首先要对显存的控制寄存器下命令。具体的命令如下表。

使用特权

评论回复
6
个百zz分点个|  楼主 | 2023-3-29 16:35 | 只看该作者
初次接触此类液晶的朋友可能对此表还不是太能看懂,我在这里解释一下。大致分为三个功能:写命令、写数据、读状态。
这三各功能由RS和R/W两个引脚控制。
写命令 RS:0 R/W:0
写数据 RS:1 R/W:0
读状态 RS:1 R/W:1

使用特权

评论回复
7
个百zz分点个|  楼主 | 2023-3-29 16:40 | 只看该作者
控制命令分为四个作用:
(1)开启显示:0X3F
(2)选择起始行:0XC0
(3)选择起始列:0X40
(4)选择起始页:0XB8(这里的页下面会有说明)

使用特权

评论回复
8
个百zz分点个|  楼主 | 2023-3-29 16:40 | 只看该作者
写数据就相对简单,一字节的数据控制点阵的八个点,通过命令寄存器规定完从何处开始控制这八个点之后,就可以通过字节操作一次控制八个点。注意这八个点是竖向的和页的控制操作也息息相关。

使用特权

评论回复
9
个百zz分点个|  楼主 | 2023-3-29 16:41 | 只看该作者
关于页的说明:
由于一次竖向控制八个点,一片有64行点,所以把显示片分为八页具体如图:

使用特权

评论回复
10
个百zz分点个|  楼主 | 2023-3-29 16:41 | 只看该作者
附上写命令和写数据的代码:
void LCM_WrCommand(uint8 CmdData)
{
LCD_RS_0();
LCD_RW_0();
gpio_write(CmdData);    //D0~D7
LCD_E_1();
DelayZ(50);
LCD_E_0();
}

使用特权

评论回复
11
个百zz分点个|  楼主 | 2023-3-29 16:41 | 只看该作者
写数据代码:
void LCM_Wrdata(uint8 Data)
{
  LCD_RS_1();
  LCD_RW_0();
  gpio_write(Data);
  LCD_E_1();
  DelayZ(50);
  LCD_E_0();
}

使用特权

评论回复
12
个百zz分点个|  楼主 | 2023-3-29 16:42 | 只看该作者
这里需要注意的是,使能信号E是下降沿使能,要放在写命令和数据的后面。这时候有同学就有疑问了,放到后面怎么使能。原理是这样的,写命令和数据实际就是通过控制STM32的IO口输出高低电平,我们程序执行过gpio_write()这个函数后,输出电平就已经是我们想要的电平了。但这时我们的液晶显存还不能识别,当我们设置E使能信号为下降沿时,已经输出的电平就被我们的显存识别了,从而执行相应的操作。

使用特权

评论回复
13
个百zz分点个|  楼主 | 2023-3-29 16:42 | 只看该作者
液晶显示

具体的显示函数代码如下:
void Lcd_Display_Executive(void)
{
    unsigned value;
    unsigned char *mem_offset,page,column,counter=0;
    extern unsigned char gui_disp_buf[8][128];
    Lcd_Write_Com_Left(0xc0);
    Lcd_Write_Com_Right(0xc0);
    Lcd_Write_Com_Left(0x3f);
    Lcd_Write_Com_Right(0x3f);/* 初始化液晶,开启显示设置起始行*/
    for(page=0;page<8;page++)
    {   
        Lcd_Write_Com_Left(page|0xb8);     
        Lcd_Write_Com_Right(page|0xb8);/* 设置起始页*/
        Lcd_Write_Com_Left(0x40);
        Lcd_Write_Com_Right(0x40);/* 设置起始列*/
        for(column=0;column<128;column++)
        {   
            mem_offset = (unsigned char*)gui_disp_buf + page*128 + column;
            value = *(mem_offset);/*利用指针读取二维数组中的值*/
            if(column>=64)
            {               
                      Lcd_Write_Data_Right(value);                        
            }
            else
            {
               Lcd_Write_Data_Left(value);         
            }
        }
        counter++;
    }
}

使用特权

评论回复
14
个百zz分点个|  楼主 | 2023-3-29 16:42 | 只看该作者
这个显示函数可以扫描到液晶的每一个点,要想控制每个点的显示就需要我们改变gui_disp_buf[8][128]这个二维数组里面的值。假如我们想让左上角第一个点亮,我们就可以把gui_disp_buf[0][0]的值设为0X01,这样左上角的第一个点就亮了。把液晶画成坐标,横向x最大为128,纵向最大为64,原点为左上角00,坐标为绝对值。如果gui_disp_buf[0][0]的值为0XFF这时候亮的就是最横坐标0,纵坐标0到7。因为一个字节控制八个点。

使用特权

评论回复
15
个百zz分点个|  楼主 | 2023-3-29 16:42 | 只看该作者
通过改变二维数组的值我们就可以操作液晶的每一个点,这样我们就可以编写对应的UI函数,比如画点画线。只要我们画出一个点,我们就可以对应的画线,画各种形状。
部分代码如下:
void GUI_Point(uint8 x,uint8 y,uint8 data)
{
    x = x&0x7f;    // 参数过滤最大127
    y = y&0x3f;    // 参数过滤最大63
    y= y>>3;
    gui_disp_buf[y][x] = data;
}

使用特权

评论回复
16
个百zz分点个|  楼主 | 2023-3-29 16:43 | 只看该作者
以此为基础就可以画各种图形。

使用特权

评论回复
17
个百zz分点个|  楼主 | 2023-3-29 16:43 | 只看该作者
效果展示

使用特权

评论回复
18
个百zz分点个|  楼主 | 2023-3-29 16:43 | 只看该作者
总结

12864的液晶虽然比较落后,但是对于液晶显示这方面知识,选择它简单易上手。这种点阵显示的液晶屏可以帮我们快速理解液晶显示的原理,我们以后假如接触有色的液晶时也更容易上手。
液晶其实只是显示的一种手段,但我们真正要显示一些什么数据,通过显示按键要想操控一些东西,光有显示是远远不够的。我们与显示紧密结合的就是通讯,有了通讯,才能让显示屏知道我们想要显示什么数据。
而我接下来的工作就是要调试串口通讯,通过固定的规约报文与主板建立数据互传。在写这篇博客时,我负责的这个项目的软件功能基本已经完成。通过写博客回忆整理在项目中学到的知识,也是一种不错的途径。希望与大家共同进步!

使用特权

评论回复
19
jiahy| | 2023-3-29 18:50 | 只看该作者
四个片选呢啊

使用特权

评论回复
20
Clyde011| | 2024-1-27 08:24 | 只看该作者

可能还需要进行一些额外的测试

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

50

主题

631

帖子

0

粉丝