STM32单片机应用与全案例实践(第2版)课件 第13、14章 基于固件库的开发示例、液晶显示在STM32中的应用-基于固件库_第1页
STM32单片机应用与全案例实践(第2版)课件 第13、14章 基于固件库的开发示例、液晶显示在STM32中的应用-基于固件库_第2页
STM32单片机应用与全案例实践(第2版)课件 第13、14章 基于固件库的开发示例、液晶显示在STM32中的应用-基于固件库_第3页
STM32单片机应用与全案例实践(第2版)课件 第13、14章 基于固件库的开发示例、液晶显示在STM32中的应用-基于固件库_第4页
STM32单片机应用与全案例实践(第2版)课件 第13、14章 基于固件库的开发示例、液晶显示在STM32中的应用-基于固件库_第5页
已阅读5页,还剩87页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第13章

基于固件库的开发及示例1本章要览1STM32程序工程模版的创建2STM32程序的烧写、调试3三个GPIO输出的范例——STM32中延时程序实现的三种常用方法这一章顺便讨论GPIO的应用——输出部分2STM32最小系统1本章开始范例程序所使用的的STM32最小系统1最小系统组成单元

CPU单元STM32F103RBT6数字电源与模拟电源通过0电阻直接共用电源LM2596SASM111712V转4V4V转3.3VBOOTBOOT0BOOT1芯片复位后从哪个区域开始执行程序串口与SWDUSARTSWD2个串口1个SWD调试接口人机界面LED独立按键5个LED3个按键接口3STM32最小系统1最小系统组成单元

CPU单元STM32F103RBT6数字电源与模拟电源通过0电阻直接共用4STM32最小系统1最小系统组成单元

5STM32最小系统1最小系统组成单元

一定要清楚:在程序下载前,BOOT的设置;下载后,要运行程序,BOOT又如何设置

6STM32最小系统1最小系统组成单元

7STM32最小系统1最小系统组成单元

USART3USART1SWD调试接口:4线即可8STM32工程模版的建立什么是工程模板?

建立工程模板的实质是什么?

建立工程模板的主要步骤有哪些?

建立工程模板的几个注意事项

一定要深刻理解工程模板的实质这样就不会机械地去学工程模板的建立问题了就能根据自己的喜好建立模板了——抵达自由王国9STM32工程模版的建立什么是工程模板?

STM32的工程模板——就是开发STM32应用程序的一个通用架构、及其配置,换言之,就是一个配置好了的空的工程——应用程序环境。有了它,可以更加快捷地开发STM32的应用程序建立工程模板的实质是什么?

STM32的模板实质——一个STM32工程应该有哪些东西,如何配置工程选项,使编译器在组件生成代码时能找到这些东西,完成代码的编译和连接。也就是说:►►必须包含哪些必要的文件;►►这些文件分别到哪里寻找,即对应的路径。10STM32工程模版的建立认识STM32的固件库

STM32固件库是什么东东——STM32的固件库

是一个或以上的完整的软件包(被称之为固件包),包括所有的标准外设的设备驱动程序,其本质是一个固件函数包(库),它由程序、数据结构和各种宏组成,包括了微控制器所有外设的性能特征。该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API。使用STM32固件库好在哪——通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。从而大大缩短开发时间,降低开发难度。STM32固件库的今世前身——ST公司2007年10月发布了V1.0版本的固件库,目前最为通用是V3.5版本,该版本固件库支持所有STM32F10X系列。可从官网免费下载。11STM32工程模版的建立认识STM32的固件库

STM32固件库——都有哪些东西,各自有啥用Libraries文件夹下是驱动库的源代码与启动文件。Project文件夹下是用驱动库写的例子跟一个工程模板。_htmresc文件夹是ST公司的LOGO图标等文件,可以直接忽视它。Utilities文件夹下存放的是ST公司评估板的相关例程代码,可以作为学习参考用,也可以直接忽视。对固件库的简单说明12STM32工程模版的建立认识STM32的固件库

STM32固件库里有一样宝贝——【1】stm32f10x_stdperiph_lib_um.chm为已经编译的帮助系统,也就是该固件库的使用手册和应用举例。【2】学会使用和爱上这个帮助系统,可以大大加快你学习的进度,让你很快“渐入佳境”!不信,我带你看看!13STM32工程模版的建立认识STM32的固件库

最后还有一样要跟你说说——Startup文件夹下有四个对应不同开发环境的启动代码文件夹,其中arm文件对应KEIL开发环境。汇编语言开发,对应不同容量芯片的启动代码,共9个启动代码是任何处理器在上电复位之后最先运行的一段汇编程序代码。那么,启动代码是啥东东呢?这个留给大家自己好好看书吧!stm32f10x.h、system_stm32f10x.c、system_stm32f10x.h也十分重要,差点忘了。这些是干啥用的呢?14STM32工程模版的建立搭建工程框架——文件夹及其文件

新建工程模版第一步:新建合适的文件夹并拷贝相应的固件库文件按照模块化思想,建立多干个文件夹,然后将固件库中必要的文件分别拷贝到各自的文件夹。例如,教材示例模板的框架如下:15STM32工程模版的建立搭建工程框架——文件夹及其文件

Libraries文件夹——固件库里的同名文件夹。这是STM32单片机及其外设的驱动程序(包括启动代码)。不能缺少。Output文件夹主要存储输出文件,例如,最后编译和链接生成的机器码文件(HEX文件),也包括其他文件的中间文件。可手工定期清理。Project文件夹主要存储开发者自己开发的相关程序文件,例如,工程文件,main.c,stm32f10x_conf.h,stm32f10x_it.c,stm32f10x_it.h?16STM32工程模版的建立新建工程——(空),通用

