stm32 多路采样求助
需要采集四个电压信号,参考了别人的程序,采用了ADC1+DMA的方式,但出来的数据都是0。贴一下我的程序。
采样口是PA0,PA1,PA2,PA3。 本帖最后由 a981223559 于 2019-5-14 20:45 编辑
ADC_SoftwareStartConvCmd(ADC1, ENABLE)这个函数写在初始化最后,DMA初始化在校准前 a981223559 发表于 2019-5-14 20:42
ADC_SoftwareStartConvCmd(ADC1, ENABLE)这个函数写在初始化最后,DMA初始化在校准前
您好。目前只有PA0口有数据显示(我还没有把AD值转换为电压值,所以数据有点大)。目前这四个AD口都是悬空的,应该有1V左右电压,所以不可能都是0的。这是什么原因呢? voidADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE ); //使能ADC1通道时钟
RCC_ADCCLKConfig(RCC_PCLK2_Div6); //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);
ADC_DMA_Configuration();
ADC_DeInit(ADC1); //复位ADC1
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //扫描模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //连续转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 3; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure);
// 设置指定的规则组通道和转换顺序
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 2, ADC_SampleTime_239Cycles5);
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 3, ADC_SampleTime_239Cycles5);
// 开启ADC的DMA
ADC_DMACmd(ADC1, ENABLE);
ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1
ADC_ResetCalibration(ADC1); //使能复位校准
while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位校准结束
ADC_StartCalibration(ADC1); //开启AD校准
while(ADC_GetCalibrationStatus(ADC1)); //等待校准结束
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
/* Clear Channel 1 DMA1_FLAG_TC flag */
DMA_ClearFlag(DMA1_FLAG_TC1);
}
void ADC_DMA_Configuration(void)
{
/* ADC1DMA1 Channel Config */
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE); //使能DMA时钟
DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值:ADC1连接DMA通道1
DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&ADC1->DR; //DMA外设ADC基地址
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue; //DMA内存基地址
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //内存作为数据传输的目的地
DMA_InitStructure.DMA_BufferSize = 768; //此值为完整一轮DMA传输的次数,3通道每通道采集50次
DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //内存地址递增
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; //外设数据位宽度16位,即DMA传输尺寸
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //数据宽度16位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; //工作在循环缓存模式,一轮结束后自动开始下轮传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道 x拥有高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; //DMA通道x禁止内存到内存
DMA_Init(DMA1_Channel1, &DMA_InitStructure); //根据DMA_InitStruct中参数DMA通道
DMA_Cmd(DMA1_Channel1, ENABLE);
}
zzzzzzydb7b11 发表于 2019-5-14 20:52
您好。目前只有PA0口有数据显示(我还没有把AD值转换为电压值,所以数据有点大)。目前这四个AD口都是悬 ...
直接参考我的程序吧,已经测试过没问题的 本帖最后由 wenyangzeng 于 2019-5-14 21:39 编辑
1、楼主既然配置了DMA,就应该等待DMA传输结束标志位,才去读取数据而非等待ADC转换结束。
2、既然ADC配置了连续采样模式,启动一次就够了,不应该一直启动ADC采样转换。
a981223559 发表于 2019-5-14 20:59
voidADC1_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
DMA_InitStructure.DMA_BufferSize = 768;
这个数据是怎么计算出来的呢?如果是4个通道,计算式子是什么呢?
按照您给的程序试了一次,四路都有示数,但我把每个引脚下拉后,示数并未回到0,应该还有一些问题。
十分感谢您的帮助! wenyangzeng 发表于 2019-5-14 21:35
1、楼主既然配置了DMA,就应该等待DMA传输结束标志位,才去读取数据而非等待ADC转换结束。
2、既然ADC配置 ...
您好:1.主函数部分我已经把ADC转换标志位去除了。改成:
while(1)
{
while(1)
{
ad1=0;ad2=0;ad3=0;ad4=0;
for(i=0;i<10;i++)
{
ad1+=adc_data;
ad2+=adc_data;
ad3+=adc_data;
ad4+=adc_data;
}
同时,在dma_init()加入了
while(!DMA_GetFlagStatus(DMA1_FLAG_TC1));
DMA_ClearFlag(DMA1_FLAG_TC1);
2.那个不知道怎么写重复了,已经删除了。
感谢您看我的程序。我有一个问题想问您,有的程序里写的是ad+=adc_data或者ad+=ADC_ConvertedValue。adc_data和ADC_ConvertedValue 代表的是通道0里的数据吗,为什么一个u16 adc_data或者u16 ADC_ConvertedValue就可以把DMA的数值存在这个数组里了呢,是在哪个函数里定义了么? 原来的程序中有一处错误:DMA_InitStructure.DMA_MemoryInc=DMA_PeripheralInc_Enable;将此语句应改为
DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;
此时都能读到数据,但不正确,情况和5楼的程序效果一样。显示的都为波动数字(1-900多变化),四个都是。即使下拉PA0,PA1,PA2,PA3四个采样口,显示依然波动。还在调试中。
页:
[1]
2