STM32的三种开发方式 HAL库固件库安装与用户手册

发布者:美好未来最新更新时间:2024-06-11 来源: elecfans关键字:STM32  HAL库  固件库 手机看文章 扫描二维码
随时随地手机看文章

  相比较早几年使用标准库开发来讲,最近几年HAL库的使用是越来越多,那么我们开发应当使用哪一种呢,本文着重介绍常用的几种开发方式及相互之间的区别,白猫也好、黑猫也好,抓到耗子就是好猫。

STM32的三种开发方式

  通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的。一般大多数都会选用标准库和HAL库,而极少部分人会通过直接配置寄存器进行开发。


  网上关于标准库、HAL库的描述相信是数不胜数。可是一个对于很多刚入门的朋友还是没法很直观的去真正了解这些不同开发发方式彼此之间的区别,所以笔者想以一种非常直白的方式,用自己的理解去将这些东西表述出来,如果有描述的不对的地方或者是不同意见的也可以大家提出。

1、直接配置寄存器

  不少先学了51的朋友可能会知道,会有一小部分人或是教程是通过汇编语言直接操作寄存器实现功能的,这种方法到了STM32就变得不太容易行得通了,因为STM32的寄存器数量是51单片机的十数倍,如此多的寄存器根本无法全部记忆,开发时需要经常的翻查芯片的数据手册,此时直接操作寄存器就变得非常的费力了。但还是会有很小一部分人,喜欢去直接操作寄存器,因为这样更接近原理,知其然也知其所以然。

2、标准库

  上面也提到了,STM32有非常多的寄存器,而导致了开发困难,所以为此ST公司就为每款芯片都编写了一份库文件,也就是工程文件里stm32F1xx…之类的。在这些 .c .h文件中,包括一些常用量的宏定义,把一些外设也通过结构体变量封装起来,如GPIO口时钟等。所以我们只需要配置结构体变量成员就可以修改外设的配置寄存器,从而选择不同的功能。也是目前最多人使用的方式,也是学习STM32接触最多的一种开发方式,我也就不多阐述了。

3、HAL库

  HAL库是ST公司目前主力推的开发方式,全称就是Hardware Abstraction Layer(抽象印象层)。库如其名,很抽象,一眼看上去不太容易知道他的作用是什么。

  它的出现比标准库要晚,但其实和标准库一样,都是为了节省程序开发的时期,而且HAL库尤其的有效,如果说标准库把实现功能需要配置的寄存器集成了,那么HAL库的一些函数甚至可以做到某些特定功能的集成。也就是说,同样的功能,标准库可能要用几句话,HAL库只需用一句话就够了。

  并且HAL库也很好的解决了程序移植的问题,不同型号的stm32芯片它的标准库是不一样的,例如在F4上开发的程序移植到F3上是不能通用的,而使用HAL库,只要使用的是相通的外设,程序基本可以完全复制粘贴,注意是相通外设,意思也就是不能无中生有,例如F7比F3要多几个定时器,不能明明没有这个定时器却非要配置,但其实这种情况不多,绝大多数都可以直接复制粘贴。是而且使用ST公司研发的STMcube软件,可以通过图形化的配置功能,直接生成整个使用HAL库的工程文件,可以说是方便至极,但是方便的同时也造成了它执行效率的低下,在各种论坛帖子真的是被吐槽的数不胜数。

HAL库固件库安装与 用户手册

1、首先设置让Cube可以自动联网下载相关固件库选择updater Settings

05ac0f04-e945-11ec-ba43-dac502259ad0.png  设置如下

05c40852-e945-11ec-ba43-dac502259ad0.png

2、根据芯片选择所需固件

  版本是向下兼容的,可以直接选择最新版。但如果觉得最新版太大,可以阅读下面的Main Changes.能够支持你目前的芯片就好。

06361a6e-e945-11ec-ba43-dac502259ad0.png  选好了,点击Install Now就行,过程可能有点长。建议直接官网下载到本地,再安装文件会被下载到如下位置,建议更改此目录,不要选在C盘!!!

0663f970-e945-11ec-ba43-dac502259ad0.png

3、寻找用户帮助手册

  进入固件所在文件夹,里面包含很多内容。

0688c872-e945-11ec-ba43-dac502259ad0.png比如说 官方提供的开发板程序,每个型号下面都有对应功能的实现,用户手册就在Drivers文件夹下面。

06c0b1f6-e945-11ec-ba43-dac502259ad0.png06f34882-e945-11ec-ba43-dac502259ad0.png

STM32 HAL库与标准库的区别_浅谈句柄、MSP函数、Callback函数

1、句柄

  句柄(handle),有多种意义,其中第一种是指程序设计,第二种是指Windows编程。现在大部分都是指程序设计/程序开发这类。

  • 第一种解释:句柄是一种特殊的智能指针 。当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。

  • 第二种解释:整个Windows编程的基础。一个句柄是指使用的一个唯一的整数值,即一个4字节(64位程序中为8字节)长的数值,来标识应用程序中的不同对象和同类中的不同的实例,诸如,一个窗口,按钮,图标,滚动条,输出设备,控件或者文件等。应用程序能够通过句柄访问相应的对象的信息,但是句柄不是指针,程序不能利用句柄来直接阅读文件中的信息。如果句柄不在I/O文件中,它是毫无用处的。句柄是Windows用来标志应用程序中建立的或是使用的唯一整数,Windows大量使用了句柄来标识对象。

STM32的标准库中,句柄是一种特殊的指针,通常指向结构体!

  在STM32的标准库中,假设我们要初始化一个外设(这里以USART为例),我们首先要初始化他们的各个寄存器。在标准库中,这些操作都是利用固件库结构体变量+固件库Init函数实现的:


USART_InitTypeDefUSART_InitStructure;


USART_InitStructure.USART_BaudRate=bound;//串口波特率

USART_InitStructure.USART_WordLength=USART_WordLength_8b;//字长为8位数据格式

USART_InitStructure.USART_StopBits=USART_StopBits_1;//一个停止位

USART_InitStructure.USART_Parity=USART_Parity_No;//无奇偶校验位

USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;//无硬件数据流控制

USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;//收发模式


USART_Init(USART3,&USART_InitStructure);//初始化串口1



可以看到,要初始化一个串口,需要:


1、对六个位置进行赋值

2、然后引用Init函数

  USART_InitStructure并不是一个全局结构体变量,而是只在函数内部的局部变量,初始化完成之后,USART_InitStructure就失去了作用。而在HAL库中,同样是USART初始化结构体变量,我们要定义为全局变量。


UART_HandleTypeDefUART1_Handler;

右键查看结构体成员


typedefstruct

{

USART_TypeDef*Instance;/*!< UART registers base address        */

UART_InitTypeDefInit;/*!< UART communication parameters      */

uint8_t*pTxBuffPtr;/*!< Pointer to UART Tx transfer Buffer */

uint16_tTxXferSize;/*!< UART Tx Transfer size              */

uint16_tTxXferCount;/*!< UART Tx Transfer Counter           */

uint8_t*pRxBuffPtr;/*!< Pointer to UART Rx transfer Buffer */

uint16_tRxXferSize;/*!< UART Rx Transfer size              */

uint16_tRxXferCount;/*!< UART Rx Transfer Counter           */

DMA_HandleTypeDef*hdmatx;/*!< UART Tx DMA Handle parameters      */

DMA_HandleTypeDef*hdmarx;/*!< UART Rx DMA Handle parameters      */

HAL_LockTypeDefLock;/*!< Locking object                     */

__IOHAL_UART_StateTypeDefState;/*!< UART communication state           */

__IOuint32_tErrorCode;/*!< UART Error code                    */

}UART_HandleTypeDef;


我们发现,与标准库不同的是,该成员不仅:


1、包含了之前标准库就有的六个成员(波特率,数据格式等),


2、还包含过采样、(发送或接收的)数据缓存、数据指针、串口 DMA 相关的变量、各种标志位等等要在整个项目流程中都要设置的各个成员。


该 UART1_Handler就被称为串口的句柄,它被贯穿整个USART收发的流程,比如开启中断:


HAL_UART_Receive_IT(&UART1_Handler,(u8*)aRxBuffer,RXBUFFERSIZE);

比如后面要讲到的MSP与Callback回调函数:


voidHAL_UART_MspInit(UART_HandleTypeDef*huart);

voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart);

在这些函数中,只需要调用初始化时定义的句柄UART1_Handler就好。


2、MSP函数

MSP: MCU Specific Package 单片机的具体方案


