当前位置: 上海铭静电子科技有限公司 » 单片机

STM32通过DMA采集多通道AD

分类:单片机 发布:2018年05月13日 15:13 浏览:861次 Tag:

环境:

主机:XP

开发环境:MDK4.23

MCU:STM32F103CBT6


说明:

通过脚PA1,PA2采集AD。每路AD采集10次。

#include "ad_driver.h"  

  

//全局变量  

//AD采样存放空间  

__IO uint16_t ADCConvertedValue[20];  

  

//函数  

//初始化AD  

void init_ad(void)  

{  

    ADC_InitTypeDef ADC_InitStructure;  

    DMA_InitTypeDef DMA_InitStructure;  

    GPIO_InitTypeDef GPIO_InitStructure;  

  

    //---------------------充电AD初始化--------------------  

    //启动DMA时钟  

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);  

  

    //启动ADC1时钟  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);  

  

    //采样脚设置  

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);  

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;  

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;  

    GPIO_Init(GPIOA, &GPIO_InitStructure);  

  

    //DMA1通道1配置  

    DMA_DeInit(DMA1_Channel1);  

    //外设地址  

    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_ADDRESS;  

    //内存地址  

    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)ADCConvertedValue;  

    //dma传输方向单向  

    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  

    //设置DMA在传输时缓冲区的长度  

    DMA_InitStructure.DMA_BufferSize = 20;  

    //设置DMA的外设递增模式,一个外设  

    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;  

    //设置DMA的内存递增模式  

    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;  

    //外设数据字长  

    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  

    //内存数据字长  

    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;  

    //设置DMA的传输模式:连续不断的循环模式  

    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  

    //设置DMA的优先级别  

    DMA_InitStructure.DMA_Priority = DMA_Priority_High;  

    //设置DMA的2个memory中的变量互相访问  

    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;  

    DMA_Init(DMA1_Channel1, &DMA_InitStructure);  

      

    //使能通道1  

    DMA_Cmd(DMA1_Channel1, ENABLE);  

  

    //ADC1配置  

    //独立工作模式  

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  

    //扫描方式  

    ADC_InitStructure.ADC_ScanConvMode = ENABLE;  

    //连续转换  

    ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;  

    //外部触发禁止  

    ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;  

    //数据右对齐  

    ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;  

    //用于转换的通道数  

    ADC_InitStructure.ADC_NbrOfChannel = 2;  

    ADC_Init(ADC1, &ADC_InitStructure);  

      

    //规则模式通道配置  

    ADC_RegularChannelConfig(ADC1, ADC_Channel_1 , 1, ADC_SampleTime_239Cycles5);  

    ADC_RegularChannelConfig(ADC1, ADC_Channel_2 , 2, ADC_SampleTime_239Cycles5);  

      

    //使能ADC1的DMA  

    ADC_DMACmd(ADC1, ENABLE);  

      

    //使能ADC1  

    ADC_Cmd(ADC1, ENABLE);  

      

    //使能ADC1复位校准寄存器    

    ADC_ResetCalibration(ADC1);  

    //检查校准寄存器是否复位完毕  

    while(ADC_GetResetCalibrationStatus(ADC1));  

      

    //开始校准  

    ADC_StartCalibration(ADC1);  

    //检测是否校准完毕  

    while(ADC_GetCalibrationStatus(ADC1));  

       

    //开启ADC1的软件转换  

    ADC_SoftwareStartConvCmd(ADC1, ENABLE);  

}  

  

//获得充电电压  

float voltage_charge(void)  

{  

    uint8_t i = 0;  

    uint16_t sum = 0;  

    float v = 0;  

  

    //取得10次充电电压平均值  

    for (i = 0;i < 10;i++)  

    {  

        sum += ADCConvertedValue[i * 2];   

    }  

    sum /= 10;  

    //变换成电压值  

    v = 0.002991 * sum;  

  

    return v;  

}  

  

//获得放电电压  

float voltage_discharge(void)  

{  

    uint8_t i = 0;  

    uint16_t sum = 0;  

    float v = 0;  

  

    //取得10次充电电压平均值  

    for (i = 0;i < 10;i++)  

    {  

        sum += ADCConvertedValue[i * 2 + 1];   

    }  

    sum /= 10;  

    //变换成电压值  

    v = 0.002991 * sum;  

  

    return v;  

}  


相关文章
 
资讯栏目
最新资讯
资讯排行
 

收缩
  • 电话咨询

  • 021-31007558