嵌入式STM32重要基础知识及实战经验分享

1、固件库:

固件库就是函数的集合,固件库函数的作用是向下负责与寄存器直接打交道, 向上提供用户函数调用的接口(API)。

2、CMSIS标准与固件库的关系

就是对固件库函数的要求。

ARM 公司为了能让不同的芯片公司生产的 Cortex-M3 芯片能在软件上基本兼容,和芯片生产商共同提出了一套标准 CMSIS 标准(Cortex Microcontroller Software Interface Standard) ,翻译过来是 “ARM Cortex™ 微控制器软件接口标准”。ST 官方库就是根据这套标准设计的。

其实不用这么讲这么复杂的,一个简单的例子,我们在使用 STM32 芯片的时候首先要进行系统初始化,CMSIS 规范就规定,系统初始化函数名字必须为 SystemInit,所以各个芯片公 司写自己的库函数的时候就必须用 SystemInit 对系统进行初始化。

3、STM32 和 ARM 以及 ARM7 的关系

ARM 是一个做芯片标准的公司,它负责的是芯片内核的架构设 计,而 TI,ST 这样的公司,他们并不做标准,他们是芯片公司,他们是根据 ARM 公司提供的 芯片内核标准设计自己的芯片。

所以,任何一个做 Cortex-M3 芯片,他们的内核结构都是一样的,不同的是他们的存储器容量,片上外设,IO 以及其他模块的区别。

 图1 cortex-m3 芯片结构

4、Cortex-M3内核

Cortex-M3 内核是单片机的中央处理器单元 CPU 。

特点:

1、Cortex-M3 是一个 32 位处理器内核。内部的数据路径是 32 位,寄存器是 32 位,存储器接口是 32 位。

2、Cortex-M3 采用哈佛架构。拥有独立的指令总线和数据总线,取指与数据访问可以同时进行。

3、 支持小端模式、大端模式。

组成介绍:

Cortex-M3内核的架构含有

(1)寄存器组、(2)NVIC、(3)中断和异常、(4)储存器映射、(5)总线接口、(6)调试支持(debug interface)、(7)指令集。

5、时钟使能

寄存器是基于什么的?

  当然是触发器!!!准确地说应该是D触发器

  触发器的赋值是一定需要时钟的, 而寄存器的时钟是由总线时钟提供的,就是说没有总线时钟的话,你给寄存器值它是不会读入的。换句话说,只有送来了时钟,触发器才能被改写值,这样寄存器才会工作。(通常会根据上升沿或者下降沿)

  又会有人说为什么我之前学51的时候为什么不用使能时钟呢?

  当初我们学51的时候,哪会关注功耗,我们能跑起来程序就行了,而且对于大多数厂家来说,绝大多数不会关注功耗。但是STM32不同,为了减少功耗,ST公司为了省电,使用了所谓的时钟门控的技术,这又涉及到了同步电路。同步电路中总有一个时钟控制。

在默认情况下这些时钟都是disable的。你如果要使用它,首先就需要enable。

  我们也可以把这个时钟简单的比作为门,STM32之所以是低功耗,就是因为他把所有门都默认设置为disable,在你需要用哪个门的时候,开哪个门就可以,也就是说用到什么外设,只要打开对应外设的时钟就可以,其他的没用到的可以还是disable,这样耗能就会减少。

        时钟门控技术就是用“与门”来控制时钟信号是否输入到外设。

6、串口通信原理

一般每次只能一个字节(8位)来接收和发送。当使用串口调试助手(XCOM)等软件时,命令行一次发送和接收到多个字节的发送数据,实际上是软件内部已经编写好的也是一个一个字节来发送和接收的。

 

数据缓存器实际上就是寄存器。

电脑串口是USB电平,单片机是TTL电平,相互串口通信连接需要将电平逻辑一致。通常需要用到USB电平转TTL芯片模块,例如:CH340、PL2303、FT232等,有时也需要电脑上安装电平转换芯片的驱动,如CH340。

串口发送的数据会先进入数据寄存器(TDR)中,当移位寄存器没有数据在发送时,数据就会接着进入到移位寄存器中发送。

