STM32-ADC voltage acquisition Multichannel

Detailed ADC

Previous blog detailed in the relevant information STM32 in the ADC, this blog is a summary of the contents of the ADC upgrade, detailing the ADC: ADC Detailed

Program Description

To make the code easier to read this, bloggersNo macro variables defined in the header fileIt is directly sampling a predetermined parameter in the function library. TheVoltage multi-channel acquisition, channel ADC1 using a total of six channels 10,11,12,13,14,15,useConverting the results transmitted to the DMA memory

Function body

Pin Configuration

Pin allocation of time, the one-time configuration pins all good, too simple, not elaborate.

void ADC_GPIO_Config(void)
{
	GPIO_InitTypeDef   GPIO_InitStruct;
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,  ENABLE);
	
	
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AIN ;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_0|
								GPIO_Pin_1|
								GPIO_Pin_2|
								GPIO_Pin_3|
								GPIO_Pin_4|
								GPIO_Pin_5;
	
	GPIO_Init(GPIOC , &GPIO_InitStruct);
}

ADC and DMA configuration

This function is mainly ADC configuration information related information and DMA.

uint16_t result[6]={0,0,0,0,0,0};

void ADC_DMA_COnfig(void)
{
	ADC_InitTypeDef  ADC_InitStructure;
	DMA_InitTypeDef DMA_InitStructure;
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,  ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
	
	/* 复位DMA1的通道1 */
	DMA_DeInit(DMA1_Channel1);
	
	// 配置 DMA 初始化结构体
	// 外设基址为:ADC 数据寄存器地址
	DMA_InitStructure.DMA_PeripheralBaseAddr = ( u32 ) ( ADC1_BASE+0x4c);
	
	// 存储器地址
	DMA_InitStructure.DMA_MemoryBaseAddr = (u32)result;
	
	// 数据源来自外设
	DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
	
	// 缓冲区大小,应该等于数据目的地的大小
	DMA_InitStructure.DMA_BufferSize = 6;
	
	// 外设寄存器只有一个,地址不用递增
	DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

	// 存储器地址递增
	DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
	
	// 外设数据大小为半字,即两个字节
	DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
	
	// 内存数据大小也为半字,跟外设数据大小相同
	DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
	
	// 循环传输模式
	DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;	

	// DMA 传输通道优先级为高,当使用一个DMA通道时,优先级设置不影响
	DMA_InitStructure.DMA_Priority = DMA_Priority_High;
	
	// 禁止存储器到存储器模式,因为是从外设到存储器
	DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
	
	// 初始化DMA
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);
	
	// 使能 DMA 通道
	DMA_Cmd(DMA1_Channel1 , ENABLE);
	
	
	// ADC 模式配置
	// 只使用一个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 = 6;	
		
	// 初始化ADC
	ADC_Init(ADC1, &ADC_InitStructure);
	
	// 配置ADC时钟为PCLK2的8分频,即9MHz
	RCC_ADCCLKConfig(RCC_PCLK2_Div8); 
	
	// 配置ADC 通道的转换顺序和采样时间
	ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 1, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 2, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 3, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 4, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_14, 5, ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_15, 6, ADC_SampleTime_55Cycles5);
	
	// 使能ADC DMA 请求
	ADC_DMACmd(ADC1, ENABLE);
	
	// 开启ADC ,并开始转换
	ADC_Cmd(ADC1, ENABLE);
	
	// 初始化ADC 校准寄存器  
	ADC_ResetCalibration(ADC1);
	// 等待校准寄存器初始化完成
	while(ADC_GetResetCalibrationStatus(ADC1));
	
	// ADC开始校准
	ADC_StartCalibration(ADC1);
	// 等待校准完成
	while(ADC_GetCalibrationStatus(ADC1));
	
	// 由于没有采用外部触发,所以使用软件触发ADC转换 
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);

It defines the beginning of the function and structure variable ADC DMA and opens both a peripheral clock (DMA mount the AHB bus). The DMA module may be written before the reference blog: DMA
The DMA transfer from memory to peripheral, takes data directly from the data from the ADC register and then transferred to the global array variable result. The remaining notes are detailed in the function.

The main function

#include "stm32f10x.h"
#include "usart.h"
#include "adc.h"



extern uint16_t result[6];
float voltage[6];


void delay(void)
{
	uint32_t k=0xffffff;
	while(k--);
}

int main(void)
{
	uint8_t n;
	/* 配置串口 */
	DEBUG_USART_Config();
	/* 有关ADC的函数打包 */
	ADCx_Init();
	while(1)
	{
		for(n=0;n<6;n++)
		{
		    /* 转换为实际电压 */
			voltage[n]=(float) result[n]/4096*3.3;
			printf("\n通道%d的值为:%fV\n",n,voltage[n]);
		}
		delay();
	}
}

The main function also has a corresponding annotation.

Published 62 original articles · won praise 188 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_43743762/article/details/100085192