STM32——库函数版——12864点阵显示屏驱动_stm32驱动12864-程序员宅基地

技术标签: stm32  STM32学习之路  

12864点阵显示屏驱动

我用的主控是STM32F103ZET6

程序里面有两种发法:一个是并行发送数据,另一个是串行发送数据

完整工程链接:12864完整驱动工程
12864学习资料和取模软件链接:12864学习资料和取模软件

引脚连接看led12864.h里面的设置

程序运行效果图:

1.并行发送数据效果图
在这里插入图片描述

2.串行发送数据效果图
在这里插入图片描述

程序如下:

main.c

#include "sys.h"
#include "delay.h"
#include "led12864.h"

/*2020.11.20*/

unsigned char defchar[] = {
    0x00,0x40,0x78,0x40,0x48,0x44,0x57,
0xFE,0x50,0x80,0x60,0xA0,0x51,0x20,
0x4A,0x28,0x4B,0xFC,0x48,0x20,0x69,
0x28,0x51,0x24,0x42,0x26,0x44,0x22,
0x40,0xA0,0x40,0x40};    //自定义字符数组,这里是陈

int main(void)
{
     

	RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);	//系统时钟设置PLL作为系统时钟
	delay_init();
	
	lcd12864_Pin_Init();  //引脚初始化共用
/*-----------并行发送数据------------------*/
//	LED_Init();          //led12864并行初始化
//	delay_ms(20);

	//任意位置显示字符串(写DDRAM中的数据)
//	display_DDRAM(0,0,"人之出,性本善。苟不教,性乃迁。性相近,习相远,教之道,贵以专");

//	display_CGRAM(1,2,0x20,defchar);    //任意位置显示自定义字符串(写CGRAM中的数据)

	
/*-----------串行发送数据------------------*/
	Lcd_Init();       //led12864串行初始化
	delay_ms(10);
	LCD_Display_Words(0,0,"怕什么天道轮回");
/*-------------------------------------*/	

	
	
	while(1);
		
		
	

}

led12864.c

#include "led12864.h"
#include "delay.h"

/***************************************************************************************
* 2020.11.20
* LED12864模块
* 管脚号  	管脚名称        	LEVER	         管脚功能描述
*  1	        VSS	          0	            电源地
*  2	        VDD	        +5.0V	          电源电压
*  3	        V0	          -	            液晶显示器驱动电压
*  4	        D/I(RS)    	H/L	            D/I=“H”    表示DB7∽DB0为显示数据
*                                         D/I=“L”        表示DB7∽DB0为显示指令数据
*  5	        R/W(SID)    H/L	            R/W=“H”,E=“H”数据被读到DB7∽DB0
*                                         R/W=“L”,E=“H→L”数据被写到IR或DR
*  6	        E(CLK)	    H/L	            R/W=“L”,E信号下降沿锁存DB7∽DB0
*                                         R/W=“H”,E=“H”DDRAM数据读到DB7∽DB0
*  7	        DB0	        H/L	            数据线
*  8	        DB1        	H/L	            数据线
*  9	        DB2	        H/L           	数据线
*  10	        DB3	        H/L            	数据线
*  11       	DB4       	H/L            	数据线
*  12	        DB5	        H/L	            数据线
*  13       	DB6	        H/L	            数据线
*  14        	DB7	        H/L	            数据线
*  15	        PSB(CS1)    H/L	            并/串行接口选择:H-并行 L-串行
*  16	        NC(CS2)	     	              空脚
*  17	        RST       	H/L	            复位信号,低电平复位
*  18	        VOUT	     -10V            	LCD驱动负电压
*  19	        LED+	      +              	LED背光板电源
*  20	        LED-	      -	              LED背光板电源
*********************************************************************************************/



