ADC不用DMA两通道逐次转换出错

2019-08-14 02:40发布


马上就晚上12点了,找了很久网上查资料也找了很久。没有找到问题所在,不知道哪里配置错了?

两个通道单独测试可以,我想用程序每启动一下换一个通道,但没有结果输出。

希望有谁能指点一下,非常感谢!!!



/************************************/
               通过串口打印输出
/************************************/
while(1)
   {
     ad=0;
       
                 ADC_SoftwareStartConvCmd(ADC1,ENABLE);     //启动
                while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));  //等待完成
                 ad=ADC_GetConversionValue(ADC1);
          
         printf("ad =%f ",3.3/4095*ad);//电压值
          delay_ms(1000);
   }



/************************************/
                    IO配置
/************************************/
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;       

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
        GPIO_Init(GPIOC,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
        GPIO_Init(GPIOC,&GPIO_InitStructure);
       
       
}

/************************************/
                    ADC配置
/************************************/

void ADC_Configuration(void)
{
        ADC_InitTypeDef ADC_InitStructure;

        ADC_InitStructure.ADC_Mode=ADC_Mode_RegSimult;   //工作在同步规则模式
        ADC_InitStructure.ADC_ScanConvMode=ENABLE;        //工作在扫描模式
        ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;  //
        ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;
        ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;
        ADC_InitStructure.ADC_NbrOfChannel=2;

        ADC_Init(ADC1,&ADC_InitStructure);

        ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);
        ADC_RegularChannelConfig(ADC1,ADC_Channel_11,2,ADC_SampleTime_239Cycles5);

        ADC_DiscModeChannelCountConfig(ADC1,1);
        ADC_DiscModeCmd(ADC1,ENABLE);
       
        ADC_Cmd(ADC1,ENABLE);


        ADC_ResetCalibration(ADC1);
        while(ADC_GetResetCalibrationStatus(ADC1));

        ADC_StartCalibration(ADC1);
        while(ADC_GetCalibrationStatus(ADC1));

        ADC_SoftwareStartConvCmd(ADC1,ENABLE);

}


友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
10条回答
主音调
1楼-- · 2019-08-14 04:42

谢谢这两天回我贴的各位。
我在网上看了一下别人的思路,发现是可行的。
用程序直接选择要转换的通道即可。
下面是具体代码。


/***********************************************************
工程名:ADC测试
版  本:
说  明:通过程序选择ADC1 10和11通道转换(非DMA模式)
        此程序只简单实现用软件选择ADC通道进行转换,实际使用
        可不使用两个IF判断,根据实际情况更改
修  改:
***********************************************************/

#include "pbdata.h"

void RCC_Configuration(void);
void GPIO_Configuration(void);
void NVIC_Configuration(void);
void USART_Configuration(void);
void ADC_Configuration(void);

/**********************************************************

功  能:把usart功能改为 printf输出
备  注:  

**********************************************************/
int fputc(int ch,FILE *f)
{
        USART_SendData(USART1,(u8)ch);
        while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET);
        return ch;
}




int main(void)
{
   u32 ad=0;
  

   RCC_Configuration();        //系统时钟初始化
   GPIO_Configuration();//端口初始化
   USART_Configuration();
   NVIC_Configuration();
   ADC_Configuration();
   
        while(1)
        {

                int i=0,k=0;
               
                if (k==0)
                {
                        ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);  //选择通道10转换
                       
                        for(i=0;i<50;i++)
                        {
              ADC_SoftwareStartConvCmd(ADC1,ENABLE);
                          while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
                         
                         ad=ad+ADC_GetConversionValue(ADC1);
                        }
                       
                          ad=ad/50;  
       printf("ad1 =%f ",3.3/4095*ad);//实际电压值
                           k=1;
                          delay_ms(1000);
                }
               
                if (k==1)
                {
                        ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_239Cycles5);  //选择通道11转换
                        for(i=0;i<50;i++)
                        {
              ADC_SoftwareStartConvCmd(ADC1,ENABLE);
                          while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));
                         
                         ad=ad+ADC_GetConversionValue(ADC1);
                        }
                       
                          ad=ad/50;  
       printf("ad2 =%f ",3.3/4095*ad);//实际电压值
                           k=0;
                         delay_ms(1000);
                }
               
        }
}         
         
void RCC_Configuration(void)
{
  SystemInit();//系统时钟72m
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);//ADC频率6分频12M  最大14M

}

/**********************************************************

功  能:串口;ADC引脚配置
备  注:

**********************************************************/
void GPIO_Configuration(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;       

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;             //TX  串口
        GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
        GPIO_Init(GPIOA,&GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;            //RX  串口
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA,&GPIO_InitStructure);

        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;             //ADC通道10
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
        GPIO_Init(GPIOC,&GPIO_InitStructure);
       
        GPIO_InitStructure.GPIO_Pin=GPIO_Pin_1;             //ADC通道11
        GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN;
        GPIO_Init(GPIOC,&GPIO_InitStructure);
       
       
}
/**********************************************************

功  能:串口中断配置
备  注:

**********************************************************/
void NVIC_Configuration(void)
{
           NVIC_InitTypeDef NVIC_InitStructure;

        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);

        NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
        NVIC_Init(&NVIC_InitStructure);
}
/**********************************************************

功  能:串口配置
备  注:  

**********************************************************/
void USART_Configuration(void)
{
    USART_InitTypeDef  USART_InitStructure;

        USART_InitStructure.USART_BaudRate=9600;
        USART_InitStructure.USART_WordLength=USART_WordLength_8b;
        USART_InitStructure.USART_StopBits=USART_StopBits_1;
        USART_InitStructure.USART_Parity=USART_Parity_No;
        USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None;
        USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx;

        USART_Init(USART1,&USART_InitStructure);
        USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
        USART_Cmd(USART1,ENABLE);
        USART_ClearFlag(USART1,USART_FLAG_TC);
}
/**********************************************************

功  能:ADC配置
备  注:  

**********************************************************/
void ADC_Configuration(void)
{
        ADC_InitTypeDef ADC_InitStructure;

        ADC_InitStructure.ADC_Mode=ADC_Mode_Independent;  //ADC1 和 ADC2 工作在独立模式
        ADC_InitStructure.ADC_ScanConvMode=DISABLE;  //单次(单通道)模式
        ADC_InitStructure.ADC_ContinuousConvMode=DISABLE;  //单次模式
        ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None;  //转换由软件而不是外部触发启动
        ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right;  //ADC 数据右对齐
        ADC_InitStructure.ADC_NbrOfChannel=1;  //ADC 通道的数目

        ADC_Init(ADC1,&ADC_InitStructure);  //初始化ADC
        ADC_Cmd(ADC1,ENABLE); //使能ADC

       
        ADC_ResetCalibration(ADC1);  //重置指定的 ADC 的校准寄存器
        while(ADC_GetResetCalibrationStatus(ADC1));

        ADC_StartCalibration(ADC1);  //开始指定 ADC 的校准状态
        while(ADC_GetCalibrationStatus(ADC1));


}

huanghan
2楼-- · 2019-08-14 06:11
开DMA,开缓存,
hasaki
3楼-- · 2019-08-14 11:42
连续转换是不是要开启
主音调
4楼-- · 2019-08-14 13:14
 精彩回答 2  元偷偷看……
wxjhby
5楼-- · 2019-08-14 13:59
主音调 发表于 2017-9-6 08:36
谢谢你的回复,我就是不想用DMA,所以才这样每次程序触发转换。
我想一步步来,DMA我后面在用。

扫描模式应该是必须要DMA的
主音调
6楼-- · 2019-08-14 19:52
hasaki 发表于 2017-9-6 08:36
连续转换是不是要开启

我是这样想的。

如果是连续转换那么我程序只要触发一次ADC就一直工作了。
但我想的是程序触发一次换一个通道ADC转换一次。

一周热门 更多>