STM32三种开发方式及其区别

发布者:温馨家园最新更新时间:2024-04-18 来源: elecfans关键字:STM32  配置寄存器 手机看文章 扫描二维码
随时随地手机看文章


多实例支持:每个外设/模块实例都有自己的句柄。因此,实例资源是独立的

下面,以ADC为例


外围进程相互通信:该句柄用于管理进程例程之间的共享数据资源。

/** 

 * @brief  ADC handle Structure definition

 */ 

typedef struct

{

 ADC_TypeDef                   *Instance;                   /*!< Register base address */

 ADC_InitTypeDef               Init;                        /*!< ADC required parameters */

  __IO uint32_t                 NbrOfCurrentConversionRank;  /*!< ADC number of current conversion rank */

 DMA_HandleTypeDef             *DMA_Handle;                 /*!< Pointer DMA Handler */

 HAL_LockTypeDef               Lock;                        /*!< ADC locking object */

 __IO uint32_t                 State;                       /*!< ADC communication state */

 __IO uint32_t                 ErrorCode;                   /*!< ADC Error code */

}ADC_HandleTypeDef;

  从上面的定义可以看出,ADC_HandleTypeDef中包含了ADC可能出现的所有定义,对于用户想要使用ADC只要定义一个ADC_HandleTypeDef的变量,给每个变量赋好值,对应的外设就抽象完了。接下来就是具体使用了。


   当然,对于那些共享型外设或者说系统外设来说,他们不需要进行以上这样的抽象,这些部分与原来的标准外设库函数基本一样。例如以下外设:


GPIO


SYSTICK


NVIC


RCC


FLASH


  以GPIO为例,对于HAL_GPIO_Init() 函数,其只需要GPIO 地址以及其初始化参数即可。


2、 三种编程方式

HAL库对所有的函数模型也进行了统一。在HAL库中,支持三种编程模式:轮询模式、中断模式、DMA模式(如果外设支持)。其分别对应如下三种类型的函数(以ADC为例):


HAL_StatusTypeDef HAL_ADC_Start(ADC_HandleTypeDef* hadc);

HAL_StatusTypeDef HAL_ADC_Stop(ADC_HandleTypeDef* hadc);


HAL_StatusTypeDef HAL_ADC_Start_IT(ADC_HandleTypeDef* hadc);

HAL_StatusTypeDef HAL_ADC_Stop_IT(ADC_HandleTypeDef* hadc);


HAL_StatusTypeDef HAL_ADC_Start_DMA(ADC_HandleTypeDef* hadc, uint32_t* pData, uint32_t Length);

HAL_StatusTypeDef HAL_ADC_Stop_DMA(ADC_HandleTypeDef* hadc);

   其中,带_IT的表示工作在中断模式下;带_DMA的工作在DMA模式下(注意:DMA模式下也是开中断的);什么都没带的就是轮询模式(没有开启中断的)。至于使用者使用何种方式,就看自己的选择了。


  此外,新的HAL库架构下统一采用宏的形式对各种中断等进行配置(原来标准外设库一般都是各种函数)。针对每种外设主要由以下宏:


__HAL_PPP_ENABLE_IT(HANDLE, INTERRUPT): 使能一个指定的外设中断

__HAL_PPP_DISABLE_IT(HANDLE, INTERRUPT):失能一个指定的外设中断

__HAL_PPP_GET_IT (HANDLE, __ INTERRUPT __):获得一个指定的外设中断状态

__HAL_PPP_CLEAR_IT (HANDLE, __ INTERRUPT __):清除一个指定的外设的中断状态

__HAL_PPP_GET_FLAG (HANDLE, FLAG):获取一个指定的外设的标志状态

__HAL_PPP_CLEAR_FLAG (HANDLE, FLAG):清除一个指定的外设的标志状态

__HAL_PPP_ENABLE(HANDLE) :使能外设

__HAL_PPP_DISABLE(HANDLE) :失能外设

__HAL_PPP_XXXX (HANDLE, PARAM) :指定外设的宏定义

_HAL_PPP_GET IT_SOURCE (HANDLE, __ INTERRUPT __):检查中断源

3、 三大回调函数

  在HAL库的源码中,到处可见一些以__weak开头的函数,而且这些函数,有些已经被实现了,比如:


__weak HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)

{

 /*Configure the SysTick to have interrupt in 1ms time basis*/

 HAL_SYSTICK_Config(SystemCoreClock/1000U);

 /*Configure the SysTick IRQ priority */

 HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority ,0U);

 /* Return function status */

 return HAL_OK;

}

有些则没有被实现,例如:


__weak void HAL_SPI_TxCpltCallback(SPI_HandleTypeDef *hspi)