/**************************************************
* 函数功能  : 引脚初始化
**************************************************/
void lcd12864_Pin_Init(void)
{
    
	GPIO_InitTypeDef  GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOD, ENABLE);	 //使能GPIOD/GPIOA端口时钟
	//数据/命令选择
	//读/写选择rw	
	//使能信号en
	//复位rst
	GPIO_InitStructure.GPIO_Pin  = RS|RW|E|RST;    
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;  //最高输出速率50MHz	
	GPIO_Init(GPIOA, &GPIO_InitStructure);  //IO口初始化
	
	//数据引脚
	GPIO_InitStructure.GPIO_Pin  = LCD_DATA;    
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;  //最高输出速率50MHz	
	GPIO_Init(GPIOD, &GPIO_InitStructure);  //IO口初始化

}

/*************************************************
* 函数功能 : LED12864数据口引脚配置为输出模式
**************************************************/
void LED12864_DB_outputMode(void)
{
    
	GPIO_InitTypeDef  GPIO_InitStructure;
	//数据引脚
	GPIO_InitStructure.GPIO_Pin  = LCD_DATA;    
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出
	GPIO_InitStructure.GPIO_Speed= GPIO_Speed_50MHz;  //最高输出速率50MHz	
	GPIO_Init(GPIOD, &GPIO_InitStructure);  //IO口初始化


}

/*************************************************
* 函数功能 : LED12864数据口引脚配置为上拉输入模式
**************************************************/
void LED12864_DB_inputMode(void)
{
    
	GPIO_InitTypeDef  GPIO_InitStructure;
	//数据引脚
	GPIO_InitStructure.GPIO_Pin  = LCD_DATA;    
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;  //推挽输出
	GPIO_Init(GPIOD, &GPIO_InitStructure);  //IO口初始化


}

/*************************************************
* 函数功能 : 写数据/命令
**************************************************/
void write_LCD12864_DB(uint8_t data)
{
    
	GPIO_Write(GPIOD,data);
}

//
/*************************************************
* 函数功能 : 读DB0-7的数据
**************************************************/
uint8_t read_LCD12864_DB(void)
{
    
	uint8_t value;
	value=GPIO_ReadInputData(GPIOD);
	return value;
}

/*************************************************
* 函数功能 : DB7引脚  忙信号检测
**************************************************/
void LCD_ReadyWait(void)
{
    
	uint8_t state;
	
	delay_ms(10);
	GPIO_WriteBit(GPIOA,RS,Bit_RESET);  //写指令  RS=0
	GPIO_WriteBit(GPIOA,RW,Bit_SET);  //写操作  R/W=1
	do
	{
    
		GPIO_WriteBit(GPIOA,E,Bit_SET);    //使能    E=1
		LED12864_DB_inputMode();     //配置数据口为上拉输入模式	
		state =read_LCD12864_DB();   //查忙标志位,等待标志位为0,表示写入完毕;为1,表示忙状态	
		LED12864_DB_outputMode();    	//配置数据口为输出模式
		GPIO_WriteBit(GPIOA,E,Bit_RESET);    //不使能    E=0
	}	while( state & 0x80);  
	
}

/*************************************************
* 函数功能 : 向LCD12864写入命令
* 函数参数 :com写入的命令
**************************************************/
void LCD_Write_com(uchar com)
{
    
	delay_ms(5);
	LCD_ReadyWait();
	delay_ms(10);
	GPIO_WriteBit(GPIOA,RS,Bit_RESET);  //写指令  RS=0
	GPIO_WriteBit(GPIOA,RW,Bit_RESET);  //写操作  R/W=0
	GPIO_WriteBit(GPIOA,E,Bit_SET);    //使能    E=高电平
	write_LCD12864_DB(com);              //写命令
	GPIO_WriteBit(GPIOA,E,Bit_RESET);    //不使能
	


}

/*************************************************
* 函数功能 : 向LCD12864写入数据
* 函数参数 :data写入的数据
**************************************************/
void LCD_Write_data(uchar data)
{
    
	delay_ms(10);
	GPIO_WriteBit(GPIOA,RS,Bit_SET);  //写数据   RS=1
	GPIO_WriteBit(GPIOA,RW,Bit_RESET);  //写操作 R/W=0
	GPIO_WriteBit(GPIOA,E,Bit_SET);    //使能   E=高电平
	write_LCD12864_DB(data);            //写数据
	GPIO_WriteBit(GPIOA,E,Bit_RESET);    //不使能
}

