stm32 adc的dma传输案例

dma不多说了,原理啥的网上一大推,源码也有注释,理解起来很容易

案例是传输adc的4个通道,需要多个或者其它的,照着修改就行。

#define ADC1_DR_Address ((u32)0x40012400+0X4C)		//ADC数据的地址

u16  ADC_buf[4];		//DMA传输BUF

void adc_dma_init()
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);

	GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;	//通道引脚
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
	GPIO_Init(GPIOA,&GPIO_InitStructure);

	
	DMA_InitTypeDef DMA_InitStructure;
	ADC_InitTypeDef	ADC_InitStructure;

	DMA_DeInit(DMA1_Channel1);
	
	DMA_InitStructure.DMA_PeripheralBaseAddr=ADC1_DR_Address;	//ADC数据寄存器地址
	DMA_InitStructure.DMA_MemoryBaseAddr=(u32)ADC_buf;	//将ADC1_DR_Address数据转移到ADC_buf
	DMA_InitStructure.DMA_DIR=DMA_DIR_PeripheralSRC; //数据传输方向,外设作为数据源
	DMA_InitStructure.DMA_BufferSize=4; //传输个数据
	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_InitStructure.DMA_Priority=DMA_Priority_High; //DMA通道优先级
	DMA_InitStructure.DMA_M2M=DMA_M2M_Disable; //禁止内存到内存传输
	DMA_Init(DMA1_Channel1,&DMA_InitStructure);
	
	DMA_Cmd(DMA1_Channel1,ENABLE);		//使能
	
	ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //独立模式
	ADC_InitStructure.ADC_ScanConvMode=ENABLE;	//扫描模式,用于多通道采集
	ADC_InitStructure.ADC_ContinuousConvMode=ENABLE; //开启连续转换
	ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;//b不使用外部触发转换
	ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;//采集数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel=4;		//要转换的个数
	ADC_Init(ADC1,&ADC_InitStructure);
	
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);	//6分频,12HZ
	
	//扫描顺序,55.5每个周期
	ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_1,2,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_2,3,ADC_SampleTime_55Cycles5);
	ADC_RegularChannelConfig(ADC1,ADC_Channel_3,4,ADC_SampleTime_55Cycles5);
	
	
	ADC_DMACmd(ADC1,ENABLE);	//向DMA发出请求
	
	ADC_Cmd(ADC1,ENABLE);
	
	ADC_ResetCalibration(ADC1);	//复位矫正寄存器
	
	while(ADC_GetResetCalibrationStatus(ADC1)); //等待矫正完成
	
	ADC_StartCalibration(ADC1);	//ADC矫正

	while(ADC_GetCalibrationStatus(ADC1));	//等待矫正完毕
	
	ADC_SoftwareStartConvCmd(ADC1,ENABLE);	//软件触发ADC转换
	
}


int main(void)
	
{
	
		adc_dma_init();

	
		while(1)
			
		{
			
			
			delay_ms(200);
				
		
		}
		
}

CSDN的代码排版真是越来越差了.....

本来想软件仿真过来看的,但不知道怎么修改IO的电压值,只能用硬件仿真测试了。

测试效果如下:数组里的值会不断刷新,也就是adc引脚的数据直接传输到了数组里面。这样就不会占用cpu资源了。

仿真工程:stm32f103c8t6,我博客的芯片基本都是这款,具体可看工程的芯片设置

https://download.csdn.net/download/hes_c/11044920

猜你喜欢

转载自blog.csdn.net/HES_C/article/details/88708629