请你跟我一起做!——话说百遍,不如动手一遍►第1步——新建KEIL工程(在Project文件夹下)►第2步——为工程添加分组(Group)►第3步——为各组添加相关文件►第4步——对KEIL开发环境进行必要的设置►第5步——简单配置工程模版中的相关文件带电脑了吗?掌握了吗?再来一次17STM32工程模版的建立新关于建立模板的“四个提醒”

正确选择CPU型号正确选择Startcode启动代码文件正确选择实际晶振正确设置Define选项。例如,USE_STDPERIPH_DRIVER,STM32F10X_HD那么,建立模板,最核心、最本质的是什么?哪些文件是必须的?这些文件各自在哪个文件夹(即路径)?得告诉C/C++编译器18STM32程序的烧写两种烧写方式:串口下载、JTAG(SWD)下载——串口下载(ISP)STM32单片机的USART1与PC的串口正确连接通过ISP烧写软件将HEX文件下载至STM32芯片STM32全系均具有ISP能力下载前必须首先将BOOT1=0BOOT0=1然后上电复位,启动STM32芯片内的LOADERBOOTER程序进行串口在系统烧写(ISP)下载完成后必须将BOOT1=0、BOOT0=0使系统恢复从用户闪存(Flash)启动,这是正常的工作模式19STM32程序的烧写两种烧写方式:串口下载、JTAG(SWD)下载——串口下载(ISP)STM32单片机的USART1与PC的串口正确连接通过ISP烧写软件将HEX文件下载至STM32芯片STM32全系均具有ISP能力——只能使用USART1下载前必须首先将BOOT1=0BOOT0=1然后上电复位,启动STM32芯片内的LOADERBOOTER程序进行串口在系统烧写(ISP)下载完成后必须将BOOT1=0、BOOT0=0使系统恢复从用户闪存(Flash)启动,这是正常的工作模式20STM32程序的烧写——串口下载(ISP)►ST官方提供的ISP软件►第三方提供的ISP软件ST官方提供的ISP软件FlashLoaderDemonstrator软件ST官方网站下载并安装21STM32程序的烧写——串口下载(ISP)►ST官方提供的ISP软件►第三方提供的ISP软件第三方提供的ISP软件较多,例如:

STM32ISP软件V1.0网上可免费下载串口下载ISP的优点▬▬不需要增加硬件成本串口下载ISP的缺点▬▬只能烧程序,不能仿真22STM32程序的烧写——基于JTAG(SWD)的程序下载►基于JTAG软件►基于SWD为了高效、快捷地调试STM32单片机系统,通常必须使用【仿真器】J-Link,U-Link等均是很好的仿真器,而这些仿真器均提供JTAG接口(SWD接口)J-link作为一款调试ARMCPU的调试设备,典型型号:V8、V9JTAG和SWD的特点与区别到底在哪里呢?20与423STM32程序的烧写——基于JTAG(SWD)的程序下载►基于JTAG软件►基于SWD要使用J-Link仿真器——调试程序和下载程序必须正确安装驱动程序在KEILMDK等开发环境中,要使用程序下载功能,必须正确设置J-Link选项下载功能是通过KEIL里的Flash菜单项—Download加以实现的。24STM32程序的调试一个程序写好后,必须经过调试,才能确认程序的正确性。调试程序是应用系统开发中最为重要的一个环节之一在KEILMDK等开发环境下调试程序的几个条件:▃有J-Link仿真器,正确设置J-Link选项▃合适的KEIL-MDK版本,常见的如µVisionV4.73.0.0▃必要的测量工具:数字万用表,逻辑笔(测高低电平、脉冲)▃被调试的实验系统或开发板——对象重点学习两个问题——●J-Link仿真器的正确设置●利用仿真器进行调试的一般步骤和方法25STM32程序的调试重点学习两个问题——●J-Link仿真器的正确设置●利用仿真器进行调试的一般步骤和方法在工程的Target1上鼠标右键选中OptionsforTarget1出现如图2.41的设置界面点击右侧的Settings26STM32程序的调试●J-Link仿真器的正确设置——Settings1和2部分正确设置1是设置SWD方式的通信速度(与PC机)出现不稳定等情况,可适当调低。理论上可达10MJ-Link如果被正确安装,应该出现类似3的信息27STM32程序的调试重点学习两个问题——●J-Link仿真器的正确设置官方好好干●利用仿真器进行调试的一般步骤和方法点击Debug菜单项的Start/StopDebugSession激活Debug功能,进入调试状态。然后使用单步、断点等命令调试程序。StepOver、Step有啥不同什么时候用RuntoCursorLine什么是断点?如何用断点?如何退出调试状态单步或断点后,如何确定程序的错误???28工程模板的使用要使用工程模板开发一个新的项目,则只要把工程模板文件夹整体复制到新的新项目的文件夹下根据新项目的需要,调整以下相关文件:▃stm32f10x_conf.h——外设头文件配置▃stm32f10x_it.c——中断函数(如果涉及到中断程序,则编写有关

中断函数的具体代码存)▃stm32f10x_it.h——中断函数头文件▃system_stm32f10x.c——如果要调整系统时钟,则必须调整

