我是靠谱客的博主 个性鸡,这篇文章主要介绍【STM32】STM32之电量采集,现在分享给大家,希望可以做个参考。

本篇博文最后修改时间:2016年10月27日,12:16。


一、简介

本文介绍如何在STM32上使用ADC1的第9通道,对电池电量进行采集


二、实验平台

库版本:STM32F10x_StdPeriph_Lib_V3.5.0

编译软件:MDK4.53

硬件平台:STM32开发板(主芯片stm32f103c8t6)

仿真器:JLINK


版权声明

博主:甜甜的大香瓜

声明:喝水不忘挖井人,转载请注明出处。

原文地址:http://blog.csdn.NET/feilusia

联系方式:897503845@qq.com

香瓜BLE之CC2541群:127442605

香瓜BLE之CC2640群:557278427

香瓜BLE之Android群:541462902

香瓜单片机之STM8/STM32群:164311667
甜甜的大香瓜的小店(淘宝店):https://shop217632629.taobao.com/?spm=2013.1.1000126.d21.hd2o8i

四、硬件原理

1)硬件原理图



由上图可知通过PB1口采集电压,其中采集的电压为锂电池经过分压后的电压。

锂电池电压范围为3V~4.2V。


2)采集电压引脚的通道


其中ADC12_IN9,是指可以是ADC1的第9通道,也可以是ADC2的第9通道。


五、基础知识

1、stm32f103c8t6的ADC是如何的?

答:

stm32f103c8t6这款芯片一共有2个ADC,每个ADC有18个通道,每个通道有12bit。

最大的转换速率为1MHz(转换时间1us),时钟不要超过14M,否则准确度会下降。

2、什么是规则通道组和注入通道组?
答:规则通道组是普通的ADC组,而注入通道组具有优先级更高的抢占式权利,能随时打断规则通道组的ADC通道,获得ADC转换的优先权。
类似于我们在买票时,规则通道组是普通老百姓,而注入通道组是老人、军人,他们可以任意插队……

六、实验步骤

1、编写ADC的驱动

1)编写驱动GUA_ADC1.c(存放在“……HARDWARE”)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//****************************************************************************** //name: GUA_ADC1.c //introduce: ADC1驱动 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.29 //****************************************************************************** #include "stm32f10x.h" #include "GUA_ADC1.h" /*********************内部函数声明************************/ static GUA_U16 GUA_ADC1_Read(GUA_U8 nGUA_Channel); //****************************************************************************** //name: GUA_ADC1_Read //introduce: ADC1的通道数值读取 //parameter: nGUA_Channel:ADC1的采集通道 //return: 该通道采集的数值 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.29 //****************************************************************************** static GUA_U16 GUA_ADC1_Read(GUA_U8 nGUA_Channel) { //规则采样顺序值为1,采样时间为 239.5 周期 ADC_RegularChannelConfig(ADC1, nGUA_Channel, 1, ADC_SampleTime_239Cycles5); //开始转换 ADC_SoftwareStartConvCmd(ADC1, ENABLE); //等待转换结束 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC)); //返回转换结果 return ADC_GetConversionValue(ADC1); } //****************************************************************************** //name: GUA_ADC1_ReadAverage //introduce: ADC1的通道数值读取 //parameter: nGUA_Channel:ADC1的采集通道 // nGUA_times:求平均值的次数 //return: 该通道采集的数值 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.29 //****************************************************************************** GUA_U16 GUA_ADC1_ReadAverage(GUA_U8 nGUA_Channel, GUA_U8 nGUA_times) { GUA_U32 nGUA_Value_Sum = 0; GUA_U8 i; //累加读取到的数值 for(i = 0; i < nGUA_times; i++) { nGUA_Value_Sum += GUA_ADC1_Read(nGUA_Channel); } //求出平均值并返回 return nGUA_Value_Sum/nGUA_times; } //****************************************************************************** //name: GUA_ADC1_Init //introduce: ADC1初始化 //parameter: none //return: none //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.29 //****************************************************************************** void GUA_ADC1_Init(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; //开GPIOB、ADC1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_ADC1, ENABLE); //ADC最大频率不能超过14M,否则不准,因此使用72M/6=12M RCC_ADCCLKConfig(RCC_PCLK2_Div6); //IO初始化 GPIO_InitStructure.GPIO_Pin =GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; GPIO_Init(GPIOB, &GPIO_InitStructure); //ADC1配置复位 ADC_DeInit(ADC1); //ADC1配置 ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //独立模式 ADC_InitStructure.ADC_ScanConvMode = DISABLE; //单通道模式 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; //单次转换模式 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件触发 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐 ADC_InitStructure.ADC_NbrOfChannel = 1; //顺序进行规则转换的ADC通道的数目 ADC_Init(ADC1, &ADC_InitStructure); //初始化配置 //使能 ADC_Cmd(ADC1, ENABLE); //校准 ADC_ResetCalibration(ADC1); //开启复位校准 while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束 ADC_StartCalibration(ADC1); //开启AD校准 while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束 }
对外接口函数为初始化函数、求多次平均值后的采集数据。

