两个adc同步采样,传输到DMA,但存在一个问题,DMA存至数组不能进行快排,故将该数组内值赋给新数组并进行计算【 更新】可以直接对dma存至的数组进行快排

目录

 初始方式

更新后


 初始方式

思路为用同一个tim触发adc进行采样

, 

normal就是DMA只转存一次,一个数组,这样的好处是配置简单

circular就是DMA不断转运,后面最好加上中断,关掉tim,不然给新数组赋值也会出现问题

要保证先开启DMA,再开启ADC,也可以直接在上图中调整RANK 

/* USER CODE BEGIN PD */
#define length 1024
#define ADC1_BUFFER_SIZE 1024
#define ADC2_BUFFER_SIZE 1024
/* USER CODE END PD */

ALIGN_32BYTES (uint16_t adc1_data[ADC1_BUFFER_SIZE]) __attribute__((section(".ARM.__at_0x24000000")));
ALIGN_32BYTES (uint16_t adc2_data[ADC2_BUFFER_SIZE]) __attribute__((section(".ARM.__at_0x38000000")));
 /* USER CODE BEGIN 2 */


  MX_ADC1_Init();	//��濮���璋��ㄦ�捐���?, 纭�淇���MX_DMA_Init()��濮�����,����浼��������烘��
  MX_ADC2_Init();	//��濮���璋��ㄦ�捐���?, 纭�淇���MX_DMA_Init()��濮�����

  HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) ; // AD��?���锛�f4涓���锟�??
  HAL_ADCEx_Calibration_Start(&hadc2, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) ;

  HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1_data, ADC1_BUFFER_SIZE);
  HAL_ADC_Start_DMA(&hadc2, (uint32_t *)adc2_data, ADC2_BUFFER_SIZE);

  HAL_TIM_Base_Start(&htim8);//锟�??瀹�瑕���ADC锟�??�����ㄥ���瑙�锟�???

问题在于adc1_data数组是16位的数组,但是由于HAL库函数的设置,转存的需要是32位的数组,故进行了强转与ALIGN_32BYTE的操作

更新后

 只要把这里改为word,那么这个数组就统一当作32位来操作。故可以进行地址的操作(如快排等)。

 HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET, ADC_SINGLE_ENDED) ; 
 HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adc1_data, ADC1_BUFFER_SIZE);
 HAL_TIM_Base_Start(&htim8);
 delay_ms(20);
//在快排前要停止dma的转运
  HAL_ADC_Stop_DMA(&hadc1);
QuickSort(adc1_data, 0,  ADC1_BUFFER_SIZE-1);

好的,以下是一个简单的使用 DMA 搬运 STM32 多通道 ADC 采样数组的程序示例: ```c #include "stm32f4xx.h" #define ADC_CHANNELS 4 #define ADC_BUFFER_SIZE (ADC_CHANNELS * 100) uint16_t adc_buffer[ADC_BUFFER_SIZE]; void initialize_adc(void); void initialize_dma(void); int main(void) { initialize_adc(); initialize_dma(); while(1) { // Do something with the ADC buffer } } void initialize_adc(void) { ADC_InitTypeDef ADC_InitStructure; ADC_CommonInitTypeDef ADC_CommonInitStructure; GPIO_InitTypeDef GPIO_InitStructure; // Enable the ADC clock RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // Enable the GPIO clock RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // Configure the ADC pins as analog inputs GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); // Configure the ADC ADC_CommonInitStructure.ADC_Mode = ADC_Mode_Independent; ADC_CommonInitStructure.ADC_Prescaler = ADC_Prescaler_Div2; ADC_CommonInitStructure.ADC_DMAAccessMode = ADC_DMAAccessMode_Disabled; ADC_CommonInitStructure.ADC_TwoSamplingDelay = ADC_TwoSamplingDelay_5Cycles; ADC_CommonInit(&ADC_CommonInitStructure); ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = ENABLE; ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = ADC_CHANNELS; ADC_Init(ADC1, &ADC_InitStructure); // Enable the ADC DMA request ADC_DMARequestAfterLastTransferCmd(ADC1, ENABLE); // Enable the ADC ADC_Cmd(ADC1, ENABLE); // Wait for the ADC to be ready while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_RDY)); } void initialize_dma(void) { DMA_InitTypeDef DMA_InitStructure; // Enable the DMA2 clock RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_DMA2, ENABLE); // Configure the DMA DMA_InitStructure.DMA_Channel = DMA_Channel_0; DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&ADC1->DR; DMA_InitStructure.DMA_Memory0BaseAddr = (uint32_t)adc_buffer; DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralToMemory; DMA_InitStructure.DMA_BufferSize = ADC_BUFFER_SIZE; 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_InitStructure.DMA_FIFOMode = DMA_FIFOMode_Disable; DMA_InitStructure.DMA_FIFOThreshold = DMA_FIFOThreshold_HalfFull; DMA_InitStructure.DMA_MemoryBurst = DMA_MemoryBurst_Single; DMA_InitStructure.DMA_PeripheralBurst = DMA_PeripheralBurst_Single; DMA_Init(DMA2_Stream0, &DMA_InitStructure); // Enable the DMA transfer complete interrupt DMA_ITConfig(DMA2_Stream0, DMA_IT_TC, ENABLE); // Enable the DMA stream DMA_Cmd(DMA2_Stream0, ENABLE); } ``` 该程序使用了 DMA2 的第 0 个流来搬运 ADC 数据,存储在 `adc_buffer` 数组中。在 `initialize_adc` 函数中,配置了 ADC 的通道数、分辨率、扫描模式等参数,并在最后启用了 ADCDMA 请求。在 `initialize_dma` 函数中,配置了 DMA2 的第 0 个流用于从 ADC 读取数据,并将数据存储到 `adc_buffer` 数组中。 请注意,实际使用时,需要根据自己的需要修改 ADCDMA 的配置参数。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值