该文件有关内容因为在stm32f10x.h中包含以下内容:#ifdefUSE_STDPERIPH_DRIVER#include"stm32f10x_conf.h"#endif这三个文件在建立模板时,已拷贝在Project文件夹29STM32的三种延时实现延时是单片机程序中常用的功能。在STM32应用系统中,要实现延时功能,通常采用三种方式。结合GPIO的输出应用范例程序,讨论三种方法:▃延时函数法——精度不高,实现方便▃SysTick定时器延时——精度高,不占用资源▃定时器中断延时——精度高,占用定时器资源重点学习两个问题——●延时的实现方法●GPIO的输出应用在这部分讨论中,重点讨论实现思想,具体程序请参阅教材一个LED闪烁,闪烁即一亮一灭,周期由延时实现30STM32的三种延时实现GPIO的输出应用——初始化、输出GPIO的初始化GPIO的高电平、低电平设置(输出)voidLED_GPIO_Config(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能时钟

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8; //选择对应的引脚GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;GPIO_Init(GPIOC,&GPIO_InitStructure);//初始化PC端口GPIO_SetBits(GPIOC,GPIO_Pin_8); //关闭LED}初始化三部曲——使能GPIO口时钟通过定义结构体变量设置对应的引脚的方式和速度初始化端口31STM32的三种延时实现GPIO的输出应用——初始化、输出GPIO的初始化GPIO的高电平、低电平设置(输出)GPIO_SetBits(GPIOC,GPIO_Pin_8);//设置该口为高电平,1delay_ms(1000); GPIO_ResetBits(GPIOC,GPIO_Pin_8);//清除该口,即低电平0delay_ms(1000);GPIO_SetBits库函数、GPIO_ResetBits库函数它们的用法掌握了?要设置某一个GPIO引脚为高电平、低电平,还有没有其他函数?32STM32的三种延时实现▃延时函数法——精度不高,实现方便▃SysTick定时器延时——精度高,不占用资源▃定时器中断延时——精度高,占用定时器资源//1ms延时函数(@72M)voiddelay_nms(u16time){u16i=0;while(time--){i=12000;//根据主频调整while(i--);}}//1us延时函数(@72M)voiddelay_us(u16time){

u16i=0;

while(time--)

{

i=10;

//根据主频调整

while(i--);

}}如果主频72M发生改变(不是72M),则必须调整i。此法有较大误差!33STM32的三种延时实现▃延时函数法——精度不高,实现方便▃SysTick定时器延时——精度高,不占用资源▃定时器中断延时——精度高,占用定时器资源CM3

内核的处理器,内部包含了一个SysTick

定时器。SysTick

是一个24

位的倒计数定时器,当计到0

时,将从RELOAD

寄存器中自动重装载定时初值。只要不把它在SysTick

控制及状态寄存器中的使能位清除,就永不停息。SysTick

在STM32

的参考手册里面介绍的很简单,其详细介绍,请参阅《Cortex-M3

权威指南》SysTick

定时器延时有两种方案——中断法——别的中断函数不便调用,不建议使用此法查询法(非中断法)——使用无限制,强烈√34STM32的三种延时实现SysTick定时器是如何工作的?SysTick定时器为递减计数器。设定初值并使能后,它以每个1系统时钟周期计数器减,计数到

0时,SysTick计数器自动重装初值并继续计数,同时可触发中断。那么每次计数器减到0,时间经过了多少时间呢?=系统时钟周期

*计数器初值。以使用72M作为系统时钟,那么每次计数器减1所用的时间是1/72M,计数器的初值如果是72000,那么每次计数器减到0,时间经过(1/72M)*72000=0.001,即1ms。(简单理解:用72M的时钟频率,即1s计数72M=72000000次,那1ms计数72000次,所以计数值为72000)

SysTick

定时器的时钟来源有两种情况可选——1)HCLK的8分频2)HCLK35STM32的三种延时实现SysTick定时器是如何工作的?SysTick定时器的初始化设置——选择时钟来源设定初值使能定时器

SysTick定时器的初始化设置涉及的寄存器——主要三个CTRL(控制寄存器)LOAD(初值寄存器)VAL(当前计数值)SysTick定时器的寄存器主要功能及其特性——

《Cortex-M3

权威指南》里面都有啦!36STM32的三种延时实现SysTick定时器是如何工作的?有例有真相,举例说明吧!/*微秒级精确延时函数*/voidDelay_us(uint32_tn)//延时多少微秒,n就输入多少!{SysTick->LOAD=72*n;//初值,因为时钟72M,72次即1μsSysTick->CTRL=0x00000005;//时钟来源设为为HCLK(72M),打开定时器while(!(SysTick->CTRL&0x00010000));//等待计数到0SysTick->CTRL=0x00000004;//关闭定时器

SysTick->VAL=0X00;//清空计数器,必须}CTRL寄存器——

第16位:计数到0则为1

第02位:时钟选择位,0=HCLK/8,1=HCLK

第00位:使能位,1为使能5=10137STM32的三种延时实现▃延时函数法——精度不高,实现方便▃SysTick定时器延时——精度高,不占用资源▃定时器中断延时——精度高,占用定时器资源如果你学过8位的51单片机,那么请你先想想采用定时器中断是如何实现延时的??38STM32的三种延时实现▃延时函数法——精度不高,实现方便▃SysTick定时器延时——精度高,不占用资源▃定时器中断延时——精度高,占用定时器资源STM32拥有众多功能强大、种类不同的定时器定时器的功能就是定时和计数,即定时器和计数器定时器中断延时——►实现原理——此法的本质及其实现要领►注意问题——重点和难点延时的本质就是定时由于定时器的内容比较复杂,所以专门有章节讨论它。作为本章的范例,重点是理解定时的实现方法。39STM32的三种延时实现定时器中断延时——实现原理时钟安全系统(CSS)

时钟安全系统被激活后,时钟监控器将实时监控外部高速振荡器;如果HSE时钟发生故障,外部振荡器自动被关闭,产生时钟安全中断,该中断被连接到Cortex-M3的NMI的中断;同时CSS将内部RC振荡器切换为STM32的系统时钟源。一旦CSS被激活,当HSE时钟出现故障时将产生CSS中断,同时自动产生NMI。NMI将被不断执行,直到CSS中断挂起位被清除。因此,在NMI的处理程序中,必须通过设置时钟中断寄存器(RCC_CIR)里的CSSC位来清除CSS中断。

