无人机底层驱动+STM32F4学习心得-3.ADC/DMA初始化

功能主要为初始化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);

猜你喜欢

转载自blog.csdn.net/qq_41422043/article/details/83756535
今日推荐