STM32F103系列多通道采集ADC

2024-07-01 12:28:02 浏览数 (2)

adc.c

代码语言:javascript复制
#include "adc.h"

uint16_t ADC_Converted_Value[ADC_NOFCHANNEL]={0,0,0,0,0,0,0,0,0,0};

static void AdcGpioInit(void)
{
    GPIO_InitTypeDef    GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(ADC_GPIO_CLK0 | ADC_GPIO_CLK1,ENABLE);
    
    //PA0~PA7
    GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN0 | ADC_GPIO_PIN1 | ADC_GPIO_PIN2 | 
                                  ADC_GPIO_PIN3 | ADC_GPIO_PIN4 | ADC_GPIO_PIN5 |
                                  ADC_GPIO_PIN7 ;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(ADC_GPIO_PORT0,&GPIO_InitStructure);
    
    //PB0 PB1
    GPIO_InitStructure.GPIO_Pin = ADC_GPIO_PIN8 | ADC_GPIO_PIN9;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(ADC_GPIO_PORT1,&GPIO_InitStructure);
}


static void AacModeConfig(void)
{
    DMA_InitTypeDef        DMA_InitStructure;
    ADC_InitTypeDef        ADC_InitStructure;
    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
    RCC_APB2PeriphClockCmd(ADC_CLK,ENABLE);
    //复位
    DMA_DeInit(ADC_DMA_CHANNEL);
    //配置dma
    DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)(&(ADC1->DR));                //ADC数据寄存器地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADC_Converted_Value;            //内部SRAM的变量
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;                                //数据源来自外设
    DMA_InitStructure.DMA_BufferSize = ADC_NOFCHANNEL;                                //缓冲区为10
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;                //地址不递增
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Disable;                        //存储器地址固定
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;        //外设数据大小为两个字节
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;                //存储数据大小为两个字节
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;                                    //循环传输模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;                                //DMA传输通道优先级最高
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;                                    //禁止存储器到存储器模式
    
    //初始化DMA
    DMA_Init(ADC_DMA_CHANNEL,&DMA_InitStructure);
    DMA_Cmd(ADC_DMA_CHANNEL,ENABLE);
    
    //ADC独立通道模式
    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 = ADC_NOFCHANNEL;                            //转换通道十个
    
    //初始化ADC
    ADC_Init(ADC1,&ADC_InitStructure);    
    //配置ADC时钟为 PCLK2的6分频  72/6=12MHz  ADC最大时间尽量不超过14M
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);        
    //配置ADC通道转换顺序为1,第一个转换,采样时间为239.5个时钟周期采集周期长一点越精确
    //ADC_RegularChannelConfig(ADC1,ADC_CHANNEL0,0,ADC_SampleTime_239Cycles5);//PA0
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL1,1,ADC_SampleTime_239Cycles5);//PA1
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL2,2,ADC_SampleTime_239Cycles5);//PA2
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL3,3,ADC_SampleTime_239Cycles5);//PA3
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL4,4,ADC_SampleTime_239Cycles5);//PA4
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL5,5,ADC_SampleTime_239Cycles5);//PA5
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL6,6,ADC_SampleTime_239Cycles5);//PA6
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL7,7,ADC_SampleTime_239Cycles5);//PA7
    
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL8,8,ADC_SampleTime_239Cycles5);//PB0
    ADC_RegularChannelConfig(ADC1,ADC_CHANNEL9,9,ADC_SampleTime_239Cycles5);//PB1
    
    ADC_DMACmd(ADC1,ENABLE);
    ADC_Cmd(ADC1,ENABLE);
    //校准寄存器
    ADC_ResetCalibration(ADC1);
    //等待校准寄存器初始化完成
    while(ADC_GetResetCalibrationStatus(ADC1));
    //开始校准
    ADC_StartCalibration(ADC1);
    
    while(ADC_GetCalibrationStatus(ADC1));
    //软件触发ADC转换
    ADC_SoftwareStartConvCmd(ADC1,ENABLE);
    
}

void AdcInit(void)
{
    AdcGpioInit();
    AacModeConfig();
}

adc.h

代码语言:javascript复制
#ifndef _ADC_H_
#define _ADC_H_

#include "stm32f10x.h"

#define ADC_NOFCHANNEL                10
#define ADC_CLK                        RCC_APB2Periph_ADC1

#define ADC_GPIO_CLK0                RCC_APB2Periph_GPIOA
#define ADC_GPIO_PORT0                GPIOA

#define ADC_GPIO_CLK1                RCC_APB2Periph_GPIOB
#define ADC_GPIO_PORT1                GPIOB


#define ADC_DMA_CHANNEL                DMA1_Channel1
//PA0
//#define ADC_GPIO_PIN0                GPIO_Pin_0
//#define ADC_CHANNEL0                ADC_Channel_0
//PA1
#define ADC_GPIO_PIN1                GPIO_Pin_1
#define ADC_CHANNEL1                ADC_Channel_1
//PA2
#define ADC_GPIO_PIN2                GPIO_Pin_2
#define ADC_CHANNEL2                ADC_Channel_2
//PA3
#define ADC_GPIO_PIN3                GPIO_Pin_3
#define ADC_CHANNEL3                ADC_Channel_3
//PA4
#define ADC_GPIO_PIN4                GPIO_Pin_4
#define ADC_CHANNEL4                ADC_Channel_4
//PA5
#define ADC_GPIO_PIN5                GPIO_Pin_5
#define ADC_CHANNEL5                ADC_Channel_5
//PA6
#define ADC_GPIO_PIN6                GPIO_Pin_6
#define ADC_CHANNEL6                ADC_Channel_6
//PA7
#define ADC_GPIO_PIN7                GPIO_Pin_7
#define ADC_CHANNEL7                ADC_Channel_7
//PB0
#define ADC_GPIO_PIN8                GPIO_Pin_0
#define ADC_CHANNEL8                ADC_Channel_8
//PB1
#define ADC_GPIO_PIN9                GPIO_Pin_1
#define ADC_CHANNEL9                ADC_Channel_9

void AdcInit(void);

#endif

备注:PA0作为第一个采集的通道,目前遇到的情况是顺序采集到的PA0是缓冲区最后一个数据,所以暂时不使用PA0作为ADC采集io,可以使用其他通道进行采集

0 人点赞