时钟安全系统(CSS)

的使能

RCC_ClockSecuritySystemCmd(ENABLE);正常情况下,范例中的上述语句可以删除不用。特此说明

!40STM32的三种延时实现定时器中断延时——实现原理程序实现要领

——选用合适的定时器——如果仅仅用于延时,选用基本定时器即可——使能相关外设的时钟——对定时器进行初始化——设置定时参数等——设置定时器中断——优先级、使能——设计定时器中断函数——启动定时器范例程序中对应的函数

——选用合适的定时器——TIM3——使能相关外设的时钟——RCC_Configuare()——对定时器进行初始化——TIM3_Configuare()(参数、允许中断等)——设置定时器中断——NVIC_Configuare()——设计定时器中断函数——TIM3_IRQHandler()(在stm32f10x_it.c)——启动定时器——TIM_Cmd(TIM3,ENABLE)41STM32的三种延时实现定时器中断延时——注意事项重点——定时器初始化设置——中断的设置难点——定时参数计算——中断的优先级(模式和等级)42STM32的GPIO输出模式STM32的最常用的外设模块是GPIO,它通常用于信号的输入输出。STM32的GPIO具有四种输入、四种输出模式。(1)GPIO_Mode_AIN

模拟输入

(2)GPIO_Mode_IN_FLOATING

浮空输入

(3)GPIO_Mode_IPD

下拉输入

(4)GPIO_Mode_IPU

上拉输入

(5)GPIO_Mode_Out_OD

开漏输出

(6)GPIO_Mode_Out_PP

推挽输出

(7)GPIO_Mode_AF_OD

复用开漏输出

(8)GPIO_Mode_AF_PP

复用推挽输出4种输出模式这2种输出模式同在用在II2总线、串行通信等43STM32的GPIO输出模式STM32的GPIO用于一般的输入输出——第一步:对GPIO进行初始化设置第二步:对GPIO进行写入、读取操作对GPIO进行初始化设置:设置什么、如何设置对GPIO进行写入操作:写入1、0(高、低电平),如何写入44STM32的GPIO输出模式STM32的GPIO初始化设置——结合例子voidLED_GPIO_Config(void){GPIO_InitTypeDefGPIO_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);//使能C口时钟

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8|GPIO_Pin_9;//选择对应的引脚

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;//推挽输出

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//速度为10MGPIO_Init(GPIOC,&GPIO_InitStructure);//初始化PC端口

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11|GPIO_Pin_12; //引脚

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_OD;//输出开漏方式

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_10MHz;//速度为10MGPIO_Init(GPIOC,&GPIO_InitStructure);//初始化C端口

}速度是啥意思?45STM32的GPIO输出模式STM32的GPIO的速度设置——GPIO的引脚速度——I/O口驱动电路的响应速度,而不是输出信号的速度。输出信号的速度只取决于程序。当STM32的GPIO端口设置为输出模式时,有三种速度可以选择——2MHz、10MHz和50MHz。这个速度是指I/O口驱动电路的速度,是用来选择不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。

高频的驱动电路,噪声也高。当你不需要高的输出频率时,请选用低频驱动电路,这样非常有利于提高系统的EMI性能。

如果你要输出较高频率的信号,但却选用了较低频率的驱动模块,你很可能会得到失真关键是,GPIO的引脚速度如何与应用匹配?

举例:对于串口,假如最大波特率只需115.2k,那么用2M的GPIO的引脚速度就够了,既省电也噪声小。原来是这个意思啊,城里套路深!46STM32的GPIO输出模式STM32的GPIO写入(输出)操作——库函数法、寄存器法GPIO_WriteBit(GPIOx,GPIO_Pin_y,BIT_SET/BIT_RESET)置位或者复位单个输出端口的数据GPIO_Write(GPIOx,0x1111)置位或者复位整个输出端口的数据。其中x:A-Gy:0-15GPIO_SetBits(GPIOA,GPIO_Pin_0

|

GPIO_Pin_1)设置PA0--PA1高电平

GPIO_ResetBits(GPIOA,GPIO_Pin_0

|

GPIO_Pin_1)设置PA0--PA1低电平GPIOB->ODR=0XFFFF;

//设置PB0高电平

GPIOB->ODR=0XFFFE;

//设置PB0低电平例如:GPIO_WriteBit(GPIOA,GPIO_Pin_3,1)设置PA3高电平GPIO_WriteBit(GPIOA,GPIO_Pin_3,0)设置PA3低电平库函数法。注意用法寄存器法47STM32的GPIO输出模式STM32的GPIO写入(输出)操作——考考你!假设一个LED接在GPIOB的8脚上,高电平关闭。如果要让它以500ms/500ms的周期闪烁显示,请写出程序?48本章小节为啥要建立工程模板——建立工程模板的实质有1哪两个方面?如何使用工程模板?一个STM32应用程序一般需要修改和重新设计的文件一般有哪几个?各自的用途是什么?STM32的程序如何下载(烧写)?使用J-Link仿真器,JTAG和SWD两种接口的区别在哪里?KEIL-MDK中,如何利用SWD进行程序调试?49感谢有你没有比人更高的山。只要你坚信自己能行,你就一定能找到进入STM32大门钥匙!Comeon►►►50第14章液晶显示在STM32中的应用——基于固件库学习内容提要1STM32与液晶模块12864的接口实现——延时法2STM32与液晶模块12864的接口实现——查询状态法3基于液晶模块12864的菜单程序4矩阵键盘的接口实现重点——STM32与液晶模块的接口矩阵键盘的接口难点——液晶模块的多样化应用(菜单、图形显示)小贴士——字模提取软件

