DMA模式的多路ADC

在做控制无人机(也包括小车)的时候需要用到2.4G无线通信将遥感和按键的值传输过去,需要用到ADC。如果用中断来做的话需要频繁进入中断,按键多的话占用的资源就很多,摇杆加上按键一共有14个了,再加上需要读取电池的电量啊等等需要用到蛮多的数模转换。所以直接搞个DMA来查询ADC岂不美哉?废话不都说,直接贴代码

首先时钟初始化

/* ADCCLK = PCLK2/4 */
	RCC_ADCCLKConfig(RCC_APB2CLK_Div16);
	RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_ADC1, ENABLE);

/* Enable DMA1 clock */
	RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA1, ENABLE);
	RCC_AHBPeriphClockCmd(RCC_AHBPERIPH_DMA2, ENABLE);

然后配置GPIO口

GPIO_InitType GPIO_InitStructure;
//ADC1_IN0  VBAT	PA0
	//ADC1_IN1	S2		PA1
	//ADC1_IN2	S2		PA2
	//ADC1_IN3	S3		PA3
	//ADC1_IN4	S3		PA4
	//ADC1_IN10	S4 S5	PC0
	//ADC1_IN11 S6 S7	PC1
	//ADC1_IN12 S8 S9	PC2
	//ADC1_IN13 S10 S11	PC3
	GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1 | GPIO_Pins_2 | GPIO_Pins_3;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_ANALOG;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOC, &GPIO_InitStructure);
	GPIO_InitStructure.GPIO_Pins = GPIO_Pins_0 | GPIO_Pins_1 | GPIO_Pins_2 |GPIO_Pins_3 |GPIO_Pins_4;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_ANALOG;
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
	//charge PB4 stanby PB5
	GPIO_InitStructure.GPIO_MaxSpeed = GPIO_MaxSpeed_2MHz;
	GPIO_InitStructure.GPIO_Pins = GPIO_Pins_4 | GPIO_Pins_5;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOB, &GPIO_InitStructure);

最后配置好DMA和ADC

    ADC_InitType ADC_InitStructure;
	DMA_InitType DMA_InitStructure;

	/* DMA1 Channel1 Configuration ----------------------------------------------*/
	DMA_Reset(DMA1_Channel1);
	DMA_DefaultInitParaConfig(&DMA_InitStructure);
	DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->RDOR;
	// DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1->RDOR;
	DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)adc_raw_buffer;
	DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALSRC;
	DMA_InitStructure.DMA_BufferSize = DMA1_CH1_ADC1_BUFFER_SIZE;
	DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
	DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
	DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_HALFWORD;
	DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_HALFWORD;
	DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR;
	DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH;
	DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;
	DMA_Init(DMA1_Channel1, &DMA_InitStructure);

	/* Enable DMA1 channel1 */
	DMA_ChannelEnable(DMA1_Channel1, ENABLE);

	/* ADC1 Configuration ------------------------------------------------------*/
	ADC_StructInit(&ADC_InitStructure);
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
	ADC_InitStructure.ADC_ScanMode = ENABLE;
	ADC_InitStructure.ADC_ContinuousMode = ENABLE;
	ADC_InitStructure.ADC_ExternalTrig = ADC_ExternalTrig_None;
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
	ADC_InitStructure.ADC_NumOfChannel = adc_count;
	ADC_Init(ADC1, &ADC_InitStructure);

	ADC_ExternalTrigConvCtrl(ADC1, ENABLE);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239_5);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239_5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239_5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_239_5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_4, 5, ADC_SampleTime_239_5);

	ADC_RegularChannelConfig(ADC1, ADC_Channel_10, 6, ADC_SampleTime_239_5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 7, ADC_SampleTime_239_5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 8, ADC_SampleTime_239_5);
	ADC_RegularChannelConfig(ADC1, ADC_Channel_13, 9, ADC_SampleTime_239_5);
	
	ADC_RegularChannelConfig(ADC1, ADC_Channel_Vrefint, 10, ADC_SampleTime_239_5);

	/*Enable internal temp vref convert channel*/
	ADC_TempSensorVrefintCtrl(ENABLE);

	/* Enable ADC1 DMA */
	ADC_DMACtrl(ADC1, ENABLE);

	/* Enable JEOC interrupt */
	// ADC_INTConfig(ADC1, ADC_INT_EC, ENABLE);
	DMA_INTConfig(DMA1_Channel1, DMA_INT_TC, ENABLE);

	/* Enable ADC1 */
	ADC_Ctrl(ADC1, ENABLE);

	/* Enable ADC1 reset calibration register */
	ADC_RstCalibration(ADC1);
	/* Check the end of ADC1 reset calibration register */
	// while (ADC_GetResetCalibrationStatus(ADC1))
		;

	// /* Start ADC1 calibration */
	ADC_StartCalibration(ADC1);
	/* Check the end of ADC1 calibration */
	// while (ADC_GetCalibrationStatus(ADC1))
		;

	/* Test on channel1 transfer complete flag */
	// while (!DMA_GetFlagStatus(DMA1_FLAG_TC1));
	// /* Clear channel1 transfer complete flag */
	// DMA_ClearFlag(DMA1_FLAG_TC1);

	/* Start ADC1 Software Conversion */
	ADC_SoftwareStartConvCtrl(ADC1, ENABLE);

然后直接去adc_raw_buffer里面读取需要的值就可以了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值