功能主要为初始化ADC和DMA,并检测STM32F407开发板端口电流、电压、以及内部温度传感器的值。
.c文件
ADC_DATA adc_buf[10];
Battery battery;
//函数功能 : 启动GPIOC_PIN4与GPIOC_PIN5(本开发板测电流和电压用的引脚)的ADC模数转换,并且启动DMA数据传输
void Battery_ADC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStruct;
ADC_CommonInitTypeDef ADC_CommonInitStruct;
ADC_InitTypeDef ADC_InitStruct;
DMA_InitTypeDef DMA_InitStruct;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2,ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
GPIO_InitStruct.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5;
GPIO_InitStruct.GPIO_Speed = GPIO_High_Speed;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AN; //模拟输入
GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC,&GPIO_InitStruct);
ADC_CommonInitStruct.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; //禁止DMA模式(多个ADC有效,DMA切换方式)
ADC_CommonInitStruct.ADC_Mode = ADC_Mode_Independent; //设置ADC模式为独立模式
ADC_CommonInitStruct.ADC_Prescaler = ADC_Prescaler_Div4; //ADC最大频率为36MHZ,时钟树上的APB1的频率为84MHZ,所以为4分频
ADC_CommonInitStruct.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; //设定两个采样之间的间隔
ADC_CommonInit(&ADC_CommonInitStruct);
ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //连续转换模式
ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //数据右对齐
ADC_InitStruct.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;//启动外触发方式
ADC_InitStruct.ADC_NbrOfConversion = 3; //PC4 PC5 TempSensor 三个需要转换
ADC_InitStruct.ADC_Resolution = ADC_Resolution_12b; //采集密度
ADC_InitStruct.ADC_ScanConvMode = ENABLE; //开启扫描模式
ADC_Init(ADC1,&ADC_InitStruct);
//设置通道第几个转换以及采样周期
ADC_RegularChannelConfig(ADC1,ADC_Channel_14,1,ADC_SampleTime_480Cycles);//P4通道
ADC_RegularChannelConfig(ADC1,ADC_Channel_15,2,ADC_SampleTime_480Cycles);//P5通道
ADC_RegularChannelConfig(ADC1,ADC_Channel_16,3,ADC_SampleTime_480Cycles);//TempSensor,通道的确立参见引脚表
ADC_TempSensorVrefintCmd(ENABLE);//使能内部温度传感器
DMA_InitStruct.DMA_Channel = DMA_Channel_0; //选择通道0
DMA_InitStruct.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; //选择外设地址
DMA_InitStruct.DMA_Memory0BaseAddr = (uint32_t)&adc_buf[0]; //内存基地址
DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralToMemory; //寄存器->内存
DMA_InitStruct.DMA_BufferSize = sizeof(ADC_DATA)*10/2; //整体的数据个数
DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; //使能内存地址自增
DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //寄存器不需要自增
DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//一次传输半字,对于STM32来说一个字等于4个字节
DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //传输一次半字(两个字节)
DMA_InitStruct.DMA_Mode = DMA_Mode_Circular; //开启循环模式
DMA_InitStruct.DMA_Priority = DMA_Priority_High; //优先级高
DMA_InitStruct.DMA_FIFOMode = DMA_FIFOMode_Disable; //禁用FIFO
DMA_InitStruct.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; //选择FIFO阈值,这里没有用到
DMA_InitStruct.DMA_MemoryBurst = DMA_MemoryBurst_Single; //单次转换模式
DMA_InitStruct.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; //单次转换模式
DMA_Init(DMA2_Stream0,&DMA_InitStruct);
DMA_Cmd(DMA2_Stream0,ENABLE); //使能DMA2通道0
ADC_DMARequestAfterLastTransferCmd(ADC1,ENABLE); //ADC1要开启DMA
ADC_DMACmd(ADC1, ENABLE); //使能ADC1的DMA模式
ADC_Cmd(ADC1,ENABLE); //使能ADC1
ADC_SoftwareStartConv(ADC1); //使ADC1开启软件启动功能
}
//函数说明 : 使用10阶滑动滤波的方式进行数据滤波,得出滤波之后的电流值和电压值
void Get_Battery(void)
{
ADC_DATA buff = {0};
for(uint8_t i = 0;i<10;i++) //采集十次电流、电压、温度值
{
buff.current += adc_buf[i].current;
buff.voltage += adc_buf[i].voltage;
buff.temperature += adc_buf[i].temperature;
}
battery.current = (buff.current/10.0+1.0)*3.3/4096.0; //计算后的电流值
battery.voltage = (buff.voltage/10.0+1.0)*3.3/4096.0; //计算后的电压值
battery.temperature = (buff.temperature/10*3.3/4095-0.76)/0.0025+25; //计算后的内部温度值
}
.h文件
#include "stm32f4xx.h"
typedef struct
{
float current; //电流信息A
float voltage; //电压信息V
float temperature;//电池温度℃
}Battery;
typedef struct
{
uint16_t current;
uint16_t voltage;
uint16_t temperature;
}ADC_DATA;
void Battery_ADC_Init(void);
void Get_Battery(void);