按键去抖动人机界面——按键输入与液晶显示关于人机界面1人机界面又称“人机接口”、“用户界面或使用者界面”HMI——Human-machine

Interface单片机应用系统中用于输入和输出的功能模块输入——最常用的是按键、鼠标输出——最常用的是发光二极管、数码管、液晶显示

声音提示(如蜂鸣器)

2凡参与人机信息交流的领域都存在着人机界面。现在大量运用在工业与商业上。好的人机接口会帮助使用者更简单、更正确、更迅速的操作设备,也能使设备发挥最大的效能并延长使用寿命好的人机界面可以大大改善“用户体验”,提高产品竞争力。同样的硬件,可以创意无限!STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的两种接口方法1延时法——就是按照时序要求通过延时函数实现各种时序关系,也就是通过延时以等待“忙”状态结束优点:简单缺点:在时序要求较高的场合,有可能会出现意外、失常

2查询状态法——通常情况下,功能模块大多会提供一个“忙”状态信号或引脚,可以随时获取该模块的当前状态如果是“忙”状态,则不能对它进行写入操作,否则,可以进行写操作对12864液晶模块而言,可通过查询状态字的忙状态位的方式以获取“忙”状态信号液晶模块跟其他功能模块一样,接口设计中最重要的是时序配合、读出写入时的应答处理。STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的硬件接口1HP12864F模块——带汉字字库(有些模块是不带汉字库的)该模块的控制器为ST7920,因此指令系统与ST7920系列完全一致该模块的电源电压范围较宽:3.0—7.0V,信号电压为:2.7-5.5V可以适用于5V单片机系统和3.3V单片机系统自带亮度调节电位器设计,可以自行焊接一个10K的小型电位器。只有通过它调整至合适的对比度,才能正常显示该模块的引脚与大多数12864模块的引脚完全兼容2与STM32的硬件接口——有并行接口方式和串行接口方式在串行接口方式中,4、5、6三脚的功能定义有所变化,分别是:①4脚:片选信号;②5脚:串行数据;③6脚:串行时钟本例使用的是串行接口方式模块4脚与STM32单片机的GPIOB的PB8相连;模块5脚与STM32单片机的GPIOB的PB9相连;模块6脚与STM32单片机的GPIOB的PB10相连。模块的PSB脚在模块上直接焊接为低电平端(串行方式)模块的RST脚可以不接液晶模块的电源和背光使用+5V电源STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——初识128641对12864的操作————读忙状态(同时读出指针地址内容),初始化之后每次对12864的读写均要进行忙检测——写命令:所有的命令可以查看指令表。写地址也是写指令——写数据:操作对象有DDRAM、CGRAM、GDRAM——读数据:操作对象也是DDRAM、CGRAM、GDRAM2DDRAM、CGRAM、GDRAM——DDRAM:(DataDisplayRam),数据显示RAM,往里面写啥,屏幕就会显示啥。CGRAM:(CharacterGenerationRAM),12864内部提供了64×2B的CGRAM,允许用户自定义4个16×16字符,每个字符占用32个字节GDRAM:(GraphicDisplayRAM):图形显示RAM,这一块区域用于绘图,往里面写啥,屏幕就会显示啥,它与DDRAM的区别在于,往DDRAM中写的数据是字符的编码,字符的显示先是在CGROM中找到字模,然后映射到屏幕上,而往GDRAM中写的数据时图形的点阵信息,每个点用1bit来保存其显示与否STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——初识128643DDRAM——12864内部有4行×32字节的DDRAM空间但是某一时刻,屏幕只能显示2行×32字节的空间那么剩余的这些空间干啥用呢?它们可以用于缓存,在实现卷屏显示——提高刷新频率4DDRAM结构——80H、81H、82H、83H、84H、85H、86H、87H、88H、89H、8AH、8BH、8CH、8DH、8EH、8FH90H、91H、92H、93H、94H、95H、96H、97H、98H、99H、9AH、9BH、9CH、9DH、9EH、9FHA0H、A1H、A2H、A3H、A4H、A5H、A6H、A7H、A8H、A9H、AAH、ABH、ACH、ADH、AEH、AFHB0H、B1H、B2H、B3H、B4H、B5H、B6H、B7H、B8H、B9H、BAH、BBH、BCH、BDH、BEH、BFH想想,这是为什么?黄色部分对应上半屏显示白色部分对应下半屏显示对应一屏显示第一行:80H、81H、82H、83H、84H、85H、86H、87H第二行:90H、91H、92H、93H、94H、95H、96H、97H第三行:88H、89H、8AH、8BH、8CH、8DH、8EH、8FH第四行:98H、99H、9AH、9BH、9CH、9DH、9EH、9FHSTM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——初识128645DDRAM中字符与汉字显示与地址的对应关系——关于DDRAM的三点注意————每次对DDRAM的操作单位是一个字,也就是2个字节,当往DDRAM写入数据时,首先写地址,然后连续送入2个字节的数据,先送高字节数据,再送低字节数据。读数据时也是如此,先写地址,然后读出高字节数据,再读出低字节数据(读数据时注意先假读一次)——显示ASCII码半宽字符时,往每个地址送入2个字节的ASCII编码,对应屏幕上的位置就会显示2个半宽字符,左边的为高字节字符,右边的为低字节字符——显示汉字时,汉字编码的2个字节必须存储在同一地址空间中,不能分开放在2个地址存放,否则显示的就不是你想要的字符。每个字中的2个字节自动结合查找字模并显示字符CDRAM用于图形显示,那么点和地址的关系又是如何,请认真自学吧!STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——初识12864612864模块串行读写的时序——一开始先传输启始字节,启始字节前五位为“同步位”字符串(五个连续的“1”),此时传输计数将被重置并且串行传输将被同步,再跟随的两个位字符串(第六、第七位)分别指定传输方向位(RW)及寄存器选择位(RS),最后第八位则为“0”。在接收到包含同步位及RW和RS信息的启始字节后,每一个八位的指令(数据)将被分为两个字节发送接收:高4位(DB7—DB4)的数据将会被放在第一个字节的LSB部分,而低4位(DB3—DB0)的数据会被放在第二个字节的LSB部分,其余的四位则以“0”填充STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——初识12864712864的核心是一个字节的写入和读出——下面是写入一个字节的函数,注意其时序延时方式实现时序配合voidSend_Byte(u8bbyte)//写入1字节(数据或命令)函数{u8i,t;for(i=0;i<8;i++) //一个字节8位{ if((bbyte)&0x80)//取出最高位 SID_H;//当前位为1,此处为宏语句,具体看教材的程序

else SID_L; //当前位为0,同上说明 SCLK_H; //时钟上升沿写入 t=0x10;//t的值要根据系统的时钟调整至合适的值 while(t--);//延时等待写入完成(时序需要)

SCLK_L; //时钟信号回到低电平,为下次跳变做准备 bbyte<<=1;//左移1位,取出要写入的下一位

}}STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——初识12864812864的写指令或数据接口函数——按照6的时序要求,写出写入指令或数据的接口函数如下voidWrite_Char(u8start,u8ddata)//写命令或数据函数{u8start_data,Hdata,Ldata;if(start==0) //参数start=0,则表示ddata为指令,否则为数据start_data=0xf8;//写指令,11111000——00写入命令

elsestart_data=0xfa;//写数据,11111010——01写入数据Hdata=ddata&0xf0;//取高四位。高低四位均作为一个字节的低4位Ldata=(ddata<<4)&0xf0;//取低四位。高低四位分两次发送Send_Byte(start_data);//发送起始信号Delaynms(10); //适当延时,延时时间1以上即可Send_Byte(Hdata);//发送高四位Delaynms(5);Send_Byte(Ldata);//发送低四位Delaynms(5);}回忆一下,在6中,5个1后是写入读出位、寄存器选择位STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——初识12864912864的指令系统——下面以基本指令为例说明(扩展指令请自己查资料学习)——清屏指令(0x01):DDRAM写满0x20,指针地址写0x00。屏幕显示空白(即清屏)——回车指令(0x02/0x03):地址指针内容写0x00——进入模式:000001I/DS:设置读写数据之后光标、显示移位的方向内部有2个可编程位,I/D表示读写一个字符后数据指针是加一还是减一。I/D=1指针加一,I/D=0指针减一。S=1开启整屏移动——显示、光标、闪烁开关:0000001DCB:D=1:显示开(Display)

C=1:光标开(Cursor)

B=1:光标位置闪烁开(Blink),B=0则为关闪烁——光标显示移位控制:0001S/CR/LXX——功能设置:001DLX

RE

XX切换基本指令集与扩展指令集。DL=1表示8位接口,DL=0表示4位接口RE=1表示开启扩展指令,RE=0表示使用基本指令开启基本指令则设置为0x30,开启扩展指令则设置为0x34STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析1范例程序框架——由于没有读取12864状态,所以只有写操作整个程序需要涉及调整的文件只有两个——main.c包含了液晶模块的基本接口函数和延时函数(粗略延时,不够精准,可根据需要调整为精准以us为单位的延时函数)——stm32f10x_conf.h设置本例涉及到的STM32的外设模块的头文件。即必须使用以下两个外设头文件#include"stm32f10x_gpio.h" //使用GPIO头文件(PB端口被使用)#include"stm32f10x_rcc.h" //使用RCC头文件(系统时钟初始化函数)串行接口使用GPIOB的PB8、PB9、PB10——PB8 ——

CS 片选——PB9 ——

SID 串行数据——PB10——

SCLK 时钟(上升沿有效)STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析2相关引脚及其操作的宏语句——主要是与液晶模块串行接口的三个引脚,采用宏定义,简便#defineDAT_128 GPIO_Pin_9 //数据引脚#defineSID_HGPIO_SetBits(GPIOB,DAT_128)//输出高电平

#defineSID_LGPIO_ResetBits(GPIOB,DAT_128)//输出低电平#defineCS_128 GPIO_Pin_8 //片选引脚

#defineCS_H GPIO_SetBits(GPIOB,CS_128)//设置高电平

#defineCS_L GPIO_ResetBits(GPIOB,CS_128)//设置低电平#defineSCLK_128GPIO_Pin_10//时钟引脚#defineSCLK_HGPIO_SetBits(GPIOB,SCLK_128)//设置高电平#defineSCLK_LGPIO_ResetBits(GPIOB,SCLK_128)//设置低电平使用宏语句是一种形象直观、简便的好方法,学会它!STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析312864的初始化——复位、显示方式、清屏、有关计数器归零等voidLcd_Init(void){Delaynms(50);//等LCM讲入工作状态(必须,否则初始化无效)

CS_H;//按照时序要求,必须高电平才能选中液晶模块Write_Char(0,0x30);//8位介面,基本指令集

Write_Char(0,0x0c);//显示打开,光标关,反白关

Write_Char(0,0x01);//清屏

Write_Char(0,0x02);//清屏,将DDRAM的地址计数器归零

Write_Char(0,0x80);//清屏,将DDRAM的地址计数器归零