串口通信是异步通信,双方必须约定好波特率,才能知道一个数据是什么时候传输完成的。同步通信则是例如在信号的上升沿的时候发送一个数据,就无需约定波特率。

7、串口通信标志位

状态寄存器SR:

1、RXNE:(读数据寄存器非空),当该位被置 1 的时候,就是提示已经有数据被接收到了,并 且可以读出来了。这时候我们要做的就是尽快去读取 USART_DR,通过读 USART_DR 可以将该位清零,也可以向该位写 0,直接清除。

2、TC:(发送完成),当该位被置位的时候,表示 USART_DR 内的数据已经被发送完成了。如 果设置了这个位的中断,则会产生中断。该位也有两种清零方式:1)读 USART_SR,写 USART_DR。2)直接向该位写 0。

控制寄存器CR1:

(主要用于设置是否开启中断)

1、RXNEIE:(接收缓冲区非空中断使能)。接收到数据的时候(RXNE 读数据寄存器非空),我们要产生中断,则开启该位。该位由软件设置或清除。

        0:禁止产生中断;

        1:当USART_SR中的TC为’1’时,产生USART中断。

2、TCIE:(发送完成中断使能)

        0:禁止产生中断;

        1:当USART_SR中的TC为’1’时,产生USART中断

8、端口复用和重映射

端口复用:STM32有很多的内置外设,这些外设的外部引脚都是与GPIO复用的。也就是说,一个GPIO如果可以复用为内置外设的功能引脚,那么当这个GPIO作为内置外设使用的时候,就叫做复用。

例如串口1 的发送接收引脚是PA9,PA10,当我们把PA9,PA10不用作GPIO,而用做复用功能串口1的发送接收引脚的时候,叫端口复用。

配置过程:-以PA9,PA10配置为串口1为例

(1)GPIO端口时钟使能:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

(2)复用外设时钟使能:比如将端口PA9,PA10复用为串口,所以要使能串口时钟。RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);

(3)端口模式配置。 GPIO_Init()函数。 查表:

 (4)如果是F407的芯片还需要配置GPIO_PinAFConfig()函数,选择GPIO复用为什么功能

但单个外设(如UART)可能可以复用到多个(多组)不同的IO口上(端口重映射),但是在同一时间内只能有一组IO口(比如RX、TX)使用该串口资源。使用时要注意资源的分配,避免冲突。

如F407的串口USART2的TX、RX就可以复用到PA2、PA3和PD5、PD6两组上。

端口重映射:每个内置外设都有若干个输入输出引脚,一般这些引脚的输出端口都是固定不变的,为了让设计工程师可以更好地安排引脚的走向和功能,在STM32中引入了外设引脚重映射的概念,即一个外设的引脚除了具有默认的端口外,还可以通过设置重映射寄存器的方式,把这个外设的引脚映射到其它的端口。

9、SPI通信

SPI是串行外设接口(Serial Peripheral Interface)的缩写,通信一次最多传输32字节数据。SPI每次数据传输可以8位或16位单位,每次传输单位数不受限制。

SPI有主、从两种模式,由主模块选择一个从模块进行同步通信,从而完成数据的交换。主设备(Master)提供时钟,从设备接收。SPI接口的读写操作都是由主设备发起,当存在多个从设备(Slave)时,通过片选信号进行管理。

SPI通信通常需要四根线,比串口的多两根:

1、MISO(Master Input Slave Output):主设备数据输入,从设备输出;

2、MOSI(Master Ouput Slave Input):主设备输出,从设备输入;

3、SCLK(Serial Clock):时钟信号,由主设备产生

4、CS/SS(Chip Select/Slave Select):从设备使能,由主设备控制(高或低电位)

一主一从:

 一主多从:(每个从机都有主机对应的单独片选线)

 SPI主、从设备都有一个串行移位寄存器,主设备通过向它的SPI串行移位寄存器写入一个字节发起传输。

 SPI通信流程:

1、主设备发起信号,将CS/SS拉低,启动通信。