/*************************************************
* 函数功能 : 清屏
*************************************************/
void LCD_clear(void)
{
    
	LCD_Write_com(0x01);    //写清屏指令0x01  
  delay_ms(10);
}

/*************************************************
* 函数功能 : 任意位置显示字符串(写DDRAM中的数据)
* 函数参数 :x第几列,y第几行,s输入的数据
*************************************************/
void display_DDRAM(uchar x,uchar y,uchar *s)
{
    
	switch(y)
	{
    
		case 0:  
			LCD_Write_com(0x80+x);     //第一行
		break;
		case 1:  
			LCD_Write_com(0x90+x);     //第二行
		break;
		case 2:  
			LCD_Write_com(0x88+x);     //第三行
		break;
		case 3:  
			LCD_Write_com(0x98+x);     //第四行
		break;	
	}
	while(*s>0)
	{
    
		LCD_Write_data(*s++);
		delay_ms(10);	
	}
}

//unsigned char defchar[] = {0x09,0x00,0xFD,0x08,0x09,0x08,0x09,
//0x10,0x09,0x20,0x79,0x40,0x41,0x04,
//0x47,0xFE,0x41,0x40,0x79,0x40,0x09,
//0x20,0x09,0x20,0x09,0x10,0x09,0x4E,
//0x51,0x84,0x21,0x00};    //自定义字符数组,这里是张
 

/*************************************************
* 函数功能 : 任意位置显示自定义字符串(写CGRAM中的数据)
* 函数参数 :x第几列,y第几行,addr 自编字符编码首地址,s输入的数据
* 声明     :12864具有4个自编字符,每个字符编码为0000H,0002H,0004H,0006H,4个自定义字符	
* CGRAM地址分别为00H~0FH、10H~1FH、20H~2FH、30H~3FH
*************************************************/
void display_CGRAM(uchar y,uchar x,uchar addr,uchar *s)
{
    
	unsigned char i,*address;
	address = s;   
	LCD_Write_com(0x40+addr);    //写CGRAM首行地址,创建第几个自编字符就写第几个自编字符的地址
	for(i = 0;i<32;i++)
	{
    
		LCD_Write_data(*address++);
	}
	switch(y)
	{
    
		case 0:  
			LCD_Write_com(0x80+x);     //第一行
		break;
		case 1:  
			LCD_Write_com(0x90+x);    //第二行
		break;
		case 2:  
			LCD_Write_com(0x88+x);    //第三行
		break;
		case 3:  
			LCD_Write_com(0x98+x);   //第四行
		break;	
	}
	LCD_Write_data(0x00);     //写自定义字符编码的高字节
	
	switch(addr)
	{
    
		case 0x00:  
			LCD_Write_data(0x00);	   //写第一个自定义字符编码的低字节
		break;
		case 0x10:  
			LCD_Write_data(0x02);     //写第二个自定义字符编码的低字节
		break;
		case 0x20:  
			LCD_Write_data(0x04);     //写第三个自定义字符编码的低字节
		break;
		case 0x30:  
			LCD_Write_data(0x06);     //写第四个自定义字符编码的低字节
		break;	
	}
}


//led12864并行初始化
void LED_Init(void)
{
    
	GPIO_WriteBit(GPIOA,RST,Bit_SET);    //复位置高
	delay_ms(10);	
	GPIO_WriteBit(GPIOA,RST,Bit_RESET);  //复位
	delay_ms(10);	
	GPIO_WriteBit(GPIOA,RST,Bit_SET);    //复位结束
	delay_ms(10);	
	
	LCD_Write_com(0x30);    //设置为基本指令集动作
	delay_ms(10);
	LCD_Write_com(0x08);    //设置显示、光标、闪烁全关。
	
	LCD_Write_com(0x01);      //清屏,并且DDRAM数据指针清零
	LCD_Write_com(0x06);      //进入模式设置
	LCD_Write_com(0x0c);      //开显示
	delay_ms(10);	

}


/*----------------------------------12864串行发送数据----------------------------------------------------*/
/*
* PSB引脚接低,串行模式
* RS引脚,拉高数据才能发送
*/
/*---------串行----------------*/
/* 字符显示RAM地址4行8列 */
uint8_t LCD_addr[4][8]={
    
	{
    0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87},  	//第一行
	{
    0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97},		//第二行
	{
    0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F},		//第三行
	{
    0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F}		//第四行
	};

//led串行发送一个字节
void SendByte(u8 byte)
{
    
	u8 i;
	for(i = 0; i< 8; i++)
	{
    
		if((byte <<i)&0x80)
		{
    
			GPIO_WriteBit(GPIOA,RW,Bit_SET);  //读操作 R/W=1
		}
		else
		{
    
			GPIO_WriteBit(GPIOA,RW,Bit_RESET);  //写操作 R/W=0		
		}
	GPIO_WriteBit(GPIOA,E,Bit_RESET);    //不使能
	delay_us(5); //延时使数据写入
	GPIO_WriteBit(GPIOA,E,Bit_SET);    //使能	
	}
}

//写命令
void Lcd_WriteCmd(u8 Cmd )
{
    
     delay_ms(1);         //由于我们没有写LCD正忙的检测,所以直接延时1ms,使每次写入数据或指令间隔大于1ms 便可不用写忙状态检测
     SendByte(WRITE_CMD);  //11111,RW(0),RS(0),0   
     SendByte(0xf0&Cmd);   //高四位
     SendByte(Cmd<<4);     //低四位(先执行<<)
}

//写数据
void Lcd_WriteData(u8 Dat )
{
    
     delay_ms(1);             //由于我们没有写LCD正忙的检测,所以直接延时1ms,使每次写入数据或指令间隔大于1ms 便可不用写忙状态检测
     SendByte(WRITE_DAT);      //11111,RW(0),RS(1),0
     SendByte(0xf0&Dat);       //高四位
     SendByte(Dat<<4);         //低四位(先执行<<)
}

//清屏
void LCD_Clear(void)
{
    
	Lcd_WriteCmd(0x01);	//清屏指令
	delay_ms(2);				//延时以待液晶稳定【至少1.6ms】
}
	
/*********************************************************** 
 *  函数功能 :  显示字符或汉字
 *  参数     : x: row(0~3)
 *              y: line(0~7) 
 *       	      str: 要显示的字符或汉字
 ***********************************************************/
void LCD_Display_Words(uint8_t x,uint8_t y,uint8_t*str)
{
     
	Lcd_WriteCmd(LCD_addr[x][y]); //写初始光标位置
	while(*str>0)
    {
     
      Lcd_WriteData(*str);      //写数据
      str++;     
    }
}
/*
* led12864串行初始化
*/
void Lcd_Init(void)
{
     
	GPIO_WriteBit(GPIOA,RST,Bit_SET);    //复位置高
	delay_ms(10);	
	GPIO_WriteBit(GPIOA,RST,Bit_RESET);  //复位
	delay_ms(10);	
	GPIO_WriteBit(GPIOA,RST,Bit_SET);    //复位结束
	delay_ms(10);
    
	delay_ms(50);   	//等待液晶自检(延时>40ms)
	Lcd_WriteCmd(0x30);        //功能设定:选择基本指令集  ,选择8bit数据流
  delay_ms(1);//延时>137us 
  Lcd_WriteCmd(0x0c);        //开显示
  delay_ms(1);	//延时>100us
  Lcd_WriteCmd(0x01);        //清除显示,并且设定地址指针为00H
  delay_ms(30);	//延时>10ms
	Lcd_WriteCmd(0x06);        //每次地址自动+1,初始化完成
	LCD_Clear();
	delay_ms(30);	//延时>10ms
}

