一前期准备 准备一个XY12864中文显示屏,有些屏幕是不带中文字库的,有些屏幕是带有中文字库,我选择的是ST7920中文驱动器 二绘制电路板 第一张就是基础的stm32最小系统图,USB转5v,然后转3.3v,图中还有DBT-18蓝牙模块,暂时没做处理,我加入蓝牙模块是为了发送数据, 这是xy12864屏幕引脚图和我使用STM32引脚控制的连接图,其中3号引脚V0是连接10k电位器 三ST7920使用 电源5v RS RW 功能说明 L L :MPU写指令到指令寄存器IR LH:读忙碌标志(BF)及地址计数器(AC)状态 HL:MPU写入资料到资料寄存器(DR) HH:MPU从资料寄存器(DR)中读出资料 而我只用到写数据和写资料, 引脚17,(REST)复位引脚,低电平有效 引脚15(PSB)串行/并行选择,高电位并行信号,低电位串行信号,我用的是并行指令输入 复位引脚我接入PA8,PSB引脚我接入PB11,两个引脚全拉高, 现在要考虑如何输入正确的指令给屏幕,首先看时序图, 有图可以看出,配置好指令的时候,需要将RE引脚拉高,延时输入指令,在拉低;写入指令的时序 比如清除指令,: RS/RW/DB7/DB6/DB5/DB4/DB3/DB2/DB1/DB0 0/0/0/0/0/0/0/0/0/1 程序里配置,先拉低RS和RW代表写入指令,在配置DB7-DB0的电位,(0低电位,1高电位),然后拉高RE,延时,在拉低RE,便能写入指令,写入数据也是同样操作,写完一个指令要留有一定的延时,给屏留时间接受指令并工作,清屏留的时间长,其他指令时间短一些; 四程序解析 #include “stm32f10x.h” #include “stm32f10x_flash.h” #include “stm32f10x_tim.h” #include “stm32f10x_usart.h” #include “stm32f10x_adc.h” #include “delay.h” int A1; int i7=0,i6=0,i5=0,i4=0,i3=0,i2=0,i1=0,i0=0,n=0,m=0; int B7,B6,B5,B4,B3,B2,B1,B0; void RCC_Configuration(void); void GPIO_Configuration(void); void Qidong(void); void Shangdian(void); void Xianshi(void); void FenJie(int A1); 制作函数分解DB7-DB0 void ZhiShi(int RSFlag);制作函数控制写入数据还是写入指令 void ShiNeng(int Sneng);制作函数控制使能写入 void TIM_Configuration(void); void NVIC_Configuration(void); int main() { delay_init(72); RCC_Configuration(); GPIO_Configuration(); GPIO_SetBits(GPIOA,GPIO_Pin_8); 置高复位引脚 GPIO_SetBits(GPIOB,GPIO_Pin_11); 置高选择8位并行
GPIO_ResetBits(GPIOA,GPIO_Pin_7); 拉低8位数据位
GPIO_ResetBits(GPIOA,GPIO_Pin_6); GPIO_ResetBits(GPIOA,GPIO_Pin_5); GPIO_ResetBits(GPIOA,GPIO_Pin_4); GPIO_ResetBits(GPIOA,GPIO_Pin_3); GPIO_ResetBits(GPIOA,GPIO_Pin_2); GPIO_ResetBits(GPIOA,GPIO_Pin_1); GPIO_ResetBits(GPIOA,GPIO_Pin_0);
Qidong(); 配置屏幕基础 Shangdian(); 上电显示:JX: while(1); } void RCC_Configuration(void) { ErrorStatus HSEStartUpStatus; RCC_DeInit(); RCC_HSEConfig(RCC_HSE_ON); HSEStartUpStatus=RCC_WaitForHSEStartUp(); if(HSEStartUpStatus==SUCCESS) { RCC_HCLKConfig(RCC_SYSCLK_Div1); RCC_PCLK2Config(RCC_HCLK_Div1); RCC_PCLK1Config(RCC_HCLK_Div2); FLASH_SetLatency(FLASH_Latency_2); FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable); RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9); RCC_PLLCmd(ENABLE); while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET); RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK); while(RCC_GetSYSCLKSource()!=0x08); } RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_USART1|RCC_APB2Periph_AFIO |RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2|RCC_APB1Periph_TIM3,ENABLE); GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE); } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_11|GPIO_Pin_10;
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
} void Qidong(void) { GPIO_ResetBits(GPIOB,GPIO_Pin_0); 拉低RE ZhiShi(0); 写入指令 FenJie(0X01); 指令01(00000001)DB7-DB0,清屏 ShiNeng(1); 使能下载指令至屏 delay_ms(100); 延时100ms
ZhiShi(0); 写入指令 FenJie(0X02); 位址归位指令02 ShiNeng(1); 使能下载指令至屏 delay_us(100); delay_ms(10);
ZhiShi(0); 写入指令
FenJie(0X06); 进入设定点,游标右移指令06
ShiNeng(1); 使能下载指令至屏
delay_us(100);
delay_ms(10);
ZhiShi(0); 写入指令
FenJie(0X0C); 整体显示,游标关,反白关指令0C
ShiNeng(1); 使能下载指令至屏
delay_us(100);
delay_ms(10);
ZhiShi(0); 写入指令
FenJie(0X14); 游标右移,AC+1,指令14
ShiNeng(1); 使能下载指令至屏
delay_us(100);
delay_ms(10);
ZhiShi(0); 写入指令
FenJie(0X30); 设为8位并行指令30
ShiNeng(1); 使能下载指令至屏
delay_us(100);
delay_ms(10);
ZhiShi(0); 写入指令
FenJie(0X40); 设定CGRAM地址到AC
ShiNeng(1); 使能下载指令至屏
delay_us(100);
delay_ms(10);
ZhiShi(0); 写入指令
FenJie(0X80); 设置DDRAM地址到AC
ShiNeng(1); 使能下载指令至屏
delay_us(100);
delay_ms(10);
ZhiShi(0); 写入指令
FenJie(0X02);
ShiNeng(1); 使能下载指令至屏
delay_us(100);
delay_ms(10);
ZhiShi(0);
FenJie(0X40);
ShiNeng(1);
delay_us(100);
delay_ms(10);
} void Shangdian(void) { 设置起始Y地址 ZhiShi(0); FenJie(0X80); ShiNeng(1); delay_us(100); 设置起始X地址 ZhiShi(0); FenJie(0X86); ShiNeng(1); delay_us(100); 开始写入数据字,先写高八位 //J字(A3CA) ZhiShi(1); FenJie(0XA3); ShiNeng(1); delay_us(100); 在写入低八位 //J字(A3CA) ZhiShi(1); FenJie(0XCA); ShiNeng(1); delay_us(100); X字高八位 //X(A3D8) ZhiShi(1); FenJie(0XA3); ShiNeng(1); delay_us(100); X字低八位 //X(A3D8) ZhiShi(1); FenJie(0XD8); ShiNeng(1); delay_us(100); } void FenJie(int A1) { 做函数值配置DB7-DB0 i7=A1/128; B6=A1-128i7; if(B6<0){B6=0;} i6=B6/64; B5=A1-128i7-i664; if(B5<0){B5=0;} i5=B5/32; B4=A1-128i7-i664-i532; if(B4<0){B4=0;} i4=B4/16; B3=A1-128i7-i664-i532-i416; if(B3<0){B3=0;} i3=B3/8; B2=A1-128i7-i664-i532-i416-i38; if(B2<0){B2=0;} i2=B2/4; B1=A1-128i7-i664-i532-i416-i38-i24; if(B1<0){B1=0;} i1=B1/2; B0=A1-128i7-i664-i532-i416-i38-i24-i12; if(B0<0){B0=0;} i0=B0/1;
if(i7==1){ GPIO_SetBits(GPIOA,GPIO_Pin_7);}
else if(i7==0){GPIO_ResetBits(GPIOA,GPIO_Pin_7);}
if(i6==1){GPIO_SetBits(GPIOA,GPIO_Pin_6);}
else if(i6==0){GPIO_ResetBits(GPIOA,GPIO_Pin_6);}
if(i5==1){GPIO_SetBits(GPIOA,GPIO_Pin_5);}
else if(i5==0){GPIO_ResetBits(GPIOA,GPIO_Pin_5);}
if(i4==1){GPIO_SetBits(GPIOA,GPIO_Pin_4);}
else if(i4==0){GPIO_ResetBits(GPIOA,GPIO_Pin_4);}
if(i3==1){GPIO_SetBits(GPIOA,GPIO_Pin_3);}
else if(i3==0){GPIO_ResetBits(GPIOA,GPIO_Pin_3);}
if(i2==1){GPIO_SetBits(GPIOA,GPIO_Pin_2);}
else if(i2==0){GPIO_ResetBits(GPIOA,GPIO_Pin_2);}
if(i1==1){GPIO_SetBits(GPIOA,GPIO_Pin_1);}
else if(i1==0){GPIO_ResetBits(GPIOA,GPIO_Pin_1);}
if(i0==1){GPIO_SetBits(GPIOA,GPIO_Pin_0);}
else if(i0==0){GPIO_ResetBits(GPIOA,GPIO_Pin_0);}
} void ZhiShi(int RSFlag) { 0/1区分是写入指令还是写入数据 if(RSFlag0) // { GPIO_ResetBits(GPIOB,GPIO_Pin_10); //RS GPIO_ResetBits(GPIOB,GPIO_Pin_1); //RW } if(RSFlag1) { GPIO_SetBits(GPIOB,GPIO_Pin_10); //RS GPIO_ResetBits(GPIOB,GPIO_Pin_1); //RW } } void ShiNeng(int Sneng) { 使能下载指令或数据 if(Sneng1) { GPIO_SetBits(GPIOB,GPIO_Pin_0); delay_us(50); GPIO_ResetBits(GPIOB,GPIO_Pin_0); ///E delay_us(50); } if(Sneng0) { GPIO_ResetBits(GPIOB,GPIO_Pin_0); ///E } } 我自己做的程序,如写的错误,请大神指出,字库对应码可以看手册后面,也可以联系我,我给你,可以到淘宝搜索店铺“睢宁小孙”“”,,写的不好,多多关照
|