MSP是指和MCU相关的初始化,引用一下正点原子的解释,个人觉得说的很明白:


  我们要初始化一个串口,首先要设置和 MCU 无关的东西,例如波特率,奇偶校验,停止位等,这些参数设置和 MCU 没有任何关系,可以使用 STM32F1,也可以是 STM32F2/F3/F4/F7上的串口。而一个串口设备它需要一个 MCU 来承载,例如用 STM32F4 来做承载,PA9 做为发送,PA10 做为接收,MSP 就是要初始化 STM32F4 的 PA9,PA10,配置这两个引脚。所以 HAL驱动方式的初始化流程就是:


HAL_USART_Init()—>HAL_USART_MspInit() ,先初始化与 MCU无关的串口协议,再初始化与 MCU 相关的串口引脚。


在 STM32 的 HAL 驱动中HAL_PPP_MspInit()作为回调,被 HAL_PPP_Init()函数所调用。当我们需要移植程序到 STM32F1平台的时候,我们只需要修改 HAL_PPP_MspInit 函数内容而不需要修改 HAL_PPP_Init 入口参数内容。


  在HAL库中,几乎每初始化一个外设就需要设置该外设与单片机之间的联系,比如IO口,是否复用等等,可见,HAL库相对于标准库多了MSP函数之后,移植性非常强,但与此同时却增加了代码量和代码的嵌套层级。可以说各有利弊。


同样,MSP函数又可以配合句柄,达到非常强的移植性:


voidHAL_UART_MspInit(UART_HandleTypeDef*huart);

3、Callback函数

  类似于MSP函数,个人认为Callback函数主要帮助用户应用层的代码编写。


  还是以USART为例,在标准库中,串口中断了以后,我们要先在中断中判断是否是接收中断,然后读出数据,顺便清除中断标志位,然后再是对数据的处理,这样如果我们在一个中断函数中写这么多代码,就会显得很混乱:


voidUSART3_IRQHandler(void)//串口1中断服务程序

{

u8Res;

if(USART_GetITStatus(USART3,USART_IT_RXNE)!=RESET)//接收中断(接收到的数据必须是0x0d0x0a结尾)

{

Res=USART_ReceiveData(USART3);//读取接收到的数据

/*数据处理区*/

}

}

}


而在HAL库中,进入串口中断后,直接由HAL库中断函数进行托管:


voidUSART1_IRQHandler(void)

{

HAL_UART_IRQHandler(&UART1_Handler);//调用HAL库中断处理公用函数

/***************省略无关代码****************/

}

  HAL_UART_IRQHandler这个函数完成了判断是哪个中断(接收?发送?或者其他?),然后读出数据,保存至缓存区,顺便清除中断标志位等等操作。


  比如我提前设置了,串口每接收五个字节,我就要对这五个字节进行处理。在一开始我定义了一个串口接收缓存区:


/*HAL库使用的串口接收缓冲,处理逻辑由HAL库控制,接收完这个数组就会调用HAL_UART_RxCpltCallback进行处理这个数组*/

/*RXBUFFERSIZE=5*/

u8aRxBuffer[RXBUFFERSIZE];

在初始化中,我在句柄里设置好了缓存区的地址,缓存大小(五个字节)


/*该代码在HAL_UART_Receive_IT函数中,初始化时会引用*/

huart->pRxBuffPtr=pData;//aRxBuffer

huart->RxXferSize=Size;//RXBUFFERSIZE

huart->RxXferCount=Size;//RXBUFFERSIZE

  则在接收数据中,每接收完五个字节,HAL_UART_IRQHandler才会执行一次Callback函数:


voidHAL_UART_RxCpltCallback(UART_HandleTypeDef*huart);

  在这个Callback回调函数中,我们只需要对这接收到的五个字节(保存在aRxBuffer[]中)进行处理就好了,完全不用再去手动清除标志位等操作。


  所以说Callback函数是一个应用层代码的函数,我们在一开始只设置句柄里面的各个参数,然后就等着HAL库把自己安排好的代码送到手中就可以了~


  综上,就是HAL库的三个与标准库不同的地方之个人见解。个人觉得从这三个小点就可以看出HAL库的可移植性之强大,并且用户可以完全不去理会底层各个寄存器的操作,代码也更有逻辑性。但与此带来的是复杂的代码量,极慢的编译速度,略微低下的效率。看怎么取舍了。