led12864.h

#include "sys.h"

/*----------------------------------12864并行发送----------------------------------------------------*/
#define RS GPIO_Pin_0   //数据/命令选择
#define RW GPIO_Pin_1   //读/写选择
#define E GPIO_Pin_2    //使能信号
#define RST GPIO_Pin_3    //复位引脚

#define LCD_DATA GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7  //数据线

#define uchar unsigned char
	
//引脚初始化
void lcd12864_Pin_Init(void);
//DB7引脚  忙信号检测
void LCD_ReadyWait(void);
//向LCD12864写入命令
void LCD_Write_com(uchar com);
//向LCD12864写入数据
void LCD_Write_data(uchar data); 
//清屏
void LCD_clear(void);
//led12864并初始化
void LED_Init(void);

//任意位置显示字符串(写DDRAM中的数据)
void display_DDRAM(uchar x,uchar y,uchar *s);
//任意位置显示自定义字符串(写CGRAM中的数据)
void display_CGRAM(uchar y,uchar x,uchar addr,uchar *s);

/*----------------------------------12864串行发送----------------------------------------------------*/

#define WRITE_CMD	0xF8//写命令  
#define WRITE_DAT	0xFA//写数据

/*
* PSB引脚接低,串行模式
* RS引脚,拉高数据才能发送
*/
//RW引脚为PA1,E引脚为PA2

//清屏
void LCD_Clear(void);
//led串行发送一个字节
void SendByte(u8 byte);
//写命令
void Lcd_WriteCmd(u8 Cmd );
//写数据
void Lcd_WriteData(u8 Dat );
//显示字符或汉字
void LCD_Display_Words(uint8_t x,uint8_t y,uint8_t*str);
//led12864串行初始化
void Lcd_Init(void);






版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_45844792/article/details/117124707

智能推荐

coursera-斯坦福-机器学习-吴恩达-第8周笔记-无监督学习_pca反向压缩-程序员宅基地

文章浏览阅读6k次,点赞3次,收藏15次。coursera-斯坦福-机器学习-吴恩达-第8周笔记-无监督学习coursera-斯坦福-机器学习-吴恩达-第8周笔记-无监督学习1聚类算法clutering1聚类算法简介2K-means21kmeans的目标函数22随机初始化23选择类别数3考试quiz维数约减 dimensionality reduction1数据压缩2数据可视化3维度约简-主成分分析法PCA1 PCA_pca反向压缩

vim插件安装及常用技巧_bxbx.vim-程序员宅基地

文章浏览阅读5.2k次。一、插件安装Vundle是vim的一个插件管理器, 同时它本身也是vim的一个插件。插件管理器用于方便、快速的安装、删除、Vim更新插件。mkdir -p ~/.vim/bundlegit clone https://github.com/gmarik/Vundle.vim.git ~/.vim/bundle/Vundle.vim管理器安装完成后,vim ~/.vimrc命令创建.vimrc文件syntax on" tab宽度和缩进同样设置为4set tabstop=4set softta_bxbx.vim

java.lang.ClassNotFoundException:如何解决-程序员宅基地

文章浏览阅读7.2w次,点赞10次,收藏41次。本文适用于当前面临java.lang.ClassNotFoundException挑战的Java初学者。 它将为您提供此常见Java异常的概述,这是一个示例Java程序,可支持您的学习过程和解决策略。 如果您对与更高级的类加载器相关的问题感兴趣,我建议您复习有关java.lang.NoClassDefFoundError的文章系列,因为这些Java异常密切相关。 java.lang..._java.lang.classnotfoundexception:

串口通信数据帧_一帧数据-程序员宅基地

