不使用DMA及过采样 实际测得电压2.5V,使用万用表测量该值准确,ADC基准电压3.3V.贴上DMA及ADC采样的代码,只测量了一个通道。
uint16_t ADCxValues[1];
uint16_t get_adc(void)
{
SCB_InvalidateDCache_by_Addr((uint32_t *)ADCxValues, sizeof(ADCxValues));
return ADCxValues[0]; //返回最近一次ADC1规则组的转换结果
}
int rt_hw_adc_init(void)
{
DMA_Handle.Instance = DMA1_Stream5; //使用的DMA1 Stream5
DMA_Handle.Init.Request = DMA_REQUEST_ADC1; //请求类型采用DMA_REQUEST_ADC1
DMA_Handle.Init.Direction = DMA_PERIPH_TO_MEMORY; //传输方向是从外设到存储器
DMA_Handle.Init.PeriphInc = DMA_PINC_DISABLE; //外设地址自增禁止
DMA_Handle.Init.MemInc = DMA_MINC_ENABLE; //存储器地址自增使能
DMA_Handle.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD; //外设数据传输位宽选择半字,即16bit
DMA_Handle.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD; //存储器数据传输位宽选择半字,即16bit
DMA_Handle.Init.Mode = DMA_CIRCULAR; //循环模式
DMA_Handle.Init.Priority = DMA_PRIORITY_LOW; //优先级低
DMA_Handle.Init.FIFOMode = DMA_FIFOMODE_DISABLE; //禁止FIFO
DMA_Handle.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL; //禁止FIFO此位不起作用,用于设置阀值
DMA_Handle.Init.MemBurst = DMA_MBURST_SINGLE; //禁止FIFO此位不起作用,用于存储器突发
DMA_Handle.Init.PeriphBurst = DMA_PBURST_SINGLE; //禁止FIFO此位不起作用,用于外设突发
HAL_DMA_Init(&DMA_Handle);
__HAL_LINKDMA(&ADC1_Handler, DMA_Handle, DMA_Handle);
ADC1_Handler.Instance = ADC1;
ADC1_Handler.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV6; //6分频
ADC1_Handler.Init.Resolution = ADC_RESOLUTION_16B; //16位模式
ADC1_Handler.Init.ScanConvMode = ADC_SCAN_DISABLE; //非扫描模式
ADC1_Handler.Init.EOCSelection = ADC_EOC_SINGLE_CONV; //关闭EOC中断
ADC1_Handler.Init.LowPowerAutoWait = DISABLE; //自动低功耗关闭
ADC1_Handler.Init.ContinuousConvMode = ENABLE; //连续转换
ADC1_Handler.Init.NbrOfConversion = 1; //1个转换在规则序列中 也就是只转换规则序列1
ADC1_Handler.Init.DiscontinuousConvMode = DISABLE; //禁止不连续采样模式
ADC1_Handler.Init.NbrOfDiscConversion = 0; //不连续采样通道数为0
ADC1_Handler.Init.ExternalTrigConv = ADC_SOFTWARE_START; //软件触发
ADC1_Handler.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;//使用软件触发
ADC1_Handler.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; //有新的数据的死后直接覆盖掉旧数据
ADC1_Handler.Init.OversamplingMode = ENABLE; //过采样
ADC1_Handler.Init.Oversampling.Ratio = 15; //15+1倍过采样
ADC1_Handler.Init.Oversampling.RightBitShift = ADC_RIGHTBITSHIFT_4; //数据右移4bit
ADC1_Handler.Init.Oversampling.TriggeredMode = ADC_TRIGGEREDMODE_SINGLE_TRIGGER;
ADC1_Handler.Init.Oversampling.OversamplingStopReset = ADC_REGOVERSAMPLING_CONTINUED_MODE;
ADC1_Handler.Init.ConversionDataManagement=ADC_CONVERSIONDATA_DMA_CIRCULAR;//DMA循环模式接收ADC转换的数据
HAL_ADC_Init(&ADC1_Handler); //初始化
HAL_ADCEx_Calibration_Start(&ADC1_Handler,ADC_CALIB_OFFSET,ADC_SINGLE_ENDED); //ADC校准
ADC1_ChanConf.Channel = ADC_CHANNEL_5; //通道
ADC1_ChanConf.Rank = ADC_REGULAR_RANK_1; //1个序列
ADC1_ChanConf.SamplingTime = ADC_SAMPLETIME_810CYCLES_5; //采样时间
ADC1_ChanConf.SingleDiff = ADC_SINGLE_ENDED; //单边采集
ADC1_ChanConf.OffsetNumber = ADC_OFFSET_NONE;
ADC1_ChanConf.Offset = 0;
ADC1_ChanConf.OffsetRightShift = DISABLE;
ADC1_ChanConf.OffsetSignedSaturation = DISABLE;
HAL_ADC_ConfigChannel(&ADC1_Handler,&ADC1_ChanConf); //通道配置
HAL_ADC_Start_DMA(&ADC1_Handler, (uint32_t *)ADCxValues, 1);
return RT_EOK;
}复制代码ad_vol = get_adc()/65536.0*3.3 |