STM32 HAL库结构

  说到STM32的HAL库,就不得不提STM32CubeMX,其作为一个可视化的配置工具,对于开发者来说,确实大大节省了开发时间。STM32CubeMX就是以HAL库为基础的,且目前仅支持HAL库及LL库!首先看一下,官方给出的HAL库的包含结构:

0737d01a-e945-11ec-ba43-dac502259ad0.png

1、stm32f4xx.h主要包含STM32同系列芯片的不同具体型号的定义,是否使用HAL库等的定义,接着,其会根据定义的芯片信号包含具体的芯片型号的头文件:

#ifdefined(STM32F405xx)

#include'stm32f405xx.h'

#elifdefined(STM32F415xx)

#include'stm32f415xx.h'

#elifdefined(STM32F407xx)

#include'stm32f407xx.h'

#elifdefined(STM32F417xx)

#include'stm32f417xx.h'

#else

#error'PleaseselectfirstthetargetSTM32F4xxdeviceusedinyourapplication(instm32f2xx.hfile)'

#endif


紧接着,其会包含stm32f4xx_hal.h。


2、stm32f4xx_hal.h:stm32f4xx_hal.c/h 主要实现HAL库的初始化、系统滴答相关函数、及CPU的调试模式配置


3、stm32f4xx_hal_conf.h :该文件是一个用户级别的配置文件,用来实现对HAL库的裁剪,其位于用户文件目录,不要放在库目录中。


接下来对于HAL库的源码文件进行一下说明,HAL库文件名均以stm32f4xx_hal开头,后面加上_外设或者模块名(如:stm32f4xx_hal_adc.c):


4、库文件:stm32f4xx_hal_ppp.c/.h // 主要的外设或者模块的驱动源文件,包含了该外设的通用API


stm32f4xx_hal_ppp_ex.c/.h // 外围设备或模块驱动程序的扩展文件。这组文件中包含特定型号或者系列的芯片的特殊API。以及如果该特定的芯片内部有不同的实现方式,则该文件中的特殊API将覆盖_ppp中的通用API。


stm32f4xx_hal.c/.h // 此文件用于HAL初始化,并且包含DBGMCU、重映射和基于systick的时间延迟等相关的API


5、其他库文件


用户级别文件:


stm32f4xx_hal_msp_template.c // 只有.c没有.h。它包含用户应用程序中使用的外设的MSP初始化和反初始化(主程序和回调函数)。使用者复制到自己目录下使用模板。


stm32f4xx_hal_conf_template.h // 用户级别的库配置文件模板。使用者复制到自己目录下使用


system_stm32f4xx.c // 此文件主要包含SystemInit()函数,该函数在刚复位及跳到main之前的启动过程中被调用。它不在启动时配置系统时钟(与标准库相反)。时钟的配置在用户文件中使用HAL API来完成。startup_stm32f4xx.s // 芯片启动文件,主要包含堆栈定义,终端向量表等 stm32f4xx_it.c/.h // 中断处理函数的相关实现


6 main.c/.h //


根据HAL库的命名规则,其API可以分为以下三大类:


初始化/反初始化函数:

HAL_PPP_Init(),HAL_PPP_DeInit()

IO 操作函数:

HAL_PPP_Read(),

HAL_PPP_Write(),

HAL_PPP_Transmit(),

HAL_PPP_Receive()

控制函数:

HAL_PPP_Set(),

HAL_PPP_Get().

状态和错误:

**HAL_PPP_GetState(),

HAL_PPP_GetError().

注意:

  目前LL库是和HAL库捆绑发布的,所以在HAL库源码中,还有一些名为 stm32f2xx_ll_ppp的源码文件,这些文件就是新增的LL库文件。使用CubeMX生产项目时,可以选择LL库。


  HAL库最大的特点就是对底层进行了抽象。在此结构下,用户代码的处理主要分为三部分:


处理外设句柄(实现用户功能)

处理MSP

处理各种回调函数

相关知识如下:


1、外设句柄定义

  用户代码的第一大部分:对于外设句柄的处理。HAL库在结构上,对每个外设抽象成了一个称为ppp_HandleTypeDef的结构体,其中ppp就是每个外设的名字。*所有的函数都是工作在ppp_HandleTypeDef指针之下。


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

下面,以ADC为例


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

/**

*@briefADChandleStructuredefinition

*/