文章浏览阅读1.2k次,点赞9次,收藏17次。不同的设备间建立连接往往需要通信,而串口通信是十分常用的一种。UART串口通信需要两根线来实现,一根用于串口发送,另外一更用于串口接收。UART串口发送或者接收过程中一帧数据包括1位起始位、8位数据位、1位停止位,为了提高数据的可靠性可以在停止位前加上1位奇偶校验位。串口通信虽然十分简单,但是在不同设备间发送的数据往往不止1个字节,往往需要多个字节组成的数据包。当我们按照数据包发送时我们需要考虑到以及,因此我们可以采用定义数据帧的方式解决上述两个问题。_一帧数据

代码编辑快捷键使用说明_改代码快捷键-程序员宅基地

文章浏览阅读1.4k次。1、Ctrl+←或→ :跳过(左边或右边)一个光标相邻的单词或词组(标点符号相当于一个单词)。点击前光标位置:点击后光标位置:2、Shift+←或→:选中(左边或右边)一个光标相邻的字符。点击前显示:点击后显示: 3、Shift+Ctrl+←或→:选中(左边或右边)一个光标相邻的单词或词组(标点符号相当于一个单词)。点击前显示:点击后显示:4、Home/End:光标定位到当前行的行头/行尾。点击前:点击Home后:点击End后:5、Ctrl+Home/End:从光标所在位置直接回到当前文件开头/结尾。点击前_改代码快捷键

【课上笔记】第七章 树与森林_树和森林的区别-程序员宅基地

树是一个有n个有限数据元素的集合,其中有一个根节点,并且每个节点可以有多个子节点。树的深度与查找有关,可通过改进合并算法来减少树的深度,提高算法效率。

随便推点

看不见的“网” ,一文读懂阿里云基础设施网络_阿里云网络基线理解-程序员宅基地

文章浏览阅读553次。编者按:在这个万物智联的时代,无论是在线网络购物,还是网络强国、数字中国建设,都离不开一张“看不见的网”——基础设施网络。2009年,首届双11每秒交易订单创建峰值400;2021年,双11每秒交易订单创建峰值58.3万,12年交易数字量猛增的背后,是阿里云在庞大分布式系统上计算和IO能力的飞跃,更离不开阿里云基础设施底层网络技术的支撑。图|阿里云全球基础设施网络系统作为阿里云基础设施的重要组成部分,阿里云基础设施网络团队负责整个阿里云全球基础设施网络,包括大规模高性能数据中心网络,全球数据中心互联_阿里云网络基线理解

TCP/UDP常见端口参考_怎么查看端口映射的是tcp还是udp-程序员宅基地

文章浏览阅读1.7k次。端口列表一览端口号码 / 层 名称 注释 1 tcpmux TCP 端口服务多路复用 5 rje 远程作业入口 7 echo Echo 服务 9 discard 用于连接测试的空服务 11 systat 用于列举连接了的端口的系统状态 13 daytime 给请求主机发送日期和时间 17 qotd 给连接了的主机发送每日格言 18 msp 消息发送协议 19 _怎么查看端口映射的是tcp还是udp

android JSBridge 漏洞挖掘_adnroid jsbridge 不安全的资源引用-程序员宅基地

文章浏览阅读825次。一、概述1. JSBridge介绍什么是JSBridge主要是给 JavaScript 提供调用 Native 功能的接口,让混合开发中的前端部分可以方便地使用 Native 的功能(例如:地址位置、摄像头)。而且 JSBridge 的功能不止调用 Native 功能这么简单宽泛。实际上,JSBridge 就像其名称中的Bridge的意义一样,是 Native 和非 Native 之间的桥梁,它的核心是构建 Native 和非 Native 间消息通信的通道,而且这个通信的通道是双向的。双向通信的通_adnroid jsbridge 不安全的资源引用

OpenCV+Mediapipe+UDP+Unity挥手电子书翻页_unity opencv 虚拟翻书-程序员宅基地

文章浏览阅读2k次,点赞13次,收藏43次。OpenCV+Mediapipe+UDP+Unity挥手翻页_unity opencv 虚拟翻书

推荐文章

热门文章

相关标签