{

  /* Prevent unused argument(s) compilation warning */

  UNUSED(hspi);

  /* NOTE : This function should not be modified, when the callback is needed,the HAL_SPI_TxCpltCallback should be implemented in the user file

  */

}

   所有带有__weak关键字的函数表示,就可以由用户自己来实现。如果出现了同名函数,且不带__weak关键字,那么连接器就会采用外部实现的同名函数。


  通常来说,HAL库负责整个处理和MCU外设的处理逻辑,并将必要部分以回调函数的形式给出到用户,用户只需要在对应的回调函数中做修改即可。HAL库包含如下三种用户级别回调函数(PPP为外设名):


1、外设系统级初始化/解除初始化回调函数(用户代码的第二大部分:对于MSP的处理):

HAL_PPP_MspInit()和 HAL_PPP_MspDeInit**


例如:


__weak void HAL_SPI_MspInit(SPI_HandleTypeDef *hspi)。


在HAL_PPP_Init() 函数中被调用,用来初始化底层相关的设备(GPIOs, clock, DMA, interrupt)


2、处理完成回调函数:HAL_PPP_ProcessCpltCallback*(Process指具体某种处理,如UART的Tx),

例如:


__weak void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi)

当外设或者DMA工作完成后时,触发中断,该回调函数会在外设中断处理函数或者DMA的中断处理函数中被调用错误处理回调函数:


HAL_PPP_ErrorCallback

例如:


__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef hspi)*

3、当外设或者DMA出现错误时,触发终端,该回调函数会在外设中断处理函数或者DMA的中断处理函数中被调用

错误处理回调函数:


HAL_PPP_ErrorCallback

例如:


__weak void HAL_SPI_ErrorCallback(SPI_HandleTypeDef hspi)*

  当外设或者DMA出现错误时,触发终端,该回调函数会在外设中断处理函数或者DMA的中断处理函数中被调用。


  绝大多数用户代码均在以上三大回调函数中实现。


  HAL库结构中,在每次初始化前(尤其是在多次调用初始化前),先调用对应的反初始化(DeInit)函数是非常有必要的。


某些外设多次初始化时不调用返回会导致初始化失败。完成回调函数有多中,例如串口的完成回调函数有


HAL_UART_TxCpltCallback 

HAL_UART_TxHalfCpltCallback

  (用户代码的第三大部分:对于上面第二点和第三点的各种回调函数的处理)在实际使用中,发现HAL仍有不少问题,例如在使用USB时,其库配置存在问题。


HAL库移植使用

基本步骤:


1、复制stm32f2xx_hal_msp_template.c,参照该模板,依次实现用到的外设的HAL_PPP_MspInit()和 HAL_PPP_MspDeInit。


2、复制stm32f2xx_hal_conf_template.h,用户可以在此文件中自由裁剪,配置HAL库。


3、在使用HAL库时,必须先调用函数:HAL_StatusTypeDef HAL_Init(void)(该函数在stm32f2xx_hal.c中定义,也就意味着第一点中,必须首先实现HAL_MspInit(void)和HAL_MspDeInit(void))


4、HAL库与STD库不同,HAL库使用RCC中的函数来配置系统时钟,用户需要单独写时钟配置函数(STD库默认在system_stm32f2xx.c中)


5、关于中断,HAL提供了中断处理函数,只需要调用HAL提供的中断处理函数。用户自己的代码,不建议先写到中断中,而应该写到HAL提供的回调函数中。


6、对于每一个外设,HAL都提供了回调函数,回调函数用来实现用户自己的代码。整个调用结构由HAL库自己完成。


例如:


Uart中,HAL提供了


void HAL_UART_IRQHandler(UART_HandleTypeDef *huart);

函数,用户只需要触发中断后,用户只需要调用该函数即可,同时,自己的代码写在对应的回调函数中即可!如下:


void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart);

void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart);

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart);

void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *huart);

void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart);

使用了哪种就用哪个回调函数即可!


基本结构


综上所述,使用HAL库编写程序(针对某个外设)的基本结构(以串口为例)如下:


1、 配置外设句柄 例如,建立UartConfig.c,在其中定义串口句柄 UART_HandleTypeDef huart;接着使用初始化句柄(HAL_StatusTypeDef HAL_UART_Init(UART_HandleTypeDef huart))


2、编写Msp 例如,建立UartMsp.c,在其中实现void HAL_UART_MspInit(UART_HandleTypeDef huart) 和 void HAL_UART_MspDeInit(UART_HandleTypeDef* huart)


3、实现对应的回调函数 例如,建立UartCallBack.c,在其中实现上文所说明的三大回调函数中的完成回调函数和错误回调函数


[1] [2]
关键字:STM32  配置寄存器 引用地址:STM32三种开发方式及其区别

上一篇:使用国民技术的N32替换STM32的操作流程
下一篇:STM32等单片机程序加密有哪些方法

推荐阅读最新更新时间:2024-11-13 16:46

