使用HAL库开发铁头山羊平衡车测锂电池电压篇

本人第一次接触HAL库,因熟练度不高想找个练手的项目,遂翻看b站铁头山羊平衡车教学,不过这个up是用标准库做的,准备用hal库复刻一下

第一次写博客,多为碎碎念,给自己看的,如果有其他人在这里有所收获那也是最好的了

一、首先是CubeMx的点点点篇:

分为ADC部分,TIM部分,USART部分

ADC:

我们先来看一下ADC的内部结构框图

我们采用ADC1的IN8通道采集电池电压,并且使用TIM2的TRGO的update事件的方式(即外部触发),向ADC输出10ms一次的频率信号来触发ADC的转换(注意是ADC的转换频率),然后开启中断,在中断程序里面通过判断标志位JEOC来获取JDR1的值并且进行电压转换(乘以系数)

所以其实在ADC里又分为了几个步骤:

1.TIM2的更新频率配置

先简单配置一下时钟树吧

由于ADC的最大频率有限制,我们这里采用6分频,12MHZ

要配置成10ms一次的话,我们主频采用72MHZ,将PSC设置成71,ARR设置成999

2.配置TIM2的从模式控制器

这里我们选择从模式控制器为主控制器且为update模式,即TIM2每溢出一次,就会向外发送一个脉冲信号,这个脉冲信号来控制ADC转换的频率

ENABLE + Update Event

至此我们的TIM2配置完成

3.配置ADC1

首先选中ADC1的IN8通道,这里不加图片了

接着配置ADC1的注入通道

Enable开启,启用注入转换,打开这个开关

Number of conversions多个转换数量的设计可以让多个 ADC 通道的采样值被分别存储到不同的寄存器中,从而支持多通道的并行或串行采样处理,但是这里只用到一个

这个参数Number of conversions的数量也决定你接下来Rank的数量

然后配置ADC的外部触发来源External Trigger Source为Timer2的TRGO输出作为输入

即Timer 2 Trigger Out event,将TIM2的TRGO与ADC的外部触发输入联系起来

4.展开Rank(rank:序号,即JDR第几个寄存器),对其进行具体配置

Channel,寄存器可以根据通道灵活绑定,如存在多个通道,寄存器的值可以在多个Channel里选择其中的一个,这个不是固定的,这里只用到channel8

1.5Cycles即转换的周期

5.ADC的NVIC

由于我们要在中断函数里转换,所以NVIC是要勾选的,这里勾选相当于闭合中断开关

6.其余一些我也不确定的参数,后面再考虑吧不是很重要

Independent mode独立模式,ADC1和ADC2互不干扰,也是一般默认的模式

对齐方式Right alignment右对齐,一般采用右对齐,也是默认的参数

TIM部分:由于和ADC配合使用,前面已经带过,不加赘述了

USART部分:

选择异步模式,926100的波特率,其他值默认

至此我们的CubeMx点点点篇就结束了,接下来的Keil环境的代码部分

二:在Keil代码编写之前,CubeMx的一些准备工作

勾选一下这个,可以获取我们的.c和.h文件,这样更方便模块化编程和管理,不然文件会合在一起

三:为了代码管理规范,我对keil文件的一些调整

1.不知道是不是我没勾选什么选项,我文件目录只有.c文件没有.h文件,所以这里的操作是针对我个人的,不知道其他人有没有这样的问题

单击品字,选中存放.c文件的目录呈现蓝色高亮

单击右下角的Add Files按钮,在Core->Inc里面选中所有的.h文件,具体有些细节不多说了

然后单击OK就可以了,目录中会出现所有的.c和.h文件

2.为了方便测试,我一般会把测试.c.h文件放到test文件夹里

这里展示一下新建test文件夹的方法,右击,新建组

会有一个New Group,但是以后新建的时候就不会产生了,因为会有重命名的问题,所以最好是创建一个new group我们就改一次名,改名在品字那里双击,这里不细说,添加文件也是在品字那里

先创建好一个文件夹,然后创建两个txt文件,后面改后缀为.c.h添加进test即可

四:正式开始我们的Keil代码编写

这里再次明确一下我们的思路:

在中断函数当中读取ADC的JDR寄存器的值,由于值是ADC的量化范围,所以需要转换成电压值再通过串口打印

所以说在Keil代码编写的时候,又分为了几个部分

1.最基本的初始化

我这里ADC中断忘记开了

2.ADC的中断配置代码

由于注释区域的存在,我们.c代码写在USER CODE BEGIN 0与END之间

另外.h文件是需要声明函数和全局变量的的,这里写在Prototypes之间

vbat:全局变量,声明的注释区域和函数的注释区域一样

        由于需要跨文件使用需要加上extern关键字,在中断中的变量需要加上volatile关键字

        这里在.c中声明的时候不需要加extern,在.h中加extern,这里解释一下:

        头文件(.h)的作用是被多个 .c 文件包含,必须加extern关键字

        .c中是定义变量,而不是声明,一句话总结就是.c定义一次.h声明被多个.c使用

        全局变量在一个 .c 文件中定义一次,在 .h 文件中用 extern 声明,供多个 .c 文件包含使用

        PS:后面我不加extern和volatile也没事,不知道为什么,但是为了规范性还是加上

void HAL_ADCEx_InjectedConvCpltCallback(ADC_HandleTypeDef* hadc):

        中断函数,写在哪里都无所谓,触发中断时会自动执行里面的操作

float app_bat_get(void):很简单的一个获取vbat值的函数

.c

.h

3.USART的代码:

这里由于是要发送浮点数,已知普通的HAL_UART_Transmit满足不了需求,所以我写了一个自用的函数,并在.h中声明

这里我才第一次了解到,原来#include头文件也可以放在user code里,涨知识了用的还是太少了

4.我们的测试程序test

这里我在test文件夹里已经建好了.c和.h文件,代码如图所示

在test文件夹写好程序后,就可以在main函数里include该测试程序了

5.使用Vofa测试

其实使用什么软件测试倒是无所谓,这里直接给看结果:

测得电压为2.06v

至此测电池电压的部分就结束了,我也没想到能写这么多字,估计是第一次用HAL库的问题实在是太多了

以后的教程应该会精简很多

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值