Delaynms(50);}对STM32对液晶等外围模块进行初始化以前,必须确保这些模块已完成复位,否则,初始化无效或无法初始化。这一点要重视!这些参数代表啥命令,请自行查阅资料消化STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析412864的文字显示坐标设置——设置文字显示时的坐标//功能描述:设置LCD显示的起始位置,X为行,Y为列//参数:X行(0~4),Y列(0~16)voidLCD_Set_XY(u8X,u8Y){u8address;switch(X){ case0:address=0x80+Y;break; case1:address=0x90+Y;break; case2:address=0x88+Y;break; case3:address=0x98+Y;break; default:address=0x80+Y;break;}Write_Char(0,address); //写命令函数(第一个参数0代表写命令)}这些参数代表啥命令,还记得吗?STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析512864的文字显示——在指定行列显示文字//功能描述:中英文字符串显示函数//参数:X为列坐标,Y为行坐标//用内码表示的汉字、ASCII码表示的字符组成的数组(字符串)voidLCD_Write_String(u8X,u8Y,uc8*s){LCD_Set_XY(X,Y);while(*s) //取出显示的ASCII码或汉字内码{ Write_Char(1,*s);//写数据,显示该字符

s++; Delaynms(1);}}STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析612864的图形显示——在指定坐标显示一个点(pixel)、图形voidDisplay_Img(u8const*img){u8i,j;for(j=0;j<32;j++)//32行for(i=0;i<8;i++)//8块(64列){Write_Char(comm,0x34);//扩展

Write_Char(comm,y+j);Write_Char(comm,x1+i);Write_Char(comm,0x30);//基本Write_Char(dat,img[j*16+i*2]);Write_Char(dat,img[j*16+i*2+1]);}for(j=32;j<64;j++)//另32行for(i=0;i<8;i++)//另8块(64列){Write_Char(comm,0x34);Write_Char(comm,y+j-32);Write_Char(comm,x2+i);Write_Char(comm,0x30);Write_Char(dat,img[j*16+i*2]);Write_Char(dat,img[j*16+i*2+1]);}Delaynms(10);Write_Char(comm,0x36); //打开图形指令}如何理解上述程序————扩展指令、基本指令——图形方式下的坐标与数据写入STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析712864的图形显示的几点说明——在指定坐标显示一个点(pixel)、图形要使用绘图功能需要开启扩展指令。然后写地址,再读写数据先开启扩展指令集(0x36\0x34),然后写入地址,这里的地址与DDRAM中的略有不同,GDRAM中的地址有2个,分别是列地址/水平地址X和行地址/垂直地址Y然后回复到基本指令状态(不是必须的),再连续写入2个字节的图形数据设定绘图RAM(GDRAM)地址到地址计数器(AC)垂直地址范围AC5...AC0(80H-BFH,共64行)水平地址范围AC3...AC0(80H-8FH,共16块)水平地址16块,每块又分成8列,所以共8列×16=128列操作的时候,先输入垂直地址,再输入水平块地址,然后再输入水平数据,可连续输入两个字节再看前面的程序,能懂了吗?STM32与液晶模块12864的接口实现——延时法STM32与液晶模块12864的软件接口——范例程序分析8程序运行效果演示——文字和图形右侧图片数据来自网络,可自行选取BMP图片以显示不同的图形STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法接口的算法1状态法原理——12864液晶模块对外提供状态信号,可以通过读取状态字来获得液晶模块的当前状态,其中最主要的是“忙”状态信息。通过查询“忙”状态信息,然后再对液晶模块进行写入操作,可以确保万无一失。因此,这种实现方法往往被推荐使用2模块化设计——本例还特别考虑了延时的精确性问题为了解决延时的精确性,使用STM32内部的SysTick的普通计数模式对延迟进行管理。这样,一方面确保了在接口函数中为保证时序配合的精准性而使用延时的需要;另一方面,绝大多数项目中,通常也需要使用延时功能。因此,增加延时函数是合理的为了增加程序的可维护性,本节的接口程序还采用了模块化方式,将延时、液晶模块接口、主函数等分文件实现模块化是程序设计的主流方向STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法接口的算法3硬件连接——同“延时法”例子程序中有详细注释,能方便看出硬件连接关系STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法接口的算法4程序框架——带框部分为需要调整或修改的文件主文件SysTick延时函数头文件液晶模块接口函数头文件STM32外设头文件配置头文件SysTick延时函数源文件液晶模块接口函数源文件STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法接口的算法5程序代码——状态检查重点讨论状态检查、STM32系统时钟初始化其他程序的分析,请自行阅读程序中的注释//功能:LCD忙检查voidCheck_Busy(void){doSend_Byte(0xfc);//11111,RW(1),RS(0),0while(0x80&Receive_Byte());}voidWrite_LCD_Command(u8cmdcode){CS_H;Check_Busy();Send_Byte(0xf8);Send_Byte(cmdcode&0xf0);//高4位Send_Byte((cmdcode<<4)&0xf0);//低4位delay_ms(2);CS_L;}检查状态函数在写命令函数中的应用读状态寄存器命令——0xfcReceive_Byte()从液晶模块读1字节函数函数值为1字节,最高位为1,说明状态为忙STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法接口的算法6-1程序代码——STM32系统时钟初始化不使用固件库默认时钟(72M),而使系统时钟可选voidStm32_Clock_Init(u8pll){ErrorStatusHSEStartUpStatus;//将外设RCC寄存器重设为缺省值RCC_DeInit();RCC_HSEConfig(RCC_HSE_ON);//RCC_HSE_ON——外部高速晶振HSE晶振打开(ON)HSEStartUpStatus=RCC_WaitForHSEStartUp();//等待HSE起振if(HSEStartUpStatus==SUCCESS)//SUCCESS:HSE晶振稳定且就绪

{RCC_HCLKConfig(RCC_SYSCLK_Div1);//RCC_SYSCLK_Div1即AHB时钟HCLK=系统时钟RCC_PCLK2Config(RCC_HCLK_Div1);//RCC_HCLK_Div1——PCLK2=HCLKRCC_PCLK1Config(RCC_HCLK_Div2);//RCC_HCLK_Div2,PCLK1=HCLK/2FLASH_SetLatency(FLASH_ACR_LATENCY_2);//FLASH存储器延时时钟周期数,2FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);//FLASH预取指使能

//设置PLL时钟源及倍频系数RCC_PLLMul_9——PLL输入时钟x9STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法接口的算法6-2程序代码——STM32系统时钟初始化(接6-1)switch(pll){case2:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_2);break;case3:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_3);break;case4:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_4);break;case5:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_5);break;case6:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_6);break;case7:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_7);break;case8:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_8);break;case9:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_9);break;default:RCC_PLLConfig(RCC_PLLSource_HSE_Div1,RCC_PLLMul_2);break;}RCC_PLLCmd(ENABLE);//使能PLLwhile(RCC_GetFlagStatus(RCC_FLAG_PLLRDY)==RESET){}//PLL准备好否RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);//设置系统时钟为:PLLwhile(RCC_GetSYSCLKSource()!=0x08){}//0x08:PLL作为系统时钟成功}}STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法接口的算法6-3程序代码——STM32系统时钟初始化(接6-2)STM32系统时钟自由设置的关键要领选择外部晶振并启动设置AHB时钟——HCLK设置高速外设时钟——PCLK2设置低速外设时钟——PCLK1设置PLL倍频系数——要注意,不是简单乘以2、3、4、设置PLL使能选择PLL作为系统时钟——SYSCLKFLASH存取的设置可使用默认值(不设置也行)时钟设置是STM32单片机系统开发最基础、最重要的第一步,时钟不正常,系统不可能正常工作使用固件库开发STM32系统,默认情况下是使用外部晶振,时钟72M——#defineSYSCLK_FREQ_72MHz72000000,改变这个地方,也可以改变默认时终值。这个你知道吗?STM32与液晶模块12864的接口实现——状态法STM32与液晶模块12864的状态法范例的实际运行1运行效果——自定义字符演示STM32系统中基于液晶模块的菜单驱动程序菜单的基本概述1程序实现的两种方式————种是基于命令行方式,即通过输入指令驱动程序实现相应功能最大缺点是必须精确掌握指令,对操作者而言,它不是十分方便——是基于菜单方式,即通过选择不同的菜单实现程序的不同功能只要通过选择不同的菜单项,就可以实现不同的功能,因此,它便于操作,成为程序实现的主流方式掌握基于菜单(菜单驱动)的程序开发技术是十分必要2菜单的常见形式——弹出菜单、下拉菜单、图标菜单、多级菜单、浮动菜单等本例讨论的是一个在嵌入式系统中常用的光标菜单作为一个演示范例,只讨论了一级菜单形式,在此基础上,完全可以仿照着继续写出二级菜单、三级菜单,以适应各种复杂的的要求STM32系统中基于液晶模块的菜单驱动程序菜单设计要求1菜单的样式——通过一个按键控制箭头上下移动,即该建相当于上下移动光标控制键;通过另外一个按键选中当前菜单项,该建相当于回车确认键——按键1——用于实现光标移动功能(箭头上下移动)——按键2——用于实现选择确认(回车键)功能左侧箭头表示当前菜单项每个菜单项对应一个功能STM32系统中基于液晶模块的菜单驱动程序菜单设计算法1①显示菜单的初始画面(如下图)②不停捕捉按键1或按键2。——如果是按键1,则首先清屏,然后将箭头放在菜单的第二项位置的整个菜单显示出来,这样感觉是光标下移了;如果光标已经位于最后一个菜单项,则移到第一个菜单项——如果是按键2,则表示选中光标所在的菜单项,则执行对应的功能不难看出,菜单的切换其实与动画的原理十分相似STM32系统中基于液晶模块的菜单驱动程序硬件电路1——上下移动键——PA0WK_UP与引脚PA0相连,对应系统板上标号为KEY2的按键,它是高电平有效,注意GPIO的正确配置——下拉输入——回车确认键——PE4KEY0与引脚PE4相连,对应系统板上标号为KEY3的按键,它是低电平有效,注意GPIO的正确配置——上拉输入——指示灯1——PE6LED0与引脚PE6相连,对应程序中的LED2——指示灯2——PE5LED1与引脚PE5相连,对应程序中的LED1STM32系统中基于液晶模块的菜单驱动程序系统实物及运行效果1STM32系统中基于液晶模块的菜单驱动程序基于模块化的程序框架1需要新建或者修改调整的文件有:delay.c,delay.h,menuandkey.c,menuandkey.h,st12864.c,st12864.h,stm32f10x_conf.h,以及main.c等8个源程序文件。①delay.c,delay.h——2个文件:主要是延时函数的定义和说明②st12864.c,st12864.h——2个文件:主要液晶模块的接口函数的定义和说明③menuandkey.c,menuandkey.h——2个文件:主要是按键和发光二极管接口函数的定义和说明④stm32f10x_conf.h——1个文件:主要是STM32所使用的外设的头文件的配置⑤main.c——1个文件:主要是程序的主函数、系统时钟等初始化的函数其中,delay.c,delay.h,st12864.c,st12864.h与上例完全相同,所以本节不予讨论STM32系统中基于液晶模块的菜单驱动程序程序代码分析1菜单实现代码——在menuandkey.c,menuandkey.h显示菜单函数——参数:为光标所在项的序号,1表示第1项,类推voidDisplayMenu(u8cur){Display_LCD_String(0,MenuItem_0,1);//选择菜单提示switch(cur)//根据该参数在相应的菜单项前显示箭头符{case1:MenuItem_1[1]=26; //字符->的ASCII码

MenuI

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论