2、主设备发送时钟信号,告诉从设备进行写或读数据,从设备会立即读取数据线上的信号,即可得到一位数据(1bit)。

3、主机将数据写入发送缓存器(Menory),缓存区(缓存长度看单片机配置)经过移位寄存器通过MOSI将字节一位一位的移出去给从机,同时MISO接口接收到的数据经移位寄存器一位位移动到接收缓存区。

4、从机也将字节的串行移位寄存器种的内容通过MISO信号线返回给主机。同时通过MOSI信号线接收主机发送的数据。两个移位寄存器中的内容就被交换。

 SPI只有主从模式之分,没有读和写的说法,外设的写操作和读操作都是同步完成。若要写操作,主机需要忽略接收到的字节。若要读,则发送一个空字节来引发从机传输。

10、#ifndef、#define、#endif作用

防止头文件被重复引用和重复编译。

#ifndef是if not define的缩写,是宏定义的一种,准确说是预处理功能(宏定义、文件包含、条件编译)中的条件编译。

加入后可预防以下错误:若在.h文件中定义了全局变量,C文件包含了此.h文件多次,若不加#ifndef宏定义,则会出现变量重复定义的错误,也无法定义枚举变量等情况。

interactiv_system.h文件为例:

11、..\OBJ\LED.axf: Error: L6218E: Undefined symbol XXXXX (referred from XXXXX.o).

extern对变量范围扩展,仍然报错,原先代码:

将需要extern的变量写在函数外部,修改后解决:

10、共地

当使用不同模块通信的时候,3.3V代表信号1,0V代表信号0。但电压都是相对的参考电压,参考对象不同,电压值也不同。两个模块的电路都是分开的,但他们的电压都是相较于左边的电路的负极而言,此时右边的0V相较于左边的可能会低了2V。那么当左边发送3.3V信号的时候,右边可能只会收到1.3V的信号,导致通信失败。

同理在驱动电机的时候,如果没有供地,本来设置的5V的信号到了电机处可能只有3V,就无法驱动电机转动。

为了解决不同模块参考电位的问题,我们可以使用一根杜邦线将两个的0V连接起来,即共地,此时两个模块的0V相同,高电平的3.3V也必然相同。

11、使用其他型号开发板时,要用JTAG_Set函数

正点原子的开发板一般不需要(一般不会出现问题),但其他开发板要使能SWD,否则可能会出现烧录后,程序无法运行的情况。

12、SD卡写入,LCD显示图片

在使用LCD显示图片时,直接将png后缀更改为jpg后缀时可以发现,图像的大小并没有改变,本质上其实格式并没有修改,图片会无法显示。

jpg、jpeg格式图片若是显示不了,可用windows系统自带的画图软件打开,图片大小会增加,一般就可以显示了。

13、不同pack的安装与卸载

“Option for Target”中的Device可以看到用的pack的版本,直接点击下面链接去官网找到对应的下载就好。

在“Debug,点击“setting”进入“Flash Download”,点击“Add”

 

 可以看到每个pack在电脑中的存储位置,一般会放在“ARM\flash”中,可以把别人电脑上有的pack直接复制到这个文件中,就可以使用了

14、C语言头文件和.c文件之间的关系

头文件.h和.c文件其实都是一样的,include" "头文件其实就是把这个头文件中的内容一行行的运行一次。其中的函数声明会在编译阶段自动匹配到同名的.c文件,具体过程可以看C语言的编译四个步骤。(后续会放出一些链接)

(130条消息) C语言后缀.h文件和.c文件作用和区别_花大师的博客-CSDN博客

从本质上来说,.c和.h并没有太大区别,只是命名方式的不同,主要为了解决重复声明的问题。

15、当出现ST-Link USBcommunication error和The content of the ST-Link is corrupt时

当已经检测到ST-Link,但是仍然ST-Link USBcommunication error一般是ST-link的固件版本问题固件需要升级。

当使用固件升级的时候仍然出现The content of the ST-Link is corrupt,且重启多次无用后,可以下载STM32 ST-LINK Utility。官方链接STSW-LINK004 – STM32 ST-LINK utility (replaced by STM32CubeProgrammer) – STMicroelectronics

 使用教程可参考博客

