|

楼主 |
发表于 2022-1-17 14:38:06
|
显示全部楼层
这是我adc dma配置的代码,如果不适用emwin 单独跑是可行的 也可以随意调节dmabuffersize的大小
void ADC1_Init(void)
{
ADC_ChannelConfTypeDef ADC1_Channel_Handler; //ADC2通道配置句柄
ADC_MultiModeTypeDef MultiMode_Handler; //双重模式句柄
//ADC1初始化
ADC1_Handler.Instance=ADC1;
HAL_ADC_DeInit(&ADC1_Handler);
ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_ASYNC_DIV2; //2分频,ADCCLK=PER_CK/2=64/2=32MHZ 异步时钟 可校准
// ADC1_Handler.Init.ClockPrescaler=ADC_CLOCK_SYNC_PCLK_DIV2; //同步时钟 不能打开ADC2的校准
ADC1_Handler.Init.Resolution=ADC_RESOLUTION_16B; //16位模式
ADC1_Handler.Init.ScanConvMode=ENABLE; //扫描模式
ADC1_Handler.Init.EOCSelection=ADC_EOC_SINGLE_CONV; //EOC全部转换完成进入中断
ADC1_Handler.Init.LowPowerAutoWait=DISABLE; //自动低功耗关闭
ADC1_Handler.Init.ContinuousConvMode=DISABLE; //关闭连续转换
ADC1_Handler.Init.NbrOfConversion=2; //3个转换在规则序列中
ADC1_Handler.Init.DiscontinuousConvMode=DISABLE; //禁止不连续采样模式
ADC1_Handler.Init.NbrOfDiscConversion=0; //不连续采样通道数为0
ADC1_Handler.Init.ExternalTrigConv=ADC_EXTERNALTRIG_T3_TRGO; //定时器触发 TIME3-CH4
ADC1_Handler.Init.ExternalTrigConvEdge=ADC_EXTERNALTRIGCONVEDGE_RISING; //外部上升沿触发
ADC1_Handler.Init.BoostMode=ENABLE; //BOOT模式使能 时钟高于20MHz时 必须使能此位
ADC1_Handler.Init.Overrun=ADC_OVR_DATA_OVERWRITTEN; //有新的数据的后直接覆盖掉旧数据
ADC1_Handler.Init.OversamplingMode=DISABLE; //过采样关闭
ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR; //DMA循环接受数据
HAL_ADC_Init(&ADC1_Handler); //初始化
//ADC1-Channel-16
ADC1_Channel_Handler.Channel=16; //通道 PA0
ADC1_Channel_Handler.Rank=ADC_REGULAR_RANK_1; //序列1
ADC1_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5; //采样周期
ADC1_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED; //单边采集
ADC1_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;
ADC1_Channel_Handler.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_Channel_Handler); //通道配置
//ADC1-Channel-19
ADC1_Channel_Handler.Channel=19; //通道 PA5
ADC1_Channel_Handler.Rank=ADC_REGULAR_RANK_2; //序列2
ADC1_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5; //采样周期
ADC1_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED; //单边采集
ADC1_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;
ADC1_Channel_Handler.Offset=0;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_Channel_Handler); //通道配置
// //ADC1-Channel-3
// ADC1_Channel_Handler.Channel=3; //通道 PA6
// ADC1_Channel_Handler.Rank=ADC_REGULAR_RANK_3; //序列3
// ADC1_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5; //采样周期
// ADC1_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED; //单边采集
// ADC1_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;
// ADC1_Channel_Handler.Offset=0;
// HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_Channel_Handler); //通道配置
HAL_ADCEx_Calibration_Start(&ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校准
//设置ADC双重模式
MultiMode_Handler.Mode = ADC_DUALMODE_REGSIMULT;
MultiMode_Handler.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
MultiMode_Handler.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_1CYCLE;
HAL_ADCEx_MultiModeConfigChannel(&ADC1_Handler,&MultiMode_Handler);
}
void ADC2_Init(void)
{
ADC_ChannelConfTypeDef ADC2_Channel_Handler; //ADC2通道配置句柄
//ADC2初始化
ADC2_Handler.Instance=ADC2;
ADC2_Handler.Init = ADC1_Handler.Init;
ADC2_Handler.Init.ExternalTrigConv=ADC_SOFTWARE_START; //双重模式的副ADC软件触发
HAL_ADC_Init(&ADC2_Handler); //初始化
//ADC2-Channel-7
ADC2_Channel_Handler.Channel=7; //通道 PA7
ADC2_Channel_Handler.Rank=ADC_REGULAR_RANK_1; //序列1
ADC2_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5; //采样周期
ADC2_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED; //单边采集
ADC2_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;
ADC2_Channel_Handler.Offset=0;
HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_Channel_Handler); //通道配置
//ADC2-Channel-4
ADC2_Channel_Handler.Channel=4; //通道 PC4
ADC2_Channel_Handler.Rank=ADC_REGULAR_RANK_2; //序列2
ADC2_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5; //采样周期
ADC2_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED; //单边采集
ADC2_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;
ADC2_Channel_Handler.Offset=0;
HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_Channel_Handler); //通道配置
//ADC2-Channel-8
// ADC2_Channel_Handler.Channel=8; //通道 PC5
// ADC2_Channel_Handler.Rank=ADC_REGULAR_RANK_3; //序列3
// ADC2_Channel_Handler.SamplingTime=ADC_SAMPLETIME_2CYCLES_5; //采样周期
// ADC2_Channel_Handler.SingleDiff=ADC_SINGLE_ENDED; //单边采集
// ADC2_Channel_Handler.OffsetNumber=ADC_OFFSET_NONE;
// ADC2_Channel_Handler.Offset=0;
// HAL_ADC_ConfigChannel(&ADC2_Handler,&ADC2_Channel_Handler); //通道配置
HAL_ADCEx_Calibration_Start(&ADC2_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校准
}
//ADC底层驱动 引脚配置、时钟使能
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_Initure; //GPIO句柄
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_ADC;
PeriphClkInitStruct.PLL2.PLL2M = 25;
PeriphClkInitStruct.PLL2.PLL2N = 504;
PeriphClkInitStruct.PLL2.PLL2P = 7;
PeriphClkInitStruct.PLL2.PLL2Q = 7;
PeriphClkInitStruct.PLL2.PLL2R = 7;
PeriphClkInitStruct.PLL2.PLL2RGE = RCC_PLL2VCIRANGE_0;
PeriphClkInitStruct.PLL2.PLL2VCOSEL = RCC_PLL2VCOWIDE;
PeriphClkInitStruct.PLL2.PLL2FRACN = 0;
PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLL2;
HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_PLL2);
__HAL_RCC_ADC12_CLK_ENABLE(); //使能ADC1/2时钟
__HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟
__HAL_RCC_GPIOC_CLK_ENABLE(); //开启GPIOC时钟
//__HAL_RCC_ADC_CONFIG(RCC_ADCCLKSOURCE_CLKP); //ADC外设时钟选择
// GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7; //PA
GPIO_Initure.Pin=GPIO_PIN_0|GPIO_PIN_5|GPIO_PIN_7; //PA
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOA,&GPIO_Initure);
// GPIO_Initure.Pin=GPIO_PIN_4|GPIO_PIN_5; //PC
GPIO_Initure.Pin=GPIO_PIN_4; //PC
GPIO_Initure.Mode=GPIO_MODE_ANALOG; //模拟
GPIO_Initure.Pull=GPIO_NOPULL; //不带上下拉
HAL_GPIO_Init(GPIOC,&GPIO_Initure);
}
void ADC_Init(void)
{
ADC1_Init();
ADC2_Init();
// HAL_ADCEx_MultiModeStart_DMA(&ADC1_Handler,(uint32_t *)ADC_DMA_Buf,2);
}
void DMA1_Stream0_Init(void)
{
__HAL_RCC_DMA1_CLK_ENABLE(); //DMA1时钟使能
//DMA1-Stream0
DMA1_Stream0_Handler.Instance=DMA1_Stream0; //数据流选择
DMA1_Stream0_Handler.Init.Request=DMA_REQUEST_ADC1; //ADC
DMA1_Stream0_Handler.Init.Direction=DMA_PERIPH_TO_MEMORY; //外设到储存器
DMA1_Stream0_Handler.Init.PeriphInc=DMA_PINC_DISABLE; //外设非增量模式
DMA1_Stream0_Handler.Init.MemInc=DMA_MINC_ENABLE; //存储器增量模式
DMA1_Stream0_Handler.Init.PeriphDataAlignment=DMA_PDATAALIGN_WORD; //外设数据长度:16位
DMA1_Stream0_Handler.Init.MemDataAlignment=DMA_PDATAALIGN_WORD; //存储器数据长度:16位
DMA1_Stream0_Handler.Init.Mode=DMA_CIRCULAR; //循环接受模式
DMA1_Stream0_Handler.Init.Priority=DMA_PRIORITY_HIGH; //高等优先级
DMA1_Stream0_Handler.Init.FIFOMode=DMA_FIFOMODE_DISABLE;
DMA1_Stream0_Handler.Init.FIFOThreshold=DMA_FIFO_THRESHOLD_FULL;
DMA1_Stream0_Handler.Init.MemBurst=DMA_MBURST_SINGLE; //存储器突发单次传输
DMA1_Stream0_Handler.Init.PeriphBurst=DMA_PBURST_SINGLE; //外设突发单次传输
//初始化
HAL_DMA_DeInit(&DMA1_Stream0_Handler);
HAL_DMA_Init(&DMA1_Stream0_Handler);
// HAL_DMA_Start (&DMA1_Stream0_Handler,RHEOSTAT_ADC1_DR_ADDR,(uint32_t)&ADC_DMA_Buf,2); //开启单缓冲
__HAL_LINKDMA(&ADC1_Handler,DMA_Handle,DMA1_Stream0_Handler); //将DMA与ADC1联系起来(发送DMA)
// __HAL_DMA_ENABLE_IT(&DMA1_Stream0_Handler,DMA_IT_TC); //传输完成中断
//开启中断 设置优先级
HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 1, 1);
HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
}
void DMA_Init(void)
{
DMA1_Stream0_Init();
}
void DMA1_Stream0_IRQHandler(void)
{
static int count=0;
int i;
SCB_InvalidateDCache(); //使 D-cache 无效,即CPU读取数据时,忽略 D-cache 中的内容,去真实的物理地址读取对应的数据(DMA-SRAM)。
if( __HAL_DMA_GET_FLAG(&DMA1_Stream0_Handler,DMA_FLAG_TCIF0_4)!=RESET)
{
// HAL_TIM_PWM_Stop(&TIM3_Handler,TIM_CHANNEL_4);
Acceleration_Buf[1] = ADC_DMA_Buf[0];
Acceleration_Buf[0] = ADC_DMA_Buf[0] >> 16;
Acceleration[0] = (float)Acceleration_Buf[0] * 3300 / 65536;
Acceleration[1] = (float)Acceleration_Buf[1] * 3300 / 65536;
oscilldev.buffer[count]=(int)Acceleration[1];
count++;
if(count==oscilldev.dataxsize)//一次数据采集完成
{
count=0;
oscilldev.adflag=1;//标记AD采集完成标志
}
__HAL_DMA_CLEAR_FLAG(&DMA1_Stream0_Handler,DMA_FLAG_TCIF0_4);
}
} |
|