typedefstruct

{

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

ADC_InitTypeDefInit;/*!< ADC required parameters */

__IOuint32_tNbrOfCurrentConversionRank;/*!< ADC number of current conversion rank */

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

HAL_LockTypeDefLock;/*!< ADC locking object */

__IOuint32_tState;/*!< ADC communication state */

__IOuint32_tErrorCode;/*!< 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_StatusTypeDefHAL_ADC_Start(ADC_HandleTypeDef*hadc);

HAL_StatusTypeDefHAL_ADC_Stop(ADC_HandleTypeDef*hadc);


HAL_StatusTypeDefHAL_ADC_Start_IT(ADC_HandleTypeDef*hadc);

HAL_StatusTypeDefHAL_ADC_Stop_IT(ADC_HandleTypeDef*hadc);


HAL_StatusTypeDefHAL_ADC_Start_DMA(ADC_HandleTypeDef*hadc,uint32_t*pData,uint32_tLength);

HAL_StatusTypeDefHAL_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):清除一个指定的外设的标志状态

[1] [2]
关键字:STM32  HAL库  固件库 引用地址:STM32的三种开发方式 HAL库固件库安装与用户手册

上一篇:利用Proteus仿真STM32实现DHT11温湿度检测
下一篇:NS32F103VBT6软硬件替代STM32F103VBT6

推荐阅读最新更新时间:2024-11-16 19:57

STM32 HAL库学习(二) 串口收发数据
上一篇实现了LED的点亮和串口轮询发送数据,这章想着实现串口接收数据,不得不说,在开始使用STM32的外设才对HAL库的框架有更准确的理解。之前一直不懂HAL库的优越性在哪,这次对它的msp层有了一定认识。 简单来说,HAL库有一个特点就是对于许多外设的初始化以及功能操作,都提供有一个weak版本的函数,例如串口的HAL_UART_MspInit()函数和HAL_UART_MspDeInit()函数等,这些都可以供用户在需要时在stm32f0xx_hal_msp.c中进行重写实现功能。 用串口初始化来举例子,用Cube配置UART1使能并生成代码后可以看到有三个关键函数: 1、void MX_USART1_UART_I
[单片机]
基于STM32处理器的定时开关装置设计
本文针对市场上现有的定时开关装置的弊端,设计了一种基于STM32处理器的定时开关装置。该装置利用GSM网络实现远程遥控功能,并通过nRF24L0l+无线通信模块,遥控在一定范围内任意分布的多个开关。系统具有友好的人机交流界面,可设置多组定时时间,以及触摸屏控制、掉电保护和红外遥控等功能。 目前,国内市场上出现了多种定时开关产品,并被广泛应用于家居生活、汽车服务、公共照明和仓库管理等领域。其中大部分产品都只有简单的定时功能;无法实现遥控、显示等高级功能。而少数可遥控的产品也只局限于较近距离的范围内,并未实现远程控制,这些降低了它的便利性和实用性。随着科技的进步,人们向往智能化、节约化的家居生活,各种网络家电应运而生,但其高
[单片机]
基于<font color='red'>STM32</font>处理器的定时开关装置设计
STM32开发板+机智云IoT+智能楼宇照明灯控
引言 随着现代电子技术以及经济的发展,人们更加追求科幻电影般的情景式生活享受,对各类智能设备的需求也越来越大。其中智能照明系统与人们的生活办公息息相关,而不同人群对照明环境也有个性化的需求。其中包括年轻人对灯光色彩变幻的追求,也有老幼人群对光照强度以及安全报警的功能需求,也有对残障人士便捷地控制开关方式的需求等等。 为了更科学可靠地满足人们对美好生活办公的需求,本文将物联网技术融入楼宇照明系统,通过对传统照明系统的分析,结合现代楼宇的功能区域结构,以STM32F103作为MCU,利用esp8266进行WiFi联网,同时配合各类传感器和LED驱动电路,实现对楼宇内走廊、电梯、办公室、卫生间等环境的远程控制。 1系统总体设计方
[单片机]
<font color='red'>STM32</font>开发板+机智云IoT+智能楼宇照明灯控
STM32的IO口灌入电流和输出驱动电流最大是多少?
  刚开始学习一款单片机的时候一般都是从操作IO口开始的,所以我也一样,先是弄个流水灯。   刚开始我对STM32的认识不够,以为是跟51单片机类似,可以直接操作端口,可是LED灯却没反应,于是乎,仔细查看资料发现,原来对于ARM,不管你要操作哪个IO口,都要先配置IO口。   不过对于普通的IO口的应用,配置会比较简单,主要就以下几个步骤:   1.打开相应IO口的时钟;   2.打开IO口相应引脚位;   3.配置IO口的模式;   4.初始化IO端口。   对于STM32的IO口可以根据需要由软件配置成8种模式:   (1)GPIO_Mode_AIN 模拟输入   (2)GPIO_Mode_IN_FLOATING 浮
[单片机]
<font color='red'>STM32</font>的IO口灌入电流和输出驱动电流最大是多少?
STM8S003F3 使用ADC:固件库版本与寄存器版本
STM8S003F3这款小型MCU,只有1K RAM与8K Flash,应用比较简单,AD采样,GPIO控制,PWM控制,还是不错的嵌入式的应用。 最近一个项目用到了几路AD采样,我平时一般喜欢下载最新的官方标准固件库,只是,这次遇到的问题是,在使用PWM与ADC采样后,代码大小竟然大于8K,编译失败!!!后来,看了下Debug下的map文件,发现,使用ADC的固件库,大小竟然有1K的代码空间。后来改为寄存器的,发现代码还不到100字节。 (1)固件库AD采样的代码如下,代码易懂,但编译后代码较大:单通道采样,多个的话,只需要一个一个采集。 #include adc.h #include stm8s.h void
[单片机]
STM32单片机串口空闲中断+DMA接收不定长数据
在上一篇文章STM32单片机串口空闲中断接收不定长数据中介绍了利用串口空闲中断接收不定长数据,这种方式有一个问题就是串口每接收到一个字节就会进入一次中断,如果发送的数据比较频繁,那么串口中断就会不停打断主程序运行,影响系统运行。那么能不能在串口接收数据过程中不要每接收一个数据中断一次,只有在一帧数据接收结束完成后只中断一次? 用串口的空闲中断加上DMA功能,就可以实现每帧数据接收完成后只中断一次,而在数据接收过程中,由DMA存储串口接收到的每个字节。 关于串口的空闲检测和DMA在STM32参考手册中有详细介绍。 下面看如何初始化串口空闲中断和 DMA。 void uart2_init( u16 baud )
[单片机]
<font color='red'>STM32</font>单片机串口空闲中断+DMA接收不定长数据
印刷机张力控制系统设计
简介:基于印刷行业张力控制原理,分析了张力控制系统组成,并介绍了以STM32为主控芯片及外围电路开发而成的闭环张力控制系统,该系统不仅控制精度高,响应速度快,而且操作简单,有合理的PID控制功能,适用于多种印刷材料。它还可以计算出材料筒的直径,使整个张力控制过程更为合理。 张力控制系统广泛应用于印刷等轻工业领域中,在收取和放卷材料时,为保证生产的质量及效率,保持恒定的张力是很重要的。在印刷过程中或者是印刷完成之后,最后的一道工序一般就是将加工物卷绕成筒状。在这一过程中,卷绕的好坏将是决定产品质量的关键,卷得太紧,容易使材料变形、拉断,卷得太松又容易使材料不紧凑,不利于搬运和运输,因而为了达到使卷绕紧凑,保证产品的质量,都要求在
[单片机]
印刷机张力控制系统设计
ST MP34DT01和STM32数字MEMS麦克风解决方案
ST 公司的MP34DT01是超小型低功耗全方位数字MEMS麦克风,具有容性传感元件和IC接口,单电源工作,声学过载点120 dBSPL,信噪比63dB,全方位灵敏度,灵敏度-26dBFC,PDM输出,主要用在手机,笔记本电脑,手持媒体播放器(PMP),VoIP,语音识别,数码相机和摄像机,防盗系统等.本文介绍了MP34DT01主要特性,以及采用MP34DT01和STM32 MCU的STEVAL-MKI117V1演示板主要特性,电路图,材料清单和PCB布局图. The MP34DT01 is an ultra-compact, low-power,omnidirectional, digital MEMS microphone
[单片机]
ST MP34DT01和<font color='red'>STM32</font>数字MEMS麦克风解决方案
小广播
设计资源 培训 开发板 精华推荐

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

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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