STM32开发 -- Jlink常用命令
h speed 4000 device = STM32F429ZI erase loadbin BOOT.bin 0x8000000 loadbin 正式版本.bin 0x08004000 loadbin 工厂测试.bin 0x08020000 savebin 工厂生产.bin 0x08000000 0x00080000 rx 3 qc exit 一直在用这个脚本烧写程序,但是,细细一看有点懵。 里面 h,rx 3,qc 等的含义不太清楚。 接下来详细总结一下,Jlink都还有哪些常用的命令。 一、查看jlink命令 使用的jlink版本如下图: jlink命令: J-Link ? Available comma
[单片机]
<font color='red'>STM32</font>开发 -- Jlink常用命令
STM32 NVIC笔记
看了一天的stm32的中断配置,对NVIC有了基本的了解(要了解NVIC,可以看《cortex M3权威指南》)。总结为3步: 1.设置中断分组寄存器 AIRCR 共0~4五组。地址:0xe000E_d00C 2.设置对应中断优先级 NVIC- IPR x=0~15配置60个中断优先级,每个中断一字节控制,只用到高4位 地址:0xE000_E400 3.使能对应中断 NVIC- ISER x=0~1 每一位对应一个外部中断使能 地址:0xE00_E100 void exti_init()//外部中断15~10 中断编号:40 { RCC- APB2ENR|=1 0; //开启复用时钟 RCC- APB2ENR
[单片机]
STM32 ILI9341驱动TFTLCD屏(一)
TFTLCD是薄膜晶体管液晶显示器。TFTLCD具有亮度好,对比度高,层次感强,颜色鲜艳等优点,是目前最主流的LCD显示器 ,广泛用于电视,手机,电脑,平板等各种的电子产品。 LCD原理图 LCD_CS为芯片选择输入引脚(“低”启用)。 RS用于在并行接口中选择“数据或命令”,当RS为1时,数据被选中;当RS为0时,命令被选中。 WR作为写信号,上升沿写入数据。 RD作为读取信号,上升沿读取数据。 RST为硬复位LCD信号。 D0-D15为16位双向数据线。 BL为背光灯控制信号。 MISO/MOSI/T_PEN/T_CS/CLK为触摸屏接口信号,本节暂不做介绍。 引脚分配为: LCD_CS:PG12、RS:PF12、WR
[单片机]
<font color='red'>STM32</font> ILI9341驱动TFTLCD屏(一)
基于STM32的自动量程电压表的设计方案
方案中的整个系统可以用一块9V电池供电,实现了低功耗和便携功能。交流测量是用AD637真有效值转换芯片将交流信号转换成直流电压后测量;用带钳位保护的反向放大器进行输入电压转换,实现了10MΩ的输入阻抗和高安全性。电路中关键器件采用TI公司的精密运算放大器OPA07和仪表放大器INA128,实现了高精度的测量;ADC采用STM32f103ZET6片内自带的12位AD,实现了低功耗,量程自动切换功能。 0 引言 在智能仪器中,常常用到自动量程转换技术,这使得仪器在很短的时间内自动选取最合适的量程实现高精度的测量。自动量程的实现一般通过控制输入信号的衰减放大倍数实现,就电压表来说其输入测量电压会大于其AD 转换器的输入范围,所以
[单片机]
基于<font color='red'>STM32</font>的自动量程电压表的设计方案
STM32新建keil工程具体步骤(详细)
1. 新建本地工程文件夹 在本地电脑上新建一个“工程模板”文件夹,在它之下再新建 6 个文件夹: 2.添加库文件到相应文件夹 把 ST 标准库必要的文件复制到工程模版对应文件夹的目录下 3.KEIL5新建工程 打开 KEIL5,新建一个工程,文件名自拟,工程放在Project目录下。 保存后弹出芯片选择,要根据自己芯片的型号提前按照PACK包,选择型号后点击OK。 随后弹出在线添加库文件,关闭即可。 4.添加组文件夹 在新建的工程中添加常用的文件夹,用来存放不同的文件。 5.添加文件 在新建的工程中添加这些文件,双击组文件夹就会出现添加文件的路径,然后选择文件即可。 6.配置魔术棒选
[单片机]
<font color='red'>STM32</font>新建keil工程具体步骤(详细)
STM32—HAL库中GPIO相关函数解析
背景: 最近一直在学习HAL库,总结下STM32中HAL库的GPIO相关函数知识点。 内容: 在stm32l152xb.h头文件中定义了GPIO的相关寄存器,下面讲述的GPIO函数将会调用到这些寄存器。寄存器的结构体定义如下图: 下面解析stm32l1xx_hal_gpio.c文件中一些常用的GPIO函数: (1)GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { GPIO_Pi
[单片机]
这8种STM32中GPIO工作模式,你都知道吗?
一、推挽输出:可以输出高、低电平,连接数字器件;推挽结构一般是指两个三极管分别受两个互补信号的控制,总是在一个三极管导通的时候另一个截止。高低电平由IC的电源决定。 推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。 二、开漏输出:输出端相当于三极管的集电极,要得到高电平状态需要上拉电阻才行。适合于做电流型的驱动,其吸收电流的能力相对强(一般20mA以内)。开漏形式的电路有以下几个特点: 1、利用外部电
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved