OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 2274|回复: 10

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

[复制链接]

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
453
金钱
453
注册时间
2016-8-8
在线时间
101 小时
发表于 2017-9-6 00:05:32 | 显示全部楼层 |阅读模式
1金钱

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

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

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



/************************************/
               通过串口打印输出
/************************************/
while(1)
   {
     ad=0;
       
                 ADC_SoftwareStartConvCmd(ADC1,ENABLE);     //启动
                while(!ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC));  //等待完成
                 ad=ADC_GetConversionValue(ADC1);
          
         printf("ad =%f\r\n",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);

}


最佳答案

查看完整内容[请看2#楼]

谢谢这两天回我贴的各位。 我在网上看了一下别人的思路,发现是可行的。 用程序直接选择要转换的通道即可。 下面是具体代码。 /*********************************************************** 工程名:ADC测试 版 本: 说 明:通过程序选择ADC1 10和11通道转换(非DMA模式) 此程序只简单实现用软件选择ADC通道进行转换,实际使用 可不使用两个IF判断,根据实际情况更改 修 改: ************ ...
如何拿下蒙住眼的树叶。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
453
金钱
453
注册时间
2016-8-8
在线时间
101 小时
 楼主| 发表于 2017-9-6 00:05:33 | 显示全部楼层

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


/***********************************************************
工程名: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\r\n",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\r\n",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));


}

如何拿下蒙住眼的树叶。
回复

使用道具 举报

10

主题

266

帖子

0

精华

高级会员

Rank: 4

积分
693
金钱
693
注册时间
2017-7-27
在线时间
98 小时
发表于 2017-9-6 08:15:59 | 显示全部楼层
开DMA,开缓存,
回复

使用道具 举报

5

主题

69

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
307
金钱
307
注册时间
2016-10-20
在线时间
64 小时
发表于 2017-9-6 08:36:20 | 显示全部楼层
连续转换是不是要开启
回复

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
453
金钱
453
注册时间
2016-8-8
在线时间
101 小时
 楼主| 发表于 2017-9-6 08:36:56 | 显示全部楼层

谢谢你的回复,我就是不想用DMA,所以才这样每次程序触发转换。
我想一步步来,DMA我后面在用。
如何拿下蒙住眼的树叶。
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-9-6 09:14:13 | 显示全部楼层
主音调 发表于 2017-9-6 08:36
谢谢你的回复,我就是不想用DMA,所以才这样每次程序触发转换。
我想一步步来,DMA我后面在用。

扫描模式应该是必须要DMA的
回复

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
453
金钱
453
注册时间
2016-8-8
在线时间
101 小时
 楼主| 发表于 2017-9-6 09:22:51 | 显示全部楼层
hasaki 发表于 2017-9-6 08:36
连续转换是不是要开启

我是这样想的。

如果是连续转换那么我程序只要触发一次ADC就一直工作了。
但我想的是程序触发一次换一个通道ADC转换一次。
如何拿下蒙住眼的树叶。
回复

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
453
金钱
453
注册时间
2016-8-8
在线时间
101 小时
 楼主| 发表于 2017-9-6 09:25:48 | 显示全部楼层
wxjhby 发表于 2017-9-6 09:14
扫描模式应该是必须要DMA的

这个问题真的没搞明白,请教一下!
如果不用扫描模式,ADC通道如何跳转到下一个通道。
比如1通道ADC转换完后跳的2通道给ADC转换。
如何拿下蒙住眼的树叶。
回复

使用道具 举报

5

主题

69

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
307
金钱
307
注册时间
2016-10-20
在线时间
64 小时
发表于 2017-9-6 09:34:55 | 显示全部楼层
ADC_InitStructure.ADC_ContinuousConvMode=ENABLE;  //  你改成这个试一下
回复

使用道具 举报

4

主题

349

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1046
金钱
1046
注册时间
2017-5-19
在线时间
335 小时
发表于 2017-9-6 16:29:10 | 显示全部楼层
规则组
此模式通过设置ADC_CR1寄存器上的DISCEN位激活。它可以用来执行一个短序列的n次转换
(n<=8),此转换是ADC_SQRx寄存器所选择的转换序列的一部分。数值n由ADC_CR1寄存器的
DISCNUM[2:0]位给出。
一个外部触发信号可以启动ADC_SQRx寄存器中描述的下一轮n次转换,直到此序列所有的转
换完成为止。总的序列长度由ADC_SQR1寄存器的L[3:0]定义。
举例:
n=3,被转换的通道 = 0、 1、 2、 3、 6、 7、 9、 10
第一次触发:转换的序列为 0、 1、 2
第二次触发:转换的序列为 3、 6、 7
第三次触发:转换的序列为 9、 10,并产生EOC事件
第四次触发:转换的序列 0、 1、 2
注意: 当以间断模式转换一个规则组时,转换序列结束后不自动从头开始。
当所有子组被转换完成,下一次触发启动第一个子组的转换。在上面的例子中,第四次触发重
新转换第一子组的通道 0、 1和2。


所以改成这样,然后每次等EOC 试试
ADC_InitStructure.ADC_NbrOfChannel=1;
回复

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
453
金钱
453
注册时间
2016-8-8
在线时间
101 小时
 楼主| 发表于 2017-9-7 21:54:23 | 显示全部楼层
wxjhby 发表于 2017-9-6 16:29
规则组
此模式通过设置ADC_CR1寄存器上的DISCEN位激活。它可以用来执行一个短序列的n次转换
(n

谢谢你的回帖
我在网上看了一下别人的方法,
通过程序直接选择通道转换
时可行的。
如何拿下蒙住眼的树叶。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-19 03:36

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表