椿湫致简 2023-07-12 19:13 采纳率: 50%
浏览 54
已结题

stm32多路ADC采集

希望采用stm32F1采集6路ADC,用来DMA把数据采集到数组中,但是结果不正确,代码如下:

u16 adc_original_data[6] = {0};


void  Adc_Init(void)
{     
    
    ADC_InitTypeDef ADC_InitStructure; 
    GPIO_InitTypeDef GPIO_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;
    
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE );//使能端口A时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );//使能ADC1通道时钟
    
    //初始化DMA
    DMA_DeInit(DMA1_Channel1);//将DMA的通道1寄存器重设为缺省值
    
    DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)( ADC1_BASE+0x4c);//DMA外设ADC基地址
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)adc_original_data;//DMA内存基地址
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //数据传输方向,从外设读到内存
    DMA_InitStructure.DMA_BufferSize = 6;//总接收发数据长度
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//外设地址寄存器不变
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//数据宽度为16位
    DMA_InitStructure.DMA_MemoryDataSize = DMA_PeripheralDataSize_HalfWord; //数据宽度为16位
    DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;  //工作在循环模式
    DMA_InitStructure.DMA_Priority = DMA_Priority_High;// 当使用一个DMA通道时,优先级设置不影响
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//DMA通道x没有设置为内存到内存传输
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);    
    
    // 使能 DMA 通道
    DMA_Cmd(DMA1_Channel1 , ENABLE);
    
    
    
    //PA1 作为模拟通道输入引脚                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);    
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;
    GPIO_Init(GPIOA, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    
    ADC_DeInit(ADC1);//复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值
    
    RCC_ADCCLKConfig(RCC_PCLK2_Div8);//设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M
    
    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 = 6;//顺序进行规则转换的ADC通道的数目
    ADC_Init(ADC1, &ADC_InitStructure);//根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器
    
    // 配置ADC 通道的转换顺序和采样时间
    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_RegularChannelConfig(ADC1, ADC_Channel_4, 4, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_5, 5, ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_6, 6, ADC_SampleTime_239Cycles5);
    
    
    ADC_Cmd(ADC1, ENABLE);//使能指定的ADC1
    ADC_DMACmd(ADC1, ENABLE);//使能ADC DMA 请求
    
    ADC_ResetCalibration(ADC1);    //使能复位校准  
    while(ADC_GetResetCalibrationStatus(ADC1));    //等待复位校准结束
    
    ADC_StartCalibration(ADC1);     //开启AD校准
    while(ADC_GetCalibrationStatus(ADC1));     //等待校准结束
    
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使用软件触发ADC转换 
}

给一个电位器两端接的3.3V和GND,用万用表测量中间电位0.9V,把通道一接在电位器中间那个脚上
用串口把结果打印在电脑上明显不对

img

这是main里打印的代码:

    while(1)
    {
        for(i=0;i<=5;i++){
            voltage[i] = (float)(adc_original_data[i]*(3.3/4096));
            printf("通道%d的值 = %f \r\n",i+1,voltage[i]);
        }
        printf("\r\n");
        printf("\r\n");
        printf("\r\n");
        delay_ms(10);

麻烦看看代码哪不对,感谢

  • 写回答

3条回答 默认 最新

  • 少林and叔叔 2023-07-12 21:23
    关注

    不用DMA的功能,从ADC的寄存器里读取ADC的值是否正确?

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

问题事件

  • 系统已结题 7月21日
  • 已采纳回答 7月13日
  • 创建了问题 7月12日

悬赏问题

  • ¥15 Stata链式中介效应代码修改
  • ¥15 latex投稿显示click download
  • ¥15 请问读取环境变量文件失败是什么原因?
  • ¥15 在若依框架下实现人脸识别
  • ¥15 添加组件无法加载页面,某块加载卡住
  • ¥15 网络科学导论,网络控制
  • ¥15 利用Sentinel-2和Landsat8做一个水库的长时序NDVI的对比,为什么Snetinel-2计算的结果最小值特别小,而Lansat8就很平均
  • ¥15 metadata提取的PDF元数据,如何转换为一个Excel
  • ¥15 关于arduino编程toCharArray()函数的使用
  • ¥100 vc++混合CEF采用CLR方式编译报错