打印
[STM32]

求助!STM32F103的ADC+DMA采样得到的数据都是0,求大神

[复制链接]
2223|7
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
部分电路结构图如下:

使用了NX3L4051模块对ADC采样通道进行选择,所以程序里也有体现。

目前就是读数一直是0,感觉自己的配置什么的也好像没有问题,检查了好多遍。

但是还是有疑问,我的程序好像没有判断什么时候DMA可以开始传输数据以及ADC什么时候采样好,还请各位大神给出建议,如果能够找到我的问题,那简直太感谢了。

先谢谢各位能够抽空看看我的程序了,非常感谢!
主程序如下:
/**
#include "stm32f10x.h"
#include "led.h"
#include "usart.h"
#include "adc.h"

uint8_t curr_state=0;
uint8_t counter=0;
uint8_t head;
uint8_t dataADC[25];   
extern __IO uint16_t ADC_ConvertedValue;
void Delay(__IO u32 nCount);

int main(void)
{
    /* USART1 config 115200 8-N-1 */
         
        USART1_Config();
    ADC1_Init();
         
        while(1)
        {
                switch(curr_state){
                case 0:
                head = 0x2A;
                dataADC[counter]=0x2A;
                counter++;
                GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_RESET);           
                Delay(2000);
                dataADC[counter]= ADC_ConvertedValue;                    
                 
                //dataADC[counter]=(uint8_t)(ADC_ConvertedValue & 0xFF);        
                dataADC[counter+1]=(uint8_t)((ADC_ConvertedValue >>8 )& 0xFF);
                counter+=2;//2
                Delay(20);
                curr_state=1;                       
                break;
                 
                case 1:
                GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_SET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_RESET);
                Delay(2000);
                dataADC[counter]=(uint8_t)(ADC_ConvertedValue & 0xFF);                                    
                dataADC[counter+1]=(uint8_t)((ADC_ConvertedValue >>8 )& 0xFF);
                counter+=2;//4
                Delay(20);
                curr_state=2;   
                 
                 
                case 2:
                GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_SET);
                Delay(2000);
                dataADC[counter]=(uint8_t)(ADC_ConvertedValue & 0xFF);                                    
                dataADC[counter+1]=(uint8_t)((ADC_ConvertedValue >>8 )& 0xFF);
                counter+=2;//6
                Delay(20);
                curr_state=3;   
                 
                case 3:
                GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_RESET);
                Delay(2000);
                dataADC[counter]=(uint8_t)(ADC_ConvertedValue & 0xFF);                                    
                dataADC[counter+1]=(uint8_t)((ADC_ConvertedValue >>8 )& 0xFF);
                counter+=2;//8
                Delay(20);
                curr_state=4;
                 
                case 4:
                GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_5, Bit_RESET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_4, Bit_SET);
                GPIO_WriteBit(GPIOA, GPIO_Pin_3, Bit_SET);
                Delay(2000);
                dataADC[counter]=(uint8_t)(ADC_ConvertedValue & 0xFF);                                    
                dataADC[counter+1]=(uint8_t)((ADC_ConvertedValue >>8 )& 0xFF);
                counter+=2;//10
                Delay(20);
                curr_state=5;
                 
                case 5:
                    counter=0;
                    dataADC[1] = ADC_GetConversionValue(ADC1);
                    //dataADC[2] = Get_Adc(1);  
                    UART1_Send_Array(dataADC,11);
                    Delay(2000);
                 // printf("\r\n The current AD value = 0x%04X \r\n", ADC_ConvertedValue[0]);
                    curr_state=0;
                    break;
                 default:
                    break;
            }
         
        }
}


void Delay(__IO uint32_t nCount)     
{
    for(; nCount != 0; nCount--);
}



ADC配置程序如下:
#include "adc.h"
#include "usart.h"

#define ADC1_DR_Address    ((u32)0x40012400+0x4c)

__IO uint16_t ADC_ConvertedValue;

*/    **ADC1 GPIO Configuration   
    PA2     ------> ADC1_IN2
    PB1     ------> ADC1_IN9
  */
static void ADC1_GPIO_Config(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
     
    /* Enable DMA clock */
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
     
    /* Enable ADC1 and GPIOA and GPIOB clock */
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC, ENABLE);
     
    /*Configure GPIO pins : PC14 PC15 */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14|GPIO_Pin_15;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
  GPIO_Init(GPIOC, &GPIO_InitStructure);
     
    /* Configure PA.03|4|5  as analog output */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOA, &GPIO_InitStructure);               
     
    /* Configure PB.00  as analog output */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);               
     
    /* Configure PA.02  as analog input */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOA, &GPIO_InitStructure);               
     
    /* Configure PB.01  as analog input */
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOB, &GPIO_InitStructure);   
}


static void ADC1_Mode_Config(void)
{
    DMA_InitTypeDef DMA_InitStructure;
    ADC_InitTypeDef ADC_InitStructure;
     
    /* DMA channel1 configuration */
    DMA_DeInit(DMA1_Channel1);
     
    DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address;               
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;   
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
    DMA_InitStructure.DMA_BufferSize = Numberofchannel;
    DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;   
    DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;                 
    DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;   
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;
    DMA_InitStructure.DMA_Mode = DMA_Mode_Normal ;                                   
    DMA_InitStructure.DMA_Priority = DMA_Priority_Low;
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
    DMA_Init(DMA1_Channel1, &DMA_InitStructure);
     
    /* Enable DMA channel1 */
    DMA_Cmd(DMA1_Channel1, ENABLE);
     
    /* ADC1 configuration */   
    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;           
    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 = Numberofchannel;                    
    ADC_Init(ADC1, &ADC_InitStructure);
     
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);

    ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 1, ADC_SampleTime_1Cycles5);
    ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 2, ADC_SampleTime_1Cycles5);
     
    /* Enable ADC1 DMA */
    ADC_DMACmd(ADC1, ENABLE);
     
    /* Enable ADC1 */
    ADC_Cmd(ADC1, ENABLE);
     
    ADC_ResetCalibration(ADC1);
    while(ADC_GetResetCalibrationStatus(ADC1));
     
    /* ADCУ׼ */
    ADC_StartCalibration(ADC1);
    /* µÈ´ýУ׼Íê³É*/
    while(ADC_GetCalibrationStatus(ADC1));
    /* ÓÉÓÚûÓвÉÓÃÍⲿ´¥·¢£¬ËùÒÔʹÓÃÈí¼þ´¥·¢ADCת»» */
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}
void ADC1_Init(void)
{
    ADC1_GPIO_Config();
    ADC1_Mode_Config();
}

相关帖子

沙发
小小pursue|  楼主 | 2017-8-20 20:59 | 只看该作者
顶起来,希望有人可以帮忙看一下,万分感谢。

使用特权

评论回复
板凳
feelhyq| | 2017-8-21 09:54 | 只看该作者
第61行 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; 这里应该是一个数组的地址然后强转U32,而你这个ADC_ConvertedValue 从第11行来看,定义的一个变量,然后转成U32,很有问题的。可以这样使用

定义一个数组ADC_ConvertedValue[100】,然后
第61行  DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;
第63行 DMA_InitStructure.DMA_BufferSize =100;



使用特权

评论回复
地板
feelhyq| | 2017-8-21 09:54 | 只看该作者
小小pursue 发表于 2017-8-20 20:59
顶起来,希望有人可以帮忙看一下,万分感谢。

另外 ,量一下 ADC   2个管脚的电压是不是为0,如果是的话,很可能程序本身没有问题。

使用特权

评论回复
5
gujiamao12345| | 2017-8-21 09:59 | 只看该作者
ADC的连续模式打开看看!

使用特权

评论回复
6
小小pursue|  楼主 | 2017-8-21 17:06 | 只看该作者
最后解决了。问题出在每次改变通道我使用的是NX3L4051芯片对其进行选择,尝试了一下在每次选择之后都重新ENABLE 一下ADC,就可以获取ADC的值了。感谢回复我的大神们。

使用特权

评论回复
7
小小pursue|  楼主 | 2017-8-22 09:43 | 只看该作者
feelhyq 发表于 2017-8-21 09:54
第61行 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue; 这里应该是一个数组的地址然后 ...

太感谢了,您看了我的代码!我最后能够实现功能了,但是DMA的功能却一直没有调试出来。数组的这个问题我也考虑过了,但是尝试了多种修改好像不是这个问题(因为之前参考别人的代码这样写应该是对的)。之后我会再来看看DMA传输到底哪里出了问题,谢谢您的解答。

使用特权

评论回复
8
小小pursue|  楼主 | 2017-8-22 09:44 | 只看该作者
gujiamao12345 发表于 2017-8-21 09:59
ADC的连续模式打开看看!

嗯嗯,ADC部分我后来解决了。应该不是模式的问题。。。现在剩下DMA传输的问题没有解决。。。非常感谢您的回答。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

1

主题

5

帖子

0

粉丝