关于MCU基础知识可以参考正点原子和robomaster C板教程详细学习,本教程对一些重要的知识点作总结概括,以及开发过程中的经验进行汇总。

一、前言:

1.资源链接:

1.【【正点原子】手把手教你学STM32 HAL库开发全集【真人出镜】STM32入门教学视频教程 单片机 嵌入式】https://www.bilibili.com/video/BV1bv4y1R7dp?vd_source=3cc3c07b09206097d0d8b0aefdf07958

2.robomaster C板教程可以百度获得。

3.【STM32入门教程-2023版 细致讲解 中文字幕】https://www.bilibili.com/video/BV1th411z7sn?vd_source=3cc3c07b09206097d0d8b0aefdf07958

2.通识学习:

MCU俗称单片机,包括ST意法半导体、NXP恩智浦、RENESAS瑞萨、MICROCHIP、infineon英飞凌、TI德州仪器、乐鑫espress等诸多品牌。STM32 指 ST 公司开发的 32 位微控制器。单片机最小系统板由MCU,时钟电路,复位电路,外部晶振,输入输出接口,电源电路组成。HAL库与标准库是ST公司针对STM32开发出来的两种库:HAL库封装集成度高,更适合与复杂任务的代码编写,标准库更贴合底层并且较为简单资料丰富适合入门学习。标准库的学习参考B站江科大,HAL库学习参考正点原子。

关于开发IDE的选择,我建议从Keil5开始,之后转向clion或vscode。Keil5操作简单下载方便且资料丰富,遇见bug网上解决方法多更适合新手入门或小项目的开发。clion或vscode界面美观但编译下载较为繁琐,但结合git可以和队友一起完成项目开发便于维护,适合团队协作和大型且多人参与的项目开发。

stm32cubemx可以进行图形化配置一些基本的外设初始化,让开发人员不用在硬件初始化代码上花费大量时间。stm32cubemx的使用经验:如果要在STM32CubeMX生成的工程中添加代码,要在提示 /* USER CODE BEGIN* /和/* USER CODE END*/之间添加代码,这样STM32CubeMX重新生成代码时才不会将自己添加的代码删除掉。此外,注意使用CubeMX配置生成的工程中的注释最好不要随便删除掉。正点原子的代码风格与stm32cubemx有所不同,没有那么多的注释和代码位置要求但都是基于HAL库进行开发的。

3.HAL库文件结构:

一个项目工程文件主要由这几个文件夹组成:Startup文件夹用于存放工程启动文件不用管,User文件夹存放开发人员编写的文件,Driver文件夹存放delay.c提供延时函数、sys.c完成一些初始化工作、usart.c完成串口初始化工作。STM32F1XXX文件夹是存放HAL库文件的地方。BSP文件夹又叫做板级支持包,是针对开发板的硬件外设而编写的驱动函数,用核心板连接模块的学习者这个文件夹里面的文件需要按照实际情况编写。readme.txt是开发者对整个项目的说明性文件。

4.单片机基础:

4.1时钟与GPIO:

时钟对单片机而言类似于人的心脏,一切活动都基于一定的频率进行。STM32的时钟来源有外部振荡和内部振荡。

STM32没有内部晶振,HSI是内部RC振荡器。HSI内部8MHz的RC振荡器的误差在1%左右内部RC振荡器的精度通常比用HSE(外部晶振)要差上十倍以上。

晶振作用是产生外部振荡,晶振将产生的振荡通过单片机的OSC_IN和OSC_OUT引脚接入单片机并通过时钟树来为单片机各个总线提供时钟基准。下图中的SYSCLK是单片机主频,不同单片机的主频有所不同。

GPIO负责采集外部器件的信息或者控制外部器件工作,即输入输出。按照功能分又分为电源引脚、晶振引脚、复位引脚、下载引脚、BOOT引脚、GPIO引脚。STM32的GPIO的输入电压为VDD ≤ 3.6 V,各位千万不要向单片机作为输入的引脚输入超过3.6v的电压。

GPIO的八种模式记住就好,剩下的肖特基二极管、寄存器等什么的的没什么实际作用,不学也行:

4.2中断与定时器:

打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断。

NVIC叫做向量中断控制器用于管理工程中的各种中断,注意一个项目工程中只有一次NVIC中断优先级分组的定义。不同的分组意味着工程中能够使用的抢占优先级和响应优先级的数量不同。每个中断都有自己的抢占优先级和响应优先级,NVIC根据这些对不同的中断执行顺序进行调度。抢占优先级(pre):高抢占优先级可以打断正在执行的低抢占优先级中断;响应优先级(sub):当抢占优先级相同时,响应优先级高的先执行,但是不能互相打断;抢占和响应都相同的情况下,自然优先级越高的,先执行。

NVIC的使用如下:

最经典的终端莫过于外部中断:外部中断通常是 GPIO 的电平跳变引起的中断。在 stm32 中,每一个 GPIO 都可以作为外 部中断的触发源,外部中断一共有 16 条线,对应着 GPIO 的 0-15 引脚,每一条外部中断 都可以与任意一组的对应引脚相连,但不能重复使用。例如外部中断 Line0 可以和 PA0, PB0,PC0 等任意一条 0 号引脚相连,但如果已经和 PA0 相连,就不能同时和 PB0,PC0 其他引脚相连。 外部中断支持 GPIO 的三种电平跳变模式,如下所示:

1. 上升沿中断:当 GPIO 的电平从低电平跳变成高电平时,引发外部中断。

2. 下降沿中断:当 GPIO 的电平从高电平跳变成低电平时,引发外部中断。

3. 上升沿和下降沿中断:当 GPIO 的电平从低电平跳变成高电平和从高电平跳变成低电

平时,都能引发外部中断

每当产生外部中断时,程序首先会进入外部中断服务函数。在 stm32f4xx_it.c 中,可以找到函数EXTI0_IRQHandler,它通过调用函数 HAL_GPIO_EXTI_IRQHandler 对中断类型进行 判断,并对涉及中断的寄存器进行处理,在处理完成后,它将调用中断回调函数 HAL_GPIO_EXTI_Callback,在中断回调函数中编写在此次中断中需要执行的功能。外部中断的使用如下:

STM32的定时器分为基本(TIM6/TIM7)、通用(TIM2/TIM3 /TIM4 /TIM5 )、高级TIM1/TIM8)三种,定时器通过psc分频从主频获得一定的频率。三种定时器的区别如下:

一个定时器通常有4个独立通道,可用于:输入捕获、输出比较、输出PWM、单脉冲模式。 输出PWM:PWM的主要用途是控制舵机或电机。定时器输出PWM原理,PWM波周期或频率由ARR决定,PWM波占空比由CCRx决定。通过这样IO口输出一定比例的方波信号。  在进行PWM信号输出时,有两种PWM模式:PWM1模式和PWM2模式。 举个例子就明白了:假设定时器设置为递增计数模式,输出有效电平的极性为高电平。PWM1模式的初始电平为高电平,发生匹配时,翻转为低电平。PWM2模式的初始电平为低电平,发生匹配时,翻转为高电平。不同输出模式对应不同的输出波形,通常采用PWM1。

PWM频率的计算方法:

4.3通信协议总结:

4.3.1 ++++IIC++++++

I2C 是一种半双工、双向二线制同步串行总线。两线制代表 I2C 只需两根信号线,一根数据线 SDA,另一根是时钟线 SCL。 I2C 总线允许挂载多个主设备,但总线时钟同一时刻只能由一个主设备产生,并且要求每个

连接到总线上的器件都有唯一的 I2C 地址,从设备可以被主设备寻址。

I2C 通信具有几类信号:

1.开始信号 S:当 SCL 处于高电平时,SDA 从高电平拉低至低电平,代表数据传输的开

始。

2. 结束信号 P:当 SCL 处于高电平时,SDA 从低电平拉高至高电平,代表数据传输结束。

3. 数据信号:数据信号每次都传输 8 位数据,每一位数据都在一个时钟周期内传递,当

SCL 处于高电平时候,SDA 数据线上的电平需要稳定,当 SCL 处于低电平的时候,

SDA 数据线上的电平才允许改变。

4. 应答信号 ACK/NACK:应答信号是主机发送 8bit 数据,从机对主机发送低电平,表示

已经接受数据。

OLED 模块使用 I2C 通信,I2C 设备的默认IIC地址为 0x78,可以通过手动修改左上方的电

阻来配置 I2C 地址为 0x7A。具体的OLED库可以自行百度学习。

4.3.2 ++++SPI++++++

SPI 是一种全双工的通信协议,主设备和从设备通信时,两端的收发是同步进行的,即主设

备和从设备在向对方发送数据的同时,也在接收对方发来的数据。采用四根线进行通信,具体如下:

SPI 的通信过程如下:

主设备将要进行通讯的从设备的 SS/CS 片选拉低, 每个从设备都有自己的CS片选引脚,需要和其通信时将这个IO的电平引脚拉低。如下图中的CS1_Accel和Gyro引脚:

主设备通过 SCK 向从设备提供同步通讯所需要的时钟信号,3. 主设备通过 MOSI 向从设备发送 8 位数据,同时通过 MISO 接收从设备发来的 8 位数 据。 通信结束,主设备拉高 SS/CS 片选。

SPI 的时序规定了不同的工作模式,如下表所示:

4.3.2 ++++RS485++++++

RS485是串行通信标准,使用差分信号传输,抗干扰能力强,常用于工控领域,大学里如果不搞PLC的话其实基本不用。RS485具有强大的组网功能,在串口基础协议之上还制定MODBUS协议。RS485电平标准与TTL电平标准不同,因次RS485电平标准设备和TTL电平标准设备通信时需要转接模块,如:

以正点原子的开发板为例:通过TP8485芯片使单片机可以像UART通信那样和其他设备通过RS485协议通信,注意这是硬件基础!!!!之后便是编写RS485的库,这个可以参考正点原子的库。

4.3.2 ++++CAN++++++

CAN通信在远距离和多设备通信时具有极好的优越性,广泛应用于工业(尤其是汽车)中。如果你负责RM的电控,那么恭喜你以后将会以CAN通信为基础,仅用两根线CAN_H和CAN_L控制整车高达7台左右的电机并准确接收电机反馈回来的数据包。以下我将从硬件和软件两个层面介绍CAN:

硬件层面:

由于CAN所使用的电平标准与TTL电平标准有所不同,所以在单片机与CAN的两个(CAN_H和CAN_L)输出端之间需要一个电平转换芯片,通常为SIT1050T:

代码层面:

CAN使用差分信号进行数据传输,根据CAN_H和CAN_L上的电位差来判断总线电平。总线电平分为显性电平(逻辑0)和隐性电平(逻辑1),二者必居其一。显性电平具有优先权。发送方通过使总线电平发生变化,将消息发送给接收方。(正点原子的总结精辟又准确)

CAN总线以“帧”形式进行通信。CAN协议定义了5种类型的帧:数据帧、遥控帧、错误帧、过载帧、间隔帧.这里重点介绍 CAN 的仲裁场和数据场的内容。和 I2C 总线一样,每一个挂载在 CAN 总线 上的 CAN 都有一个自己独属的 ID,每当一个设备发送一帧数据时,总线其他设备会检查这 个 ID 是否是自己需要接收数据的对象,如果是则接收本帧数据,如果不是则忽略。 ID 存储在数据帧最前头的仲裁场内,CAN 的 ID 分为标准 ID 和拓展 ID 两类,标准 ID 长度 为 11 位。如果设备过多,标准 ID 不够用的情况下,可以使用拓展 ID,拓展 ID 的长度有 29 位.在通过 ID 判断本帧数据可以接收后,控制场中的 DLC 规定了本帧数据的长度,而数据场内 的数据的大小为 8 Byte,即 8 个 8 位数据。CAN 总线的一个数据帧中所需要传输的有效数 据实际上就是这 8Byte。

下面提供一个应用案例(利用CAN控制RM电机):

如果要发送数据给 1 号到 4 号电调,控制电机的输出电流,从而控制电机转速时,需要按照表中的内容,将发送的 CAN 数据帧的 ID 设置为 0x200,数据域中的 8Byte 数据按照电调 1 到 4 的高八位和第八位的顺序装填。MCU可以接受电机发送过来的包,通过接收到的 ID 判断究竟接收到的是哪个电调发送来的数据,RM手册中规定 1 号电调 ID 为 0x201,2 号为 0x202,3 号为 0x203,4 号为 0x204。判断完数据来源之后,就可以按 照手册中的数据格式进行解码,通过高八位和第八位拼接的方式,得到电机的转子机械角度, 转子转速,转矩电流,电机温度等数据。注意:RM每个电机的ID通过硬件层面的操作完成,比如GM6020电机通过其底部不同的开关的位置设置ID,对应ID号参考大疆对电机的说明文档。

关于CAN协议的详细知识例如CAN滤波器呀啥的可以进行深入研究,但是我相信肯定是今天看完明天忘掉,HAL库已经对CAN通信做了很好的封装,因此我认为底层的东西了解个大概就好,具体会用就行。(PS:大佬勿喷,能学的深入点是好的)

5.DMA:

DMA传输无需CPU直接控制传输,也没有中断处理方式那样保留现场和恢复现场过程,通过硬件为RAM和IO设备开辟一条直接传输数据的通道,使得CPU的效率大大提高.

//下班了,这里还没写完有空再更

6.keil的使用

5.1基本控件的使用

关于keil的下载或者是使用中会出现的问题每个人不尽相同,遇到问题最好的解决办法是百度。因此本文不对这方面的问题做过多的介绍。关于使用技巧,我认为最重要的使ctrl+F,这个功能可以在当前文件或整个工程中定位你所想查找的关键词的位置,方便代码调试。

keil可以进行仿真,具体如何使用详见正点原子HAL库视频,里面有详细介绍,这里进重点强调部分内容。代码调试时,现将STLINK连接好,如下图所示:

调试相关的控件在窗口的右上角,具体的解释如下所示。依据这个功能,可以加断点让程序运行到你所指定的位置停止,以此来一行一行的运行代码或者是运行嵌套的代码便于更好的定位到代码错误的地方。

还有一个很重要的DEBUG功能是可以在在 watch 窗口查看变量的实时数据和变量类型,这在调PID,陀螺仪能应用场景中是极为方便的。

关于keil的使用注意事项或者技巧好像也没啥了,在使用的过程中可以自行探索。

好文阅读

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。