https://www.cnblogs.com/cuter/p/8879993.html

16、STlink/v2中SWD模式(4线)连线方式

连接1、7、9、20脚。

1:TVCC,供电。

7:SWIO,SWD接口的数据线,传输数据。

9:SWCLK,SWD接口的时钟线,用于同步数据传输。

20:GND,地线。

16、串口接的电压不对,或者降压芯片出现问题

降压芯片出问题,往往会影响到串口传输的电平(串口传输的数据)。电平不对,传输的信号可能会接收到全是1,或者怎么样都是一样的数据。可以检查下电压,降压芯片。

17、短接后电流瞬间无穷大,可能直接击穿降压芯片

不要试着短接任何电线,一瞬间可能就会击穿芯片,短接电流无穷大,降压芯片很可能第一个先被击穿。

18、出现error:"..\OBJ\WHEELTEC.axf: Error: L6218E: Undefined symbol SPI_Cmd (referred from 24l01.o)."

一般很可能是忘记添加对应的固件库,像adc、spi、usart等

添加如下,添加后正常

 

19、芯片引脚对应外设的查询

可在官网下载对应的芯片手册,查看每个引脚对应外设。

如下,我们可以看到PA4、PA5引脚有哪些外设可用,若是F407芯片则还需要配置GPIO_PinAFConfig()函数指名复用什么功能,F103则不需要。

数据手册下载方法:

1、进入官网:

意法半导体-STMicroelectronics

2、 搜索栏中输入你想要查找的芯片型号

3、即可进入下载对应的数据手册

20、外设资料的查询

除了正点原子和CSDN等处的资料外,可以下载STM官方中文手册查看,包括SPI、USART等的原理。

可去正点原子资料处下载

 包括了各种外设原理和寄存器的讲解

21、直流电机、步进电机、伺服电机、舵机的使用

单片机IO口一般输出的电流电压较小,无法直接驱动电机和舵机,需要加上相应的驱动模块。

1、直流电机:转动速度与电流大小相关,电流越大,转动速度越快,负载越高。但无法进行精确定位。

2、步进电机:以脉冲信号驱动,脉冲的数量决定了转动的角度,可以进行转动位置定位,但为开环控制。每步的转角取决于电机本身的硬件设置,200步一转的转角为(360/200)1.8度。

步进电机也可以控制转动的速度,脉冲的频率越高,转动的速度越快。

3、伺服电机:和步进一样以脉冲信号驱动,都能控制速度和转动的位置,但多了编码器等数据反馈,能够实现闭环控制,精确度更高。

4、舵机:用PWM控制,以脉冲的占空比决定舵机转动的角度。

电机的相关原理可参考

直流电机的原理及驱动_直流电机驱动-CSDN博客

步进电机原理及驱动_步进驱动器的工作原理-CSDN博客

22、LM2596降压芯片的使用

通过调节蓝色电位器旋钮(一般顺时针旋转升压,逆时针旋转降压),使用万用表测量输出电压直至需要的电压为止。

电位器即可变电阻

23、NRF24L01无线通信模块的使用

可设置每次接收0-32个字节,但实际传输(SPI)依然为8位一次。只是在NRF24L01一个一个字节取出先放入一个数组内。

 NRF24L01发送和接收的字节设置

虽然NRF24L01每次可读写0-32个字节数据,但实际上每次传输都只为1个字节(8bit)的数据,通过循环来实现一次多个字节数据的读取。

读出:写入无用数据以读取数据。每次读取数据位u8类型

写入:忽略读到的数据。每次写入数据为u8类型

 

 有效数据宽度设置:若要在过程中不断改变每次接收到的数据大小,需要对接收模式RX寄存器中的通道X有效数据宽度进行更改。或者可采用每次只接受1个字节数据,通过定时器来计算接收时间间隔,当超过定时时间没有接收到新数据则溢出,视为接收完毕,否则重启定时器。

作者:ZHU~.

物联沃分享整理
物联沃-IOTWORD物联网 » 嵌入式STM32重要基础知识及实战经验分享

发表评论