基于STM32的电子时钟设计

2020-11-30 03:27
绵阳师范学院学报 2020年11期
关键词:外设固件寄存器

郭 辛

(绵阳师范学院机电工程学院,四川绵阳 621000)

0 引言

单片机自诞生之日起已走过近半个世纪的历程.随着电子技术和计算机技术的飞速发展,进入21世纪以来以嵌入式系统为代表的新兴技术正在逐渐占据工业控制领域主导地位,并逐步取代以8位处理器为核心的传统测控系统[1].近年来由于数字信息技术和网络技术的广泛应用,单片机作为主流核心处理器的地位逐步下降,现代电子技术的发展正朝着智能化、网络化和低功耗的方向迈进.新技术的不断更新,需要新的设计思想的注入才能满足技术发展需求.那么,如何将新兴技术融合到传统知识架构体系,将基础理论与工程应用实际相结合,就成为设计人员急需破解的难题.

ARM作为一种32位的高性能、低成本的嵌入式RISC微处理器,得到了广泛的应用,STM32系列是意法半导体 (STMicroelectronics) 集团专为要求高性能、低成本和低功耗的嵌入式应用设计的ARM Cortex-M系列产品的代表作.基于STM32的嵌入式技术已经渗透在工业控制系统、数据采集系统、智能化仪器仪表和办公自动化等诸多领域的应用,甚至在很大程度上正在改变我们现有的商业模式和工作生活方式,如智能手机、导航系统、无人机和平板电脑等,并呈现出明显的系统化、人工智能化和物联网的趋势.

目前, Cortex系列处理器已经占据了大部分嵌入式处理器的中高端产品市场,而嵌入式系统的应用开发对从业者要求很高,初学者若要快速掌握其原理并在实际工程中加以应用,必须改变传统的思维方式并构建新的设计理念.本文以STM32F103RC处理器(Cortex-M普通型号之一)为平台,通过对定时器、中断系统和LCD显示模块的组合设计为例,针对基于固件库设计思想的方法进行探讨与总结,以开启嵌入式系统的应用设计学习之门[2].

1固件库概述

固件库是指“STM32 标准函数库”,它是由 ST 公司针对 STM32 提供的函数接口,即 API(Application Program Interface),是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征.它是架设在构成部件的寄存器与用户驱动层之间的代码,向下处理与寄存器直接相关的配置,向上为用户提供配置寄存器的接口[3].部件的调用和基本操作写成了通用的子函数,对复杂的硬件操作实现了函数封装.

在以51单片机为代表的8位机由于硬件系统相对简单,通常采用直接配置寄存器的方式来进行应用开发;而32位处理器核内系统复杂,外设资源丰富.应用系统若仍旧采用传统的设计方式,不但效率低、可移植性差,而且技术难度大,已不能适应较复杂的工程应用.

基于固件库的技术思想为解决这一问题提供了新思路:开发者根据具体任务需求按照CMSIS标准构建工程,利用固件库提供的资源,设计和改造相关函数以实现对部件的操作.本文结合综合实验项目的开发——电子时钟的设计为例,首先介绍库函数中主要涉及的定时器和LCD显示驱动的基本结构和工作原理,在此基础上利用现有库资源进行功能设计与系统构建.

2 定时器概述

STM32F1 系列中,共有 8 个定时器TIM1—TIM8,分为基本定时器,通用定时器和高级定时器.基本定时器 TIM6 和 TIM7 是一个 16 位的只能向上计数的定时器,它只能定时,没有外部 I/O;通用定时器 TIM2/3/4/5 是一个 16 位的可以向上/下计数的定时器,可以定时、输出比较和输入捕捉,每个定时器有四个外部I/O;高级定时器 TIM1/8是一个 16 位的可以向上/下计数的定时器,可以定时、输出比较,输入捕捉,以及实现三相电机互补输出信号,每个定时器有 8 个外部 I/O[4].此例以TIM6作定时器,设计一款LCD屏显电子时钟,计时60 min,最小显示值1s.

2.1 TIM6定时器组成

根据STM32参考手册基本定时器的功能结构如图1所示[3].

图1 基本定时器功能框图Fig.1 Block Diagram of Basic Timer Function

定时器若要向外提供基本时钟信号,需对相关寄存器进行参数设置:

1)时钟源TIM*CLK:根据STM32时钟系统设置,通常挂载APB1时钟总线,默认取值为72MHz[5];

2)16位分频器PSC:用于存放预分频值,分频范围1~65536,则时钟周期

CK_CLK= (PSC+1)/ TIM*CLK

(1)

即每计1个数的时间间隔

3)自动重装载寄存器ARR:用于存放16位计数值,用于设定定时长度

Td= CK_CLK*ARR

(2)

综上所述,首先对定时器初始化,将所预设参数写入到对应的结构体中,赋值包含以下内容:

……

#define BASIC_TIM TIM6

#define BASIC_TIM_CLK RCC_APB1Periph_TIM6

#define BASIC_TIM_ARR 1000-1

#define BASIC_TIM_PSC 71

……

按照以上参数设置,基本定时时长为:

Td= 〔(PSC+1)/ TIM*CLK〕 *ARR =(72/72M)*1 000=1ms

(3)

2.2 电子时钟定时原理

如图2所示,内部定时器提供基准时长Td=1ms,引入定时中断,每计时1ms中断一次;中断次数time= 1 000产生1s定时,即LCD 显示屏每隔1 s更新一次秒位(sec)计数值;每计满60 s更新一次分位(min)计数值,并将其分别显示到LCD屏上.

图2 定时原理示意图Fig.2 Schematic Diagram of Timing Principle

2.3 LCD显示

内部时基信号产生后,还需将结果显示出来,STM32F103实验板配2.8吋16位数据接口液晶屏,控制芯片采用了ILI0341.ILI0341是一个用于TFT液晶显示的单芯片控制驱动器,具有262,144色的240RGB×320像素显示方案;ILI0341支持8/9/16/18位数据总线的MCU接口,6/16/18位数据总线的RGB接口以及3/4线的SPI 接口[4],本示例中液晶屏控制器采用了预先配置的8080 接口通讯,使用 16 根数据线的 RGB565格式.其相关驱动程序按照ILI9341标准编制,主要由如下几步完成:

1)初始化LCD数据/控制管脚ILI9341_GPIO_Config ().

2)点亮背光 ILI9341_BackLed_Control ( ENABLE ).

3)初始化控制寄存器ILI9341_REG_Config ().

4)设置显示模式ILI9341_GramScan(LCD_SCAN_MODE).

初始化液晶屏完成后,调用显示驱动函数.

5)清屏ILI9341_Clear(0,0,LCD_X_LENGTH,LCD_Y_LENGTH).

6)设置显示字符字体(8x16)、颜色(红字)及背景(黑底)LCD_SetFont(&Font8x16);LCD_SetColors(RED,BLACK).

7)使用c标准库把时间变量转化成字符串并显示 sprintf(dispBuff,"time : %d: %d ",y,x);[6]LCD_ClearLine(LINE(6));ILI9341_DispStringLine_EN(LINE(6),dispBuff).将数据转换成字符串,存放于数组dispBuff并写入指定行.

3 系统设计

在以51单片机为主控单元的系统中,我们往往采用直接配置寄存器控制字的方法来操控硬件,因为MCS-51内部寄存器只有21个,而且功能简单,程序设计直观简便;而STM32作为系统主控制器,其内部设备多达几十个,而控制这些设备的寄存器有几百个,若要使系统维持基本运转,操作这些寄存器所需的驱动程序代码成千上万行,这对于应用开发者来说逐条写程序是不现实的.芯片厂商将这些外设的驱动源码封装成固件函数包提供给用户,由用户在此基础上进行应用开发,因此以STM32为主控制器的应用系统开发就包括项目搭建和程序设计两部分.

3.1 固件库文件结构分析

1)启动文件startup_stm32f10x_hd.s:设置堆栈、PC指针和配置系统时钟等.

2)时钟配置文件system_stm32f10x.c:将外部时钟倍频并为各子模块提供配套的时钟源.

3)内核相关的驱动文件core_cm3.h:内核的外设寄存器映射;core_cm3.c:内核的外设驱动固件库.

NVIC(嵌套向量中断控制器)描述文件:misc.h和misc.c.

4)外设相关的库文件stm32f10x.h:实现了内核之外的寄存器映射;stm32f10x_xx.c:外设的驱动函数库文件;

核外设备:GPIO、USRAT、I2C、SPI、FSMC等驱动文件.

5)头文件的配置文件stm32f10x_conf.h 头文件的配置文件,将多个外设的头文件进行统一调配管理,如:

stm32f10x_usart.h,stm32f10x_i2c.h,stm32f10x_spi.h,stm32f10x_adc.h,stm32f10x_fsmc.h...

对外设描述的结构体,映射地址的头文件都放在stm32f10x_conf.h中进行声明,使用时只需包含该配置头文件即可,并可通过“宏断言”函数进行选配.

6)专门注册中断服务函数的C文件:stm32f10x_it.c和stm32f10x_it.h.这些文件按照相应的规则分布在不同的路径下,这个规则就是ST集团与各芯片开发商共同制订的CMSIS标准[3].

3.2 工程项目构建

参照CMSIS标准创建项目文件以及组文件夹:CMSIS、FWlib、inc、src、Project、Output和User,并将固件库提供的基本源代码拷贝到对应目录下,如:项目文件创建并保存在Project路径下;核外外设的驱动程序复制到src源码目录下;对描述部件的寄存器结构体统一定义在inc头文件目录下;而直接针对任务而设计的程序文件通常放置在用户目录User中,如main()程序,中断服务程序等等.

在本例的电子时钟设计中,根据前面所介绍的定时器和LCD的工作原理,配置相关驱动程序或函数集,并写入预设的定时参数,重新组合、设计功能程序:1)计算并确定定时初值以及分频器参数;2)LCD 初始化机模式配置,设计变量显示程序;3)中断服务程序的数据处理部分程序设计.

3.3 程序设计

首先对定时器、中断寄存器、AFIO引脚以及液晶屏进行初始化设置,并将设计的参数值写入对应寄存器中;开启定时时钟和中断系统,主程序实时不间断显示时间——分位(min)和秒位(sec);中断服务程序完成定时器计数值的更新和处理,并将其转换成时间变量传回主程序显示,程序流程图见图3.

图3 程序流程图Fig.3 Program Flow Chart

4 结论

由于内部时钟源能提供1K~72MHz时钟信号,误差为±1%,则时钟误差最小可以控制在0. 01 us范围内.通过上述实验教学项目的开发,总结出32位微处理平台在工程实践中的设计流程:(1)任务分析:根据设计要求明确项目所需实现功能,提出设计方案主体框架、功能模块构成、技术实现路线;(2)搭建工程项目:根据STM32平台所提供资源,确定主控系统模块并搭建项目主体框架;对照现有资源匹配现有的子模块,制作与主系统的接口函数并确定底层部件参数;(3)主系统集成:完成主要业务的程序编制并进行系统整和调试.基于STM32平台的嵌入式系统开发,应采用立足于对系统资源的整合和集成的思维方式,将各部件的驱动程序看作一种供开发者使用的函数集合,开发者需要做的是将这些离散、抽象的“程序块”有机地进行组合,以搭积木的方式进行模块化设计,这才是嵌入式系统应用的本质所在.

猜你喜欢
外设固件寄存器
STM32和51单片机寄存器映射原理异同分析
Lite寄存器模型的设计与实现
移位寄存器及算术运算应用
基于SHA1的SCADA系统PLC固件完整性验证方法
基于UEFI固件的攻击验证技术研究*
基于固件的远程身份认证
提取ROM固件中的APP
Lx5280模拟器移植设计及实施
外设天地行情
外设天地行情