我用的主控是STM32F103ZET6
程序里面有两种发法:一个是并行发送数据,另一个是串行发送数据
完整工程链接:12864完整驱动工程
12864学习资料和取模软件链接:12864学习资料和取模软件
程序运行效果图:
1.并行发送数据效果图
2.串行发送数据效果图
程序如下:
#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);
}
#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
}
#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);
文章浏览阅读1.1k次,点赞25次,收藏29次。汽车动力性概括来讲,是指汽车在良好路面上直线行驶时,由汽车受到的纵向外力决定、所能达到的平均行驶速度。通常用最高车速、爬坡能力、加速时间表征。_真simulink车辆仿真基础教程
文章浏览阅读2.4k次,点赞2次,收藏12次。Swagger2引入、Spring-Swagger2整合、Swagger2常用注解与插件_swagger2
文章浏览阅读881次。一、什么是JVMJVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java_jvm原理及性能调优
文章浏览阅读804次。社交网络分析重要概念简介、相关资料和前沿研究_social network的bei 和ei
文章浏览阅读140次。version 0.1 版本还存在一些BUG,采用sqlite数据库做为测试关于推送部分大家可以在pypi搜索anps 下载安装apnsclient 测试###通用部分提交length = json整体包长action = 协议关键字部分提交部分提交 uid ,为了使协议通用语web环境返回status = 状态成功失败errcode = 错误代码,需要具体定义common1000010001 ..._python tornado tcp 聊天
文章浏览阅读1.6k次。1. 问题: conda search numpy 以及 conda search --full-name python 失败。失败的现象:Loading channels: failedCondaHTTPError: HTTP 404 NOT FOUND for url <http://pypi.douban.com/simple/noarch/repodata.json>..._loading channels: failed
文章浏览阅读8.3k次,点赞6次,收藏80次。Python科学计算基础库:Numpy,Pandas,Scipy,Matplotlib1.NumPy支持大量的维度数组与矩阵运算,此外也针对数组运算提供大量的数学函数库,线性代数,傅里叶变换和随机数功能底层使用C语言编写,内部解除了GIL(全局解释器锁),其对数组的操作速度不受Python解释器的限制,效率远高于纯Python代码。2.PandasPandas是一个强大的基于Numpy分析结构化数据的工具集;Pandas 可以从各种文件格式比如 CSV、JSON、SQL、Micros_python常用库介绍
文章浏览阅读5.9w次,点赞150次,收藏1.4k次。利用conda指令搭建Pytorch环境,并在Pytorch环境中安装GPU版Pytorch相关包。_anaconda创建pytorch环境
文章浏览阅读955次,点赞12次,收藏32次。有时我们在磁盘规划前会想要确定一下当前系统的文件系统或磁盘分区情况。这时,就有几个命令可以供选择,通过本文,可以学习这些命令的使用。_lsblk
文章浏览阅读5.7k次,点赞11次,收藏46次。结论!!!学生类当中虽然没有构造方法 但是测试代码当中Student对象也创建完成了。是因为当类中没有任何构造方法的时候系统默认构造一个无参数的构造方法构造方法和普通方法结构的区别如下:调用构造方法怎么调用呢?..._构造方法和普通方法之间的区别
文章浏览阅读199次。全文链接:http://tecdat.cn/?p=23378在本文中,我们将使用基因表达数据。这个数据集包含120个样本的200个基因的基因表达数据。这些数据来源于哺乳动物眼组织样本的微阵列实验(点击文末“阅读原文”获取完整代码数据)。相关视频1 介绍在本文中,我们将研究以下主题证明为什么低维预测模型在高维中会失败。进行主成分回归(PCR)。使用glmnet()进行岭回归、lasso 和弹性网el..._高维数据回归方法
文章浏览阅读419次,点赞16次,收藏3次。此外,中科数安防泄密软件还具有智能加密功能,可以识别散落在企业不同位置的机密文件,并对其强制加密,非核心数据不被过分加密,防止敏感内容泄漏。同时,它还支持离网办公,针对出差人员或网络故障等原因引起的客户端离网,用户可以发起离网审批,确保终端密文在出差过程中保持可用状态,不影响正常办公。它采用了多种加密机制和技术手段,确保企业数据的安全性、完整性和机密性。总之,中科数安防泄密软件是一种功能强大、技术先进的企业数据保护软件,可以有效地防止敏感数据的泄露和非法访问,保障企业的信息安全和业务连续性。