2) 编写驱动头文件 GUA_ADC1.h(存放在“ …… HARDWARE ”)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//****************************************************************************** //name: GUA_ADC1.h //introduce: ADC1驱动的头文件 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.29 //****************************************************************************** #ifndef _GUA_ADC1_H_ #define _GUA_ADC1_H_ /*********************宏定义************************/ #ifndef GUA_U8 typedef unsigned char GUA_U8; #endif #ifndef GUA_8 typedef signed char GUA_8; #endif #ifndef GUA_U16 typedef unsigned short GUA_U16; #endif #ifndef GUA_16 typedef signed short GUA_16; #endif #ifndef GUA_U32 typedef unsigned long GUA_U32; #endif #ifndef GUA_32 typedef signed long GUA_32; #endif #ifndef GUA_U64 typedef unsigned long long GUA_U64; #endif #ifndef GUA_64 typedef signed long long GUA_64; #endif /*********************外部函数************************/ extern GUA_U16 GUA_ADC1_ReadAverage(GUA_U8 nGUA_Channel, GUA_U8 nGUA_times); extern void GUA_ADC1_Init(void); #endif

2、编写电量采集的驱动

1)编写驱动GUA_Battery_Check.c(存放在“……HARDWARE”)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
//****************************************************************************** //name: GUA_Battery_Check.c //introduce: 电量检测驱动 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.28 //****************************************************************************** #include "stm32f10x.h" #include "GUA_ADC1.h" #include "GUA_Battery_Check.h" /*********************宏定义************************/ #define GUA_BATTERY_CHECK_COUNT_PER_COLLECT 5 //每次采集的次数 //****************************************************************************** //name: GUA_Battery_Check_Read //introduce: 读电量 //parameter: none //return: 返回16bit的电量,右对齐 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.28 //****************************************************************************** GUA_U16 GUA_Battery_Check_Read(void) { GUA_U16 nGUA_Battery_Check_Value = 0; GUA_U16 nGUA_Num = 0; //采集BATTERY_CHECK_COUNT_PER_COLLECT次,累加采集的电量值 for(nGUA_Num = 0; nGUA_Num < GUA_BATTERY_CHECK_COUNT_PER_COLLECT; nGUA_Num++) { //累加读取adc的转换值 nGUA_Battery_Check_Value += GUA_ADC1_ReadAverage(ADC_Channel_9, 1); } //求出电量平均值 nGUA_Battery_Check_Value /= GUA_BATTERY_CHECK_COUNT_PER_COLLECT; //返回 return nGUA_Battery_Check_Value; } //****************************************************************************** //name: GUA_Battery_Check_Init //introduce: 电量检测初始化 //parameter: none //return: none //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.28 //****************************************************************************** void GUA_Battery_Check_Init(void) { //ADC1初始化 GUA_ADC1_Init(); }

2) 编写驱动头文件GUA_ Battery_Check.h(存放在“ …… HARDWARE ”)
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
//****************************************************************************** //name: GUA_Battery_Check.h //introduce: 电量检测的头文件 //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.28 //****************************************************************************** #ifndef _GUA_BATTERY_CHECK_H_ #define _GUA_BATTERY_CHECK_H_ /*********************宏定义************************/ #ifndef GUA_U8 typedef unsigned char GUA_U8; #endif #ifndef GUA_8 typedef signed char GUA_8; #endif #ifndef GUA_U16 typedef unsigned short GUA_U16; #endif #ifndef GUA_16 typedef signed short GUA_16; #endif #ifndef GUA_U32 typedef unsigned long GUA_U32; #endif #ifndef GUA_32 typedef signed long GUA_32; #endif #ifndef GUA_U64 typedef unsigned long long GUA_U64; #endif #ifndef GUA_64 typedef signed long long GUA_64; #endif /*********************外部函数声明************************/ GUA_U16 GUA_Battery_Check_Read(void); void GUA_Battery_Check_Init(void); #endif

3、工程中添加自己写的驱动

1)工程中添加GUA_ADC1.c和GUA_Battery_Check.c



2)在MDK设置中添加驱动源文件路径



4、添加库的驱动

1)添加库的驱动文件



2)添加库的驱动头文件(stm32f10x_conf.h 中)

复制代码
1
#include "stm32f10x_adc.h"

5、在应用层中调用

1)添加驱动头文件(main.c中)

复制代码
1
#include "GUA_Battery_Check.h"

2) 添加驱动初始化代码(main.c的main函数中)

复制代码
1
2
//电源电量采集 GUA_Battery_Check_Init();

3)添加测试代码

①写测试代码(main.c中)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//****************************************************************************** //name: GUA_Test //introduce: 测试代码 //parameter: none //return: none //author: 甜甜的大香瓜 //email: 897503845@qq.com //QQ group 香瓜单片机之STM8/STM32(164311667) //changetime: 2016.12.29 //****************************************************************************** static void GUA_Test(void) { U16 nGUA_Battery_Check_Value = 0; while(1) { //读取电量 nGUA_Battery_Check_Value = GUA_Battery_Check_Read(); } }

②调用测试代码 main.c的main函数中

复制代码
1
2
//测试代码 GUA_Test();

七、实验结果

仿真并查看测试代码中电量读取情况,如下图


上图可知读取到的电量数值为2760,由于adc的精度是12bit(4096)、参考电压为3.3V,因此实际读出的电量值为2760*3.3/4096=2.2236328125V

由于该采集电压是经过分压后的,代入公式“Vbat*75/(51+75)=2.2236328125”后,可计算出Vbat=3.735703125V。

用万用表实测锂电池电压为3.7V(200V档)。

因此实验成功。




最后

以上就是个性鸡最近收集整理的关于【STM32】STM32之电量采集的全部内容,更多相关【STM32】STM32之电量采集内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(76)

相关文章

评论列表共有 0 条评论

立即
投稿
返回
顶部