打印

香主你们好,我想问各位关于STM32 AD采集的问题

[复制链接]
3365|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
simon1062|  楼主 | 2011-7-19 14:54 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
现在要用STM32的ADC1的0通道采集一路(PA0)电压,然后通过串口发给上位机,现在调试的结果,PA0悬空采集到的0,我给PA0加3.3v还是0,我现在把程序贴出来,麻烦大家帮小弟看一下,哪里出错了?谢谢!

/*******************************************************************************
*  函数功能:AD转换
*  编写时间:2011.07.08
*  作    者:
*******************************************************************************/
#include "stm32f10x.h"
#include "adc_config.h"
ErrorStatus HSEStartUpStatus;
/*
********************************************************************************
** 函数名称 : main(void)
** 函数功能 : 主函数
** 输    入 : 无
** 输    出 : 无
** 返    回 : 无
********************************************************************************
*/
int main(void)
{
   RCC_Configuration();     //时钟初始化
   GPIO_Configuration();     //GPIO初始化
   ADC1_Configuration();     //ADC1初始化
   USART1_Configuration();  //串口初始化
AD_DMA_Configuration();      
   while(1)
   {
        USART_SendData(USART1, ad_value[0]/256);
     Delayms(1);
        USART_SendData(USART1, ad_value[0]);
     Delayms(1);
        USART_SendData(USART1, '*');
     Delayms(1);
  USART_SendData(USART1, '*');
     Delayms(30);
  }      
}
/*
********************************************************************************
** 函数名称 : RCC_Configuration(void)
** 函数功能 : 时钟初始化
** 输    入 : 无
** 输    出 : 无
** 返    回 : 无
********************************************************************************
*/
void RCC_Configuration(void)
{   
   /* RCC system reset(for debug purpose) */
   RCC_DeInit();
   /* Enable HSE */
   RCC_HSEConfig(RCC_HSE_ON);
   /* Wait till HSE is ready */
   HSEStartUpStatus = RCC_WaitForHSEStartUp();
   if(HSEStartUpStatus == SUCCESS)
   {
     /* HCLK = SYSCLK */
     RCC_HCLKConfig(RCC_SYSCLK_Div1);
  
     /* PCLK2 = HCLK */
     RCC_PCLK2Config(RCC_HCLK_Div1);
     /* PCLK1 = HCLK/2 */
     RCC_PCLK1Config(RCC_HCLK_Div2);
     /* Flash 2 wait state */
     FLASH_SetLatency(FLASH_Latency_2);
     /* Enable Prefetch Buffer */
     FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
     /* PLLCLK = 8MHz * 9 = 72 MHz */
     RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9);
     /* Enable PLL */
     RCC_PLLCmd(ENABLE);
     /* Wait till PLL is ready */
     while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)
     {
     }
     /* Select PLL as system clock source */
     RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
  
     /* Wait till PLL is used as system clock source */
     while(RCC_GetSYSCLKSource() != 0x08)
     {
     }
   }
      
}
/*
********************************************************************************
** 函数名称 : GPIO_Configuration(void)
** 函数功能 : 端口初始化
** 输    入 : 无
** 输    出 : 无
** 返    回 : 无
********************************************************************************
*/
void GPIO_Configuration(void)
{
   GPIO_InitTypeDef GPIO_InitStructure;
   RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA  | RCC_APB2Periph_GPIOB, ENABLE  );
/* Configure Pa.0 (ADC Channel—0) as analog input*/
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;         // 选中管脚PA0
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;      // 模拟输入
   GPIO_Init(GPIOA, &GPIO_InitStructure);       //选择A端口
/* Configure Pa.0 (ADC Channel—1) as analog input*/
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;         // 选中管脚PA1
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;      // 模拟输入
   GPIO_Init(GPIOA, &GPIO_InitStructure);       //选择A端口

    /* Configure USART1 Tx (PA.09) as alternate function push-pull */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;      //选中管脚PA9
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;     // 复用推挽输出
   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    // 最高输出速率50MHz
   GPIO_Init(GPIOA, &GPIO_InitStructure);       // 选择A端口
   
   /* Configure USART1 Rx (PA.10) as input floating */
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;      //选中管脚PA10
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //浮空输入
   GPIO_Init(GPIOA, &GPIO_InitStructure);       //选择A端口
}
/*************************************************************
** 函数名称 :void AD_DMA_Configuration(void)
** 函数功能 :STM32 ADC1通道  DMA传输设置
** 入口参数 :
** 出口参数 :
**************************************************************/
void AD_DMA_Configuration(void)
{
   DMA_InitTypeDef DMA_InitStructure;
  //DMA传输设置
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //外设地址
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32)ad_value;//(uint32_t)&ADCConvertedValue; //存储器地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;  //外设作为数据传输的来源
  DMA_InitStructure.DMA_BufferSize = 10; //定义DMA缓冲区大小1
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; //外设地址寄存器不变
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器改变 自动变址填充 DMA_MemoryInc_Disable; //内存地址寄存器不变
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;  //设定了外设数据宽度 数据宽度为16位
  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);
}
/*
********************************************************************************
** 函数名称 : ADC1_Configuration(void)
** 函数功能 : ADC1初始化
** 输    入 : 无
** 输    出 : 无
** 返    回 : 无
********************************************************************************
*/
void ADC1_Configuration(void)
{
ADC_InitTypeDef ADC_InitStructure;

//AD 系统时钟 配置
RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE );
    // ADC1初始化配置
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;//独立工作模式
    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_InitStructure.ADC_NbrOfChannel = 1;//用于转换的通道数
    ADC_Init(ADC1, &ADC_InitStructure);      
//ADC通道采样时序配置
    ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_55Cycles5); //采样时间为55.5周期
  
    //ADC1的DMA传输配置
AD_DMA_Configuration();
//使能或者失能指定的ADC1的DMA请求
    ADC_DMACmd(ADC1, ENABLE);   
  
//使能ADC1,ADC_Cmd只能在其他ADC设置函数之后被调用
    ADC_Cmd(ADC1, ENABLE);  

//使能DMA通道5 用于AD采集
DMA_Cmd(DMA1_Channel1, ENABLE);     
   //重置ADC1的校准寄存器
    ADC_ResetCalibration(ADC1);  // 重置指定的ADC的校准寄存器
    while(ADC_GetResetCalibrationStatus(ADC1)); // 检查结束ADC1复位校准寄存器
    ADC_StartCalibration(ADC1); // 开启ADC1校准
    while(ADC_GetCalibrationStatus(ADC1)); // 检查ADC1校准是否结束
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);//使能ADC1软件转换启动
  
}

/*
********************************************************************************
** 函数名称 : USART1_Configuration(void)
** 函数功能 : 串口1初始化
** 输    入 : 无
** 输    出 : 无
** 返    回 : 无
********************************************************************************
*/
void USART1_Configuration(void)
{
USART_InitTypeDef USART_InitStructure;
USART_ClockInitTypeDef  USART_ClockInitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1 , ENABLE  );
USART_ClockInitStructure.USART_Clock = USART_Clock_Disable;   // 时钟低电平活动
USART_ClockInitStructure.USART_CPOL = USART_CPOL_Low;    // 时钟低电平
USART_ClockInitStructure.USART_CPHA = USART_CPHA_2Edge;    // 时钟第二个边沿进行数据捕获
USART_ClockInitStructure.USART_LastBit = USART_LastBit_Disable;  // 最后一位数据的时钟脉冲不从SCLK输出

/* Configure the USART1 synchronous paramters */
USART_ClockInit(USART1, &USART_ClockInitStructure);     // 时钟参数初始化设置
                  
USART_InitStructure.USART_BaudRate = 115200;        // 波特率为:115200
USART_InitStructure.USART_WordLength = USART_WordLength_8b;     // 8位数据
USART_InitStructure.USART_StopBits = USART_StopBits_1;      // 在帧结尾传输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;    // 发送使能+接收使能
/* Configure USART1 basic and asynchronous paramters */
USART_Init(USART1, &USART_InitStructure);
   
   /* Enable USART1 */
USART_ClearFlag(USART1, USART_IT_RXNE);    //清中断,以免一启用中断后立即产生中断
USART_ITConfig(USART1,USART_IT_RXNE, ENABLE);  //使能USART1中断源
USART_Cmd(USART1, ENABLE);       //USART1总开关:开启

}

/*
********************************************************************************
** 函数名称 : Delay(vu32 nCount)
** 函数功能 : 短延时函数   i=1;40us延时
** 输    入 : 无
** 输    出 : 无
** 返    回 : 无
********************************************************************************
*/
void Delay(uint32 nCount)
{
for(; nCount != 0; nCount--);
}
/*
********************************************************************************
** 函数名称 : void Delayms(vu32 m)
** 函数功能 : 长延时函数  m=1,延时1ms
** 输    入 : 无
** 输    出 : 无
** 返    回 : 无
********************************************************************************
*/
void Delayms(uint32 m)
{
  uint32 i;
  
   for(; m != 0; m--)
       for (i=0; i<50000; i++);
}

/*************结束***************/
沙发
lixiaoxu2meng| | 2011-7-20 11:43 | 只看该作者
不知 楼主程序对不对  但是LS说的很关键,没有配置 ADC时钟是肯定不对滴

使用特权

评论回复
板凳
simon1062|  楼主 | 2011-7-22 10:56 | 只看该作者
已经配置的了,在void ADC1_Configuration(void)中配置了。我现在是不通过DMA,然后直接从AD采集取数据然后发,是对的。可是加上DMA,从DMA中取数据,就不对了,应该是DMA配置问题或者DMA数据传输问题,大侠帮忙看看~~谢谢 3# lixiaoxu2meng

使用特权

评论回复
地板
simon1062|  楼主 | 2011-7-22 10:57 | 只看该作者
这个已经ADC1_Configuration(void)中配置了,而且我加上这句话还是不行,麻烦大侠再帮忙看看,谢谢~~ 2# super008

使用特权

评论回复
5
iamlight_ren| | 2011-9-6 11:23 | 只看该作者
加上这句RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);
你都让GPIO时钟使能了,RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA  | RCC_APB2Periph_GPIOB, ENABLE  );
却没让DMA1时钟使能。

使用特权

评论回复
6
jinghui1978| | 2011-9-6 13:21 | 只看该作者
本帖最后由 jinghui1978 于 2011-9-6 13:22 编辑

顶6楼! DMA1时钟必须使能。另外,我觉得还要使能AFIO的时钟,很奇怪你“不通过DMA而是直接AD采集”是怎么成功的,不开AFIO就能使用AD和串口功能吗?

使用特权

评论回复
7
iamlight_ren| | 2011-9-6 14:06 | 只看该作者
他已经使能了IO的时钟,配置了IO的AIN输入方式,就可以通过ADC_Cmd(ADC1, ENABLE);  和ADC_SoftwareStartConvCmd(ADC1, ENABLE);开始采样和转换啦。

使用特权

评论回复
8
IJK| | 2011-9-6 14:36 | 只看该作者
根据STM32 使用DMA进行ADC 转换的例程,自己改一下应该就可以了

使用特权

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

本版积分规则

0

主题

5

帖子

1

粉丝