STM固件库详解

合集下载

stm32固件库函数使用keil时的常见错误分析

stm32固件库函数使用keil时的常见错误分析

stm32固件库函数使用keil时的常见错误分析error: A1355U: A Label was found which was in no AREA 终级解决办法分类:深入C语言2009-12-30 11:26208人阅读评论(0)收藏举报error: A1355U: A Label was found which was in no AREA 在KEIL工程中,我使用另一个工程中正确的分散加载文件到一个新工程中,竟然就出现这样的提示。

到网上搜索,有很多内容是关于这个问题的,但是却没有几个很好解决问题的。

其实出现这个问题有两种情况,一种是出现在.s的汇编文件中,另一种是出现在.scf (或者.scat)等的分散加载文件中。

原来很多人在汇编文件(多数为.s的启动代码)中出现这个问题的,基本上是因为使用汇编的格式不对,关于这个错误,ARM官网有相关的说明:A1355U: A Label was found which was in no AREAExample:This can occur where no white-space precedes an assembler directive.Assembler directives must be indented with white-space, for example:use:IF :DEF: FOO; codeENDIFnot:IF :DEF: FOO; codeENDIFSymbols in the left hand column 1 are assumed to be labels,hence the error message.意思是在编写汇编文件时,标号要顶格写,而其他的代码都要用空格或者TAB键来使代码进行缩进,这样,就不会出现编译的问题了。

如果问题是出现在分散加载文件中,那么很可能你是把分散加载文件一起加入到了KEIL的工程中,类似这样:这时候,就可能会出现error: A1355U: A Label was found which was in no AREA这样的报错,不管你用多么正确的SCATTER文件格式,它始终都会报错。

STM32 固件库中RCC_GetClocksFreq()函数注意事项

STM32 固件库中RCC_GetClocksFreq()函数注意事项

STM32 固件库中RCC_GetClocksFreq()函数注意事项在STM32 固件库中,当你使用RCC_GetClocksFreq()这个函数的时候,需要注意一下。

(比如,你在使用串口的USART_Init 的时候,就无形中使用到这个函数)。

当你使用外部晶振做为系统时钟的时候,而且外部晶振不是标准8MHz 的时候,你需要留意一下STM32 的固件库,里面的stm32f10x_rcc.c 这个文件,在它的RCC_GetClocksFreq()这个函数中,有这么一段voidRCC_GetClocksFreq(RCC_ClocksTypeDef* RCC_Clocks){u32 tmp = 0, pllmull = 0, pllsource = 0, presc = 0;/* Get SYSCLK source -*/tmp = RCC->CFGR & CFGR_SWS_Mask;switch (tmp){case 0 乘以00:/* HSI used as system clock */RCC_Clocks- >SYSCLK_Frequency = HSI_Value;break;case 0 乘以04:/* HSE used as system clock */RCC_Clocks- >SYSCLK_Frequency=HSE_Value;break;case 0 乘以08:/* PLL used as system clock *//* Get PLL clock source and multiplication factor -*/pllmull = RCC->CFGR & CFGR_PLLMull_Mask;pllmull = ( pllmull >> 18) + 2;pllsource = RCC->CFGR & CFGR_PLLSRC_Mask;if (pllsource == 0 乘以00){/* HSI oscillator clock divided by 2 selected as PLL clock entry */RCC_Clocks->SYSCLK_Frequency = (HSI_Value >> 1) * pllmull;}else{/* HSE selected as PLL clock entry */if ((RCC->CFGR & CFGR_PLLXTPRE_Mask) != (u32)RESET){/* HSE oscillator clock divided by 2 */。

STM32固件库v3.5变更指南

STM32固件库v3.5变更指南
v35多出选用以太网媒体界面iwdg无不同pwr无不同rccv20的所有函数均有另增加以下函数
STM32 固件库中文使用手册只到 V2.0,其后未再更新。本文就 V3.5 对 V2.0 的常用部件 变更做简要说明。
பைடு நூலகம்
无不同
ADC_
无不同
BKP_
DMA_
void DMA_SetCurrDataCounter(DMA_Channel_TypeDef* DataNumber); V3.5 多出 向通道 x 的 CNDTR 寄存器写入数据传输数量
#endif /* STM32F10X_CL */
#ifdef STM32F10X_CL void RCC_AHBPeriphResetCmd(uint32_t RCC_AHBPeriph, FunctionalState NewState); #endif /* STM32F10X_CL */
无不同
void TIM_SetIC1Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); V3.5 void TIM_SetIC2Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); V3.5 void TIM_SetIC3Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); V3.5 void TIM_SetIC4Prescaler(TIM_TypeDef* TIMx, uint16_t TIM_ICPSC); V3.5 void TIM1_SetIC1Prescaler(u16 TIM1_IC1Prescaler); V2.0 void TIM1_SetIC2Prescaler(u16 TIM1_IC2Prescaler); V2.0 void TIM1_SetIC3Prescaler(u16 TIM1_IC3Prescaler); V2.0 void TIM1_SetIC4Prescaler(u16 TIM1_IC4Prescaler); V2.0 功能:设置输入捕获预分频值(TIM_ICPSC_DIV1、TIM_ICPSC_DIV2、TIM_ICPSC_DIV4、 TIM_ICPSC_DIV8),分别为输入每 1、2、4 和 8 个边沿触发一次捕获

STM32 GPIO 配置之ODR, BSRR, BRR 详解

STM32 GPIO 配置之ODR, BSRR, BRR 详解

STM32 GPIO 配置之ODR, BSRR, BRR 详解用stm32 的配置GPIO 来控制LED 显示状态,可用ODR,BSRR,BRR 直接来控制引脚输出状态.ODR寄存器可读可写:既能控制管脚为高电平,也能控制管脚为低电平。

管脚对于位写1 gpio 管脚为高电平,写0 为低电平BSRR 只写寄存器:[color=Red]既能控制管脚为高电平,也能控制管脚为低电平。

对寄存器高16bit 写1 对应管脚为低电平,对寄存器低16bit写1对应管脚为高电平。

写0 ,无动作BRR 只写寄存器:只能改变管脚状态为低电平,对寄存器管脚对于位写1 相应管脚会为低电平。

写0 无动作。

刚开始或许你跟我一样有以下疑惑:1.既然ODR 能控制管脚高低电平为什么还需要BSRR和SRR寄存器?2.既然BSRR能实现BRR的全部功能,为什么还需要SRR寄存器?对于问题1 ------ 意法半导体给的答案是---“This way, there is no risk that an IRQ occurs between the read and the modify access.”什么意思呢?就就是你用BSRR和BRR去改变管脚状态的时候,没有被中断打断的风险。

也就不需要关闭中断。

用ODR操作GPIO的伪代码如下:disable_irq()save_gpio_pin_sate = read_gpio_pin_state();save_gpio_pin_sate = xxxx;chang_gpio_pin_state(save_gpio_pin_sate);enable_irq();关闭中断明显会延迟或丢失一事件的捕获,所以控制GPIO的状态最好还是用SBRR和BRR对于问题2 ------- 个人经验判断意法半导体仅仅是为了程序员操作方便估计做么做的。

因为BSRR的低16bsts 恰好是set操作,而高16bit是reset 操作而BRR 低16bits 是reset 操作。

flash做EEPROM用

flash做EEPROM用

STM32 本身没有自带 EEPROM,但是 STM32 具有 IAP(在应用编程)功能,所以我们可以把它的 FLASH 当成 EEPROM 来使用STM32 FLASH 简介不同型号的 STM32,其 FLASH 容量也有所不同,最小的只有 16K 字节,最大的则达到了1024K 字节。

战舰 STM32 开发板选择的 STM32F103ZET6 的 FLASH 容量为 512K 字节,属于大容量产品(另外还有中容量和小容量产品),STM32 的闪存模块由:主存储器、信息块和闪存存储器接口寄存器等 3 部分组成。

主存储器,该部分用来存放代码和数据常数(如 const 类型的数据)。

对于大容量产品,其被划分为 256 页,每页 2K 字节。

注意,小容量和中容量产品则每页只有 1K 字节。

从上图可以看出主存储器的起始地址就是 0X08000000, B0、B1 都接 GND 的时候,就是从 0X08000000开始运行代码的。

信息块,该部分分为 2 个小部分,其中启动程序代码,是用来存储 ST 自带的启动程序,用于串口下载代码,当 B0 接 V3.3,B1 接 GND 的时候,运行的就是这部分代码。

用户选择字节,则一般用于配置写保护、读保护等功能,闪存存储器接口寄存器,该部分用于控制闪存读写等,是整个闪存模块的控制机构。

闪存的读取内置闪存模块可以在通用地址空间直接寻址,任何 32 位数据的读操作都能访问闪存模块的内容并得到相应的数据。

读接口在闪存端包含一个读控制器,还包含一个 AHB 接口与 CPU 衔接。

这个接口的主要工作是产生读闪存的控制信号并预取 CPU 要求的指令块,预取指令块仅用于在 I-Code 总线上的取指操作,数据常量是通过 D-Code 总线访问的。

这两条总线的访问目标是相同的闪存模块,访问 D-Code 将比预取指令优先级高这里要特别留意一个闪存等待时间,因为 CPU 运行速度比 FLASH 快得多,STM32F103的 FLASH 最快访问速度≤24Mhz,如果 CPU 频率超过这个速度,那么必须加入等待时间,比如我们一般使用 72Mhz 的主频,那么 FLASH 等待周期就必须设置为 2,该设置通过 FLASH_ACR寄存器设置。

STM32内部FLASH读写操作详解

STM32内部FLASH读写操作详解

STM32芯片内部的FLASH存储器,主要用于存储我们代码。

如果内部FLASH存储完我们的代码还有剩余的空间,那么这些剩余的空间我们就可以利用起来,存储一些需要掉电保存的数据。

本文以STM32103ZET为例。

STM32103ZET属于大容量产品,其闪存模块组织如下:其主存储器大小为512KB分为256页,每页大小都为2KB我们的程序般默认烧写到第0页的起始地址(0x08000000)处。

当BOOT引脚和BOOT引脚都接GND寸,就是从这个地址开始运行代码的。

这个地址在keil中可以看到:F 面对STM32内部FLASH 进行简单的读写测试:内部FLASH 读写测试 流程图如下:本流程图省略异常情况,只考虑成功的情况:f-Q Options for Target 'FLASH'一丄Utvice Til i«l I Output ] Li itinc | Ustr | C/C++ | AsmLinker Debue Vtiiitws\tSTHicroetedonici SR32F103ZEOpef^g syseiTi : |Sysem \^ewer Rle.{MHi): Bll-Cod* GeniFon —ARM Compter: | Use default cwnpiter veraion 5刁厂 Lse Cjoss-^ottile OrtimiiatorIv Lse Micro LIBotCancelCeCa-olts Help假如我们要下载的程序大小为4.05KB , 则第0、1、2页用于保存我们的程序,我们需要掉电保存的数据只能保存在第 3~第255页这一部分空间内。

我们最终要下载的程序大小可在工程对应的 .map 文件中看到。

.map 文件可以双击工程的Target 的名字快速打开,如:hrlphdrt Tool ; SVM 応 inJ 艸 hti 単 ,-■k ,A 弟=*七住」Mitw J 咖3口知,樹;卜( J... —. ■丹 Ft E4R vl«* PiQjtit “Ml Dtbug•ffli11 htBj£画 IF b.农-I r sj fLASj- In 討mi■. 1.7 viieiiii '.L二KP;L 叭1祠£ -L 二El 仍恤■走r二匚 top.gt £Jt±』CMS5三Q StriPaiph thr.ci二uc4114出, + e 4H ULiJry T'^CiJbd Mt*LMb|HELL ・md " D*fca ] ■W Egf icrtBli 畤TCT P Hmucfi>n 3 Hlih —b kp C b4i-i3 Jhdn_c.driR.Hbloral HD Size Ifodt + ・□ palFl*Total R>I 51■疋c £RM Eta - Zr TZatJ) Totdg flW S 上电 jt 屁It + 觀尿H * 也 G SU TL Use CustziEFife示例代码:本例的关键代码如下(以读写第255页为例):/******************************************************************************************************** -------------------------------------- STM32 Demo ------------------------工程说明:STM32内部FLASH实验作者:ZhengNian博客: zhengnianli.github.io公众号:嵌入式大杂烩********************************************************************************************************/#defi ne MAIN_CONFIG#i nclude "con fig.h"/* STM32F103ZET6有256页,每一页的大小都为2KB */#defi ne ADDR_FLASH _P AGE_255 ((ui nt32_t)0x0807F800) /* Page255 2KB *//* FLASH读写测试结果*/#defi ne #defi ne #defi ne/* Flash 读写测试buf */ #defi ne BufferSize 6ui nt16_t usFlashWriteBuf[BufferSize]= {0x0101,0x0202,0x0303,0x0404,0x0505,0x0606}; ui nt16_t usFlashReadBuf[BufferSize] = {0};/*供本文件调用的函数声明*/ static int FlashReadWriteTest(void);*********************************** ** 函数:main参数:void 返回:无 说明:主函数********************************************************************* ***********************************/ int main(v oid) {/*上电初始化*/ Sysl nit();/*内部Flash 读写测试*/if (TEST_SUCCESS == FlashReadWriteTest()) prin tf("Flash test success!' n"); } else {prin tf("Flash test failed!\n"); } while (1) {} }*************************************函数:FlashReadWriteTest ,内部Flash 读写测试函数 ** 参数:void**返回:TEST_ERROR :错误(擦除、写入错误) TEST_SUCCESS:成功TEST_FAILED :失败 **说明:无********************************************************************************************************/ static int FlashReadWriteTest(void) {TEST_ERROR -1 TEST_SUCCESS 0 TEST_FAILED 1 /*/*错误(擦除、写入错误)*/ /*成功*/失败*/uin t32_t ucStartAddr;/*解锁*/FLASH_U nIockO;/*擦除操作*/ ucStartAddr = ADDR_FLASH _P AGE_255;if (FLASH_CO MP LETE != FLAsH_Erase Page(ucStartAddr)) { prin tf("Erase Error!\n"); return TEST_ERROR;}elseucStartAddr = ADDR_FLASH _P AGE_255;printf("擦除成功,此时FLASH中值为:\n");for (i nt i = 0; i < BufferSize; i++){usFlashReadBuf[i] = *(ui nt32_t*)ucStartAddr;prin tf("ucFlashReadBuf[%d] = 0x%.4x\n", i, usFlashReadBuf[i]); ucStartAddr += 2;}}/*写入操作*/ucStartAddr = ADDR_FLASH _P AGE_255;printf("\n往FLASH中写入的数据为:\n");for (i nt i = 0; i < BufferSize; i++){if (FLASH_CO MP LETE != FLASH _P rogramHalfWord(ucStartAddr, usFlashWriteBuf[i])) {prin tf("Write Error!\n");return TEST_ERROR;} "prin tf("ucFlashWriteBuf[%d] = 0x%.4x\n", i, usFlashWriteBuf[i]); ucStartAddr += 2;} /*上锁*/ FLASH_Lock();/*读取操作*/ucStartAddr = ADDR_FLASH _P AGE_255;printf("\n 从FLASH 中读出的数据为:\n"); for (i nt i = 0; i < BufferSize; i++) {usFlashReadBuf[i] = *(__10 uin t16_t*)ucStartAddr;prin tf("ucFlashReadBuf[%d] = 0x%.4x\n", i, usFlashReadBuf[i]); ucStartAddr += 2; }/*读出的数据与写入的数据做比较*/ for (i nt i = 0; i < BufferSize; i++) {if (usFlashReadBuf[i] != usFlashWriteBuf[i]) {return TEST_FAILED; } }return TEST_SUCCESS; }/******************************************************************** *************************************** End Of File********************************************************************* ***********************************/(1)进行解锁操作STM32的闪存编程是由内嵌的闪存编程/擦除控制器(FPEC )管理,这个模块包含的寄存器如下:STM32复位后,FPEC 模块是被保护的, 不能写入FLASH_CR 寄存器;通 过写入特定的序列到FLASH_KEYF 寄存器可以打开FPEC 模块(即写入KEY1和KEY2 ,只有在写保护被解除后,我们才能操作相关寄存器。

4.ST MC SDK 5.x WB应用指南和固件详解

4.ST MC SDK 5.x WB应用指南和固件详解

ST MC SDK 5.x WB应用指南和固件详解STM32电动机控制应用系列讲座之四目录2❑ST MC SDK5.x WB应用指南▪软件工具的下载和安装▪ST MC Workbench及关键配置参数▪MC Project 的生成,编译和下载▪电机控制及监控❑ST MC SDK5.x固件详解▪程序架构▪组件▪例程代码讲解▪开发实战如何向例程中添加外设和自己的代码Step-by-Step添加一段闪灯代码ST MC SDK5.x WB 应用指南❑ST MC SDK5.x WB 应用指南▪软件工具的下载和安装▪ST MC Workbench 及关键配置参数▪MC Project 的生成,编译和下载▪电机控制及监控❑ST MC SDK5.x 固件详解▪程序架构▪组件▪例程代码讲解▪开发实战如何向例程中添加外设和自己的代码Step-by-Step 添加一段闪灯代码软件工具的安装4请预先安装下列PC 软件工具:•X-CUBE-MCSDK 或X-CUBE-MCSDK-FUL •STM32CubeMX (v4.25.1/v4.26.1)及固件库•ST-LINK/V2 (v4.2.0)•IDE:−IAR Embedded Workbench for Arm (v7.80.4/v8.20.2)−μVision® IDE for Arm® (Keil® MDK) v5.25−Atollic TrueSTUDIO for STM32 version 9.0.0STM32CubeMX 请不要安装在中文路径下!!软件启动5下列方式可启动ST MC Workbench软件工具:•单击其图标•从安装文件夹路径直接启动Workbench61231.用户按钮区用于创建新项目,加载已有项目或启动ST电机参数测量工具。

2.最近的项目区用于加载近期的项目。

3.例程区用于加载项目示例。

创建新工程7硬件配置窗口8图标和菜单区硬件信息硬件细节设定按钮区用户信息主要的硬件配置Workbench菜单(1)9✓New Project: 创建一个新项目✓Open Project…: 打开一个现有的项目✓Close Project: 关闭现在的项目✓Save Project: 使用相同文件名保存打开的项目✓Save Project As…: 将打开的项目保存为指定的文件名✓Properties: 查看项目属性✓Recent List: 从最近打开过的项目列表中加载一个现有项目✓Recent List Delete: 删除最近的项目列表✓Exit: 从硬件配置窗口退出Workbench菜单(2)10✓Pin assignment:检查MCU的引脚分配和剩余的可用引脚✓Generation:根据所选的IDE,生成MC应用工程文件✓Monitor:监控并转动电机✓Clear Log:清除用户信息表✓Export Log: 将用户信息表以文本格式导出到日志文件✓Restore Info Message: 需要时显示用户信息表Workbench菜单(3)11工具栏图标12✓New:创建一个新项目✓Load:打开一个现有的项目✓Save:使用相同文件名保存打开的项目✓Clear Log:清除用户信息表✓Pin assignment :检查MCU的引脚分配和剩余的可用引脚✓Generation: 根据所选的IDE,生成MC应用工程文件.✓Click to open monitor: 监控并转动电机✓Help: 提供在线帮助文件的访问接口✓About: 显示该应用的版本号硬件细节设定按钮区13根据客户需求快速设置电机库电机参数硬件驱动驱动控制管理单片机相关电机参数14电机15 马达参数配置极对数最大转速最大电流额定电压电机相电阻电机电感电机发电常数电机转动惯量电机阻力系数电机d轴电感电机q轴电感d轴电感和q轴电感比率16传感器Hall同步电角度:•电机Hall A的上升沿到电机A相反电动势最高点的延迟角度。

4.ST MC SDK 5.x WB应用指南和固件详解

4.ST MC SDK 5.x WB应用指南和固件详解

ST MC SDK 5.x WB应用指南和固件详解STM32电动机控制应用系列讲座之四目录2❑ST MC SDK5.x WB应用指南▪软件工具的下载和安装▪ST MC Workbench及关键配置参数▪MC Project 的生成,编译和下载▪电机控制及监控❑ST MC SDK5.x固件详解▪程序架构▪组件▪例程代码讲解▪开发实战如何向例程中添加外设和自己的代码Step-by-Step添加一段闪灯代码© 2018 STMicroelectronics -保留所有权利© 2018 STMicroelectronics -保留所有权利ST MC SDK5.x WB 应用指南❑ST MC SDK5.x WB 应用指南▪软件工具的下载和安装▪ST MC Workbench 及关键配置参数▪MC Project 的生成,编译和下载▪电机控制及监控❑ST MC SDK5.x 固件详解▪程序架构▪组件▪例程代码讲解▪开发实战如何向例程中添加外设和自己的代码Step-by-Step 添加一段闪灯代码© 2018 STMicroelectronics -保留所有权利软件工具的安装4请预先安装下列PC 软件工具:•X-CUBE-MCSDK 或X-CUBE-MCSDK-FUL •STM32CubeMX (v4.25.1/v4.26.1)及固件库•ST-LINK/V2 (v4.2.0)•IDE:−IAR Embedded Workbench for Arm (v7.80.4/v8.20.2)−μVision® IDE for Arm® (Keil® MDK) v5.25−Atollic TrueSTUDIO for STM32 version 9.0.0STM32CubeMX 请不要安装在中文路径下!!。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

S T M32固件库详解基于标准外设库的软件开发STM32标准外设库概述STM32标准外设库之前的版本也称固件函数库或简称固件库,是一个固件函数包,它由程序、数据结构和宏组成,包括了微控制器所有外设的性能特征。

该函数库还包括每一个外设的驱动描述和应用实例,为开发者访问底层硬件提供了一个中间API,通过使用固件函数库,无需深入掌握底层硬件细节,开发者就可以轻松应用每一个外设。

因此,使用固态函数库可以大大减少用户的程序编写时间,进而降低开发成本。

每个外设驱动都由一组函数组成,这组函数覆盖了该外设所有功能。

每个器件的开发都由一个通用API (application programming interface 应用编程界面)驱动,API对该驱动程序的结构,函数和参数名称都进行了标准化。

ST公司2007年10月发布了版本的固件库,MDK 之前的版本均支持该库。

2008年6月发布了版的固件库,从2008年9月推出的MDK 版本至今均使用版本的固件库。

以后的版本相对之前的版本改动较大,本书使用目前较新的版本。

使用标准外设库开发的优势简单的说,使用标准外设库进行开发最大的优势就在于可以使开发者不用深入了解底层硬件细节就可以灵活规范的使用每一个外设。

标准外设库覆盖了从GPIO到定时器,再到CAN、I2C、SPI、UART和ADC等等的所有标准外设。

对应的C源代码只是用了最基本的C编程的知识,所有代码经过严格测试,易于理解和使用,并且配有完整的文档,非常方便进行二次开发和应用。

STM32F10XXX标准外设库结构与文件描述1. 标准外设库的文件结构可以从ST的官方网站下载到各种版本的标准外设库,首先看一下版本标准外设库的文件结构,如图 5-3所示。

以上版本的文件结构大致相同,每个版本可能略有调整。

图 5-3 STM32F10XXX 标准外设库文件结构表 5-4中介绍了每个文件夹所包含的主要内容。

表 5-4 STM32F10XXX 标准外设库文件夹描述标准外设库的第一部分是CMSIS 和STM32F10x_StdPeriph_Driver,CMSIS 是独立于供应商的Cortex-M 处理器系列硬件抽象层,为芯片厂商和中间件供应商提供了简单的处理器软件接口,简化了软件复用工作,降低了Cortex-M 上操作系统的移植难度,并减少了新入门的微控制器开发者的学习曲线和新产品的上市时间。

STM32F10x_StdPeriph_Driver则包括了分别对应包括了所有外设对应驱动函数,这些驱动函数均使用C语言编写,并提供了统一的易于调用的函数接口,供开发者使用。

Project文件夹中则包括了ST官方的所有例程和基于不同编译器的项目模板,这些例程是学习和使用STM32的重要参考。

Utilities 包含了相关评估板的示例程序和驱动函数,供使用官方评估板的开发者使用,很多驱动函数同样可以作为学习的重要参考。

STM32F10xxx标准外设库体系结构如图 5-4所示。

图中很好的展示了各层以及具体文件之间的联系,各文件的具体功能说明如表 5-5所示。

图 5-4 STM32F10xxx标准外设库体系结构表 5-5 文件功能说明2. 基于CMSIS标准的软件架构根据调查研究,软件开发已经被嵌入式行业公认为最主要的开发成本。

对于ARM公司来说,一个ARM内核往往会授权给多个厂家,生产种类繁多的产品,如果没有一个通用的软件接口标准,那么当开发者在使用不同厂家的芯片时将极大的增加了软件开发成本,因此,ARM 与Atmel、IAR、Keil、hami-nary Micro、Micrium、NXP、SEGGER和ST等诸多芯片和软件厂商合作,将所有Cortex芯片厂商产品的软件接口标准化,制定了CMSIS标准。

此举意在降低软件开发成本,尤其针对新设备项目开发,或者将已有软件移植到其他芯片厂商提供的基于Cortex处理器的微控制器的情况。

有了该标准,芯片厂商就能够将他们的资源专注于产品外设特性的差异化,并且消除对微控制器进行编程时需要维持的不同的、互相不兼容的标准的需求,从而达到降低开发成本的目的。

如图 5-5所示,基于CMSIS标准的软件架构主要分为以下4层:用户应用层、操作系统及中间件接口层、CMSIS层、硬件寄存器层。

其中CMSIS层起着承上启下的作用:一方面该层对硬件寄存器层进行统一实现,屏蔽了不同厂商对Cortex-M系列微处理器核内外设寄存器的不同定义;另一方面又向上层的操作系统及中间件接口层和应用层提供接口,简化了应用程序开发难度,使开发人员能够在完全透明的情况下进行应用程序开发。

也正是如此,CMSIS层的实现相对复杂。

图 5-5 CMSIS标准的软件架构层主要分为以下3 个部分:(1) 核内外设访问层(CPAL,Core Peripheral Access Layer):该层由ARM 负责实现。

包括对寄存器名称、地址的定义,对核寄存器、NVIC、调试子系统的访问接口定义以及对特殊用途寄存器的访问接口(例如:CONTROL,xPSR)定义。

由于对特殊寄存器的访问以内联方式定义,所以针对不同的编译器ARM 统一用来屏蔽差异。

该层定义的接口函数均是可重入的。

(2) 片上外设访问层(DPAL, Device Peripheral Access Layer):该层由芯片厂商负责实现。

该层的实现与CPAL 类似,负责对硬件寄存器地址以及外设访问接口进行定义。

该层可调用CPAL 层提供的接口函数同时根据设备特性对异常向量表进行扩展,以处理相应外设的中断请求。

(3) 外设访问函数(AFP, Access Functions for Peripherals):该层也由芯片厂商负责实现,主要是提供访问片上外设的访问函数,这一部分是可选的。

对一个Cortex-M 微控制系统而言,CMSIS 通过以上三个部分实现了:l 定义了访问外设寄存器和异常向量的通用方法;l 定义了核内外设的寄存器名称和核异常向量的名称;l 为RTOS 核定义了与设备独立的接口,包括Debug 通道。

这样芯片厂商就能专注于对其产品的外设特性进行差异化,并且消除他们对微控制器进行编程时需要维持的不同的、互相不兼容的标准需求,以达到低成本开发的目的。

CMSIS 中的具体文件结构如表 5-6所示。

表 5-6 CMSIS文件夹结构在实际开发过程中,根据应用程序的需要,可以采取2种方法使用标准外设库(StdPeriph_Lib):(1) 使用外设驱动:这时应用程序开发基于外设驱动的API(应用编程接口)。

用户只需要配置文件””,并使用相应的文件”.c”即可。

(2) 不使用外设驱动:这时应用程序开发基于外设的寄存器结构和位定义文件。

这两种方法的优缺点在“使用标准外设库开发的优势”小节中已经有了具体的介绍,这里仍要说明的是,使用使用标准外设库进行开发可以极大的减小软件开发的工作量,也是目前嵌入式系统开发的一个趋势。

标准外设库(StdPeriph_Lib)支持STM32F10xxx系列全部成员:大容量,中容量和小容量产品。

从表 5-6中也可以看出,启动文件已经对不同的系列进行了划分,实际开发中根据使用的STM32产品具体型号,用户可以通过文件””中的预处理define或者通过开发环境中的全局设置来配置标准外设库(StdPeriph_Lib),一个define对应一个产品系列。

下面列出支持的产品系列STM32F10x_LD:STM32小容量产品STM32F10x_MD:STM32中容量产品STM32F10x_HD:STM32大容量产品在库文件中这些define的具体作用范围是:l 文件“”中的中断IRQ定义l 启动文件中的向量表,小容量,中容量,大容量产品各有一个启动文件l 外设存储器映像和寄存器物理地址l 产品设置:外部晶振(HSE)的值等l 系统配置函数因此通过宏定义这种方式,可以使标准外设库适用于不同系列的产品,同时也方便与不同产品之间的软件移植,极大的方便了软件的开发。

STM32F10XXX标准外设库的使用标准外设库中包含了众多的变量定义和功能函数,如果不能了解他们的命名规范和使用规律将会给编程带来很大的麻烦,本节将主要叙述标准外设库中的相关规范,通过这些规范的学习可以更加灵活的使用固件库,同时也将极大增强程序的规范性和易读性,同时标准外设库中的这种规范也值得我们在进行其他相关的开发时使用和借鉴。

1. 缩写定义标准外设库中的主要外设均采用了缩写的形式,通过这些缩写可以很容易的辨认对应的外设。

2. 命名规则标准外设库遵从以下命名规则?PPP表示任一外设缩写,例如:ADC。

源程序文件和头文件命名都以“stm32f10x_”作为开头,例如:。

常量仅被应用于一个文件的,定义于该文件中;被应用于多个文件的,在对应头文件中定义。

所有常量都由英文字母大写书写。

寄存器作为常量处理。

他们的命名都由英文字母大写书写。

在大多数情况下,他们采用与缩写规范一致。

外设函数的命名以该外设的缩写加下划线为开头。

每个单词的第一个字母都由英文字母大写书写,例如:SPI_SendData。

在函数名中,只允许存在一个下划线,用以分隔外设缩写和函数名的其它部分。

对于函数命名,总的来说有以下规则:l 名为PPP_Init的函数,其功能是根据PPP_InitTypeDef中指定的参数,初始化外设PPP,例如TIM_Init.l 名为PPP_DeInit的函数,其功能为复位外设PPP的所有寄存器至缺省值,例如TIM_DeInit.l 名为PPP_Init的函数,其功能为通过设置PPP_InitTypeDef 结构中的各种参数来定义外设的功能,例如:USART_Init .l 名为PPP_Cmd的函数,其功能为使能或者失能外设PPP,例如: SPI_Cmd.l 名为PPP_ITConfig的函数,其功能为使能或者失能来自外设PPP某中断源,例如:RCC_ITConfig.l 名为PPP_DMAConfig的函数,其功能为使能或者失能外设PPP的DMA接口,例如:TIM1_DMAConfig.l 用以配置外设功能的函数,总是以字符串“Config”结尾,例如GPIO_PinRemapConfig.l 名为PPP_GetFlagStatus的函数,其功能为检查外设PPP某标志位被设置与否,例如:I2C_GetFlagStatus.l 名为PPP_ClearFlag的函数,其功能为清除外设PPP标志位,例如:I2C_ClearFlag.l 名为PPP_GetITStatus的函数,其功能为判断来自外设PPP的中断发生与否,例如:I2C_GetITStatus.l 名为PPP_ClearITPendingBit的函数,其功能为清除外设PPP中断待处理标志位,例如:I2C_ClearITPendingBit.这样的命名方式非常便于程序的编写和阅读,以标准外设库中的示例函数为例,下面摘录了STM32F10x_StdPeriph_Examples\ADC\3ADCs_DMA\中的一段程序。

相关文档
最新文档