4204|21

15

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

stm32之奇葩adc [复制链接]

改变adc输入引脚电压后,串口打印的电压值不更新,只有重新打开串口后才更新,有朋友遇到过这种情况吗?
此帖出自stm32/stm8论坛

最新回复

ADC转换完成就会置位EOC,EOC没有及时清除(看你程序,EOC标志应该是软件清除),第二次ADC已经开始采样转换,但此时EOC仍然是置位的。所以无法保证读ADC结果寄存器时,当前ADC采样刚完成,新一轮采样未开启。   详情 回复 发表于 2014-1-2 23:32
点赞 关注
 

回复
举报

6040

帖子

204

TA的资源

版主

沙发
 
估计不是STM32奇葩,而是你的程序比较奇葩。
此帖出自stm32/stm8论坛
 
 

回复

234

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
呵呵 ,是楼主比较奇葩...
此帖出自stm32/stm8论坛
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

4
 
我没有使用DMA,我是在while(1)中查询ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) ,等待ADC采集结束,然后打印。我刚刚调试了一下,每次采集的数据是正确的,打印也是对的,但是为什么全速运行的时候,串口就不更新了呢?
此帖出自stm32/stm8论坛
 
 
 

回复

234

帖子

0

TA的资源

一粒金砂(高级)

5
 
贴上你的code, 要不然别人怎么帮你..
此帖出自stm32/stm8论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

6
 

adc.c代码
#include "adc.h"

#define ADC1_DR_Address    ((u32)0x4001244C)
__IO u16 ADC_ConvertedValue;



/*
* 函数名:ADC1_GPIO_Config
* 描述  :使能ADC1和DMA1的时钟,初始化PB.01
* 输入  : 无
* 输出  :无
* 调用  :内部调用
*/
static void ADC1_GPIO_Config(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;

        /* Enable ADC1 and GPIOC clock */
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);

  /* Configure PB.01  as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOB, &GPIO_InitStructure);                                // PB1,输入时不用设置速率
}


/* 函数名:ADC1_Mode_Config
* 描述  :配置ADC1的工作模式为MDA模式
* 输入  : 无
* 输出  :无
* 调用  :内部调用
*/
static void ADC1_Mode_Config(void)
{
        ADC_InitTypeDef ADC_InitStructure;
       
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  /* ADC1 configuration */
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  ADC_InitStructure.ADC_ScanConvMode = DISABLE;
  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);

  /* ADC1 regular channel11 configuration */
  ADC_RegularChannelConfig(ADC1, ADC_Channel_9, 1, ADC_SampleTime_55Cycles5);

  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);
//  ADC_ITConfig(ADC1, ADC_IT_EOC, ENABLE);

  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1));

  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1);
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));
     
  /* Start ADC1 Software Conversion */
//  ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

/*
* 函数名:ADC1_Init
* 描述  :无
* 输入  :无
* 输出  :无
* 调用  :外部调用
*/
void ADC1_Init(void)
{
        ADC1_GPIO_Config();
        ADC1_Mode_Config();
}


此帖出自stm32/stm8论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

7
 
主函数文件
#include "stm32f10x.h"
#include "adc.h"

const unsigned char table[10] = {'0','1','2','3','4','5','6','7','8','9'};

// 软件延时
void Delay(__IO u32 nCount)
{
  for(; nCount != 0; nCount--);
}

void USART_GPIO_CONFIG()
{
        GPIO_InitTypeDef GPIO_InitStructure;
       
        //SystemInit();
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);  
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
        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;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
        GPIO_Init(GPIOA, &GPIO_InitStructure);
}

void USART_MODE_CONFIG()
{
    USART_InitTypeDef USART_InitStructure;
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
        USART_StructInit(&USART_InitStructure);
        USART_InitStructure.USART_BaudRate = 115200;
        USART_InitStructure.USART_WordLength = USART_WordLength_9b;
        USART_InitStructure.USART_Parity = USART_Parity_Even;
        USART_Init(USART1, &USART_InitStructure);
        USART_Cmd(USART1, ENABLE);
        //USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
        //USART_ITConfig(USART1, USART_IT_TXE, ENABLE);
}

void disp_adc(u16 res)
{
        u8 wan, qian, bai, shi, ge;
        wan = res / 10000;
        qian = res %10000 /1000;
        bai = res %1000 / 100;
        shi = res %100 / 10;
        ge = res %10;
        USART_SendData(USART1 , table[wan]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        USART_SendData(USART1 , table[qian]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        USART_SendData(USART1 , table[bai]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        USART_SendData(USART1 , table[shi]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        USART_SendData(USART1 , table[ge]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        USART_SendData(USART1 , '\t');
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
}

void disp_adc2(u16 d)
{
    float temp = d*3.3/4096;
        unsigned char s = (unsigned char)(temp * 10);

        USART_SendData(USART1 , table[s/10]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        USART_SendData(USART1 , '.');
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
        USART_SendData(USART1 , table[s%10]);
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);

        USART_SendData(USART1 , '\t');
        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
}

int main(void)
{       
        u16 res;
        /* config the sysclock to 72M */      
  SystemInit();

  /* USART1 config */
        USART_GPIO_CONFIG();
        USART_MODE_CONFIG();

        /* enable adc1 and config adc1 to dma mode */
        ADC1_Init();

        ADC_SoftwareStartConvCmd(ADC1, ENABLE);       

  while (1)
  {
                while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
                res = ADC_GetConversionValue(ADC1);
                disp_adc2(res);
                ADC_ClearFlag(ADC1, ADC_FLAG_EOC);  
  }
}
此帖出自stm32/stm8论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

8
 
应该是串口的问题,但是不知道哪里出了问题。
此帖出自stm32/stm8论坛
 
 
 

回复

234

帖子

0

TA的资源

一粒金砂(高级)

9
 
你串口助手用的是啥工具
此帖出自stm32/stm8论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

10
 
正点原子V1.5
此帖出自stm32/stm8论坛
 
 
 

回复

1万

帖子

16

TA的资源

版主

11
 
float temp = d*3.3/4096;
        unsigned char s = (unsigned char)(temp * 10);
我觉得问题在这里,是你程序的事
此帖出自stm32/stm8论坛

点评

这段代码是把数字量换算成电压值,并精确到小数点后一位。你认为问题在哪里?  详情 回复 发表于 2013-12-29 14:03
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

12
 
ddllxxrr 发表于 2013-12-29 04:04
float temp = d*3.3/4096;
        unsigned char s = (unsigned char)(temp * 10);
我觉得问题在这里, ...

这段代码是把数字量换算成电压值,并精确到小数点后一位。你认为问题在哪里?
此帖出自stm32/stm8论坛
 
 
 

回复

1万

帖子

16

TA的资源

版主

13
 
这句总是得取整数部分,并且还是CHAR,言外之意,就是基本上值 不变
此帖出自stm32/stm8论坛

点评

temp取值范围在0到3.3之间 ,乘以10之后转换成char,s范围是0到33,怎么会不变你?  详情 回复 发表于 2013-12-30 19:55
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

14
 
void disp_adc2(u16 d)
{
    float temp = d*3.3/4096;
        unsigned char s = (unsigned char)(temp * 10);

//        USART_SendData(USART1 , table[s/10]);
//        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
//        USART_SendData(USART1 , '.');
//        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
//        USART_SendData(USART1 , table[s%10]);
//        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);

//        USART_SendData(USART1 , '\t');
//        while(USART_GetFlagStatus(USART1, USART_FLAG_TC)==RESET);
}
既然没有开串口,为什么不屏蔽串口应用呢?你程序一直在检测串口发送这里的while停留。难怪不刷信AD值,要是变化了才怪。
此帖出自stm32/stm8论坛

点评

我是每发送一个字符才等待的,一次电压值发送完成之后,怎么会停留在while里呢?  详情 回复 发表于 2013-12-30 19:57
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

15
 
ddllxxrr 发表于 2013-12-29 22:20
这句总是得取整数部分,并且还是CHAR,言外之意,就是基本上值 不变

temp取值范围在0到3.3之间 ,乘以10之后转换成char,s范围是0到33,怎么会不变你?
此帖出自stm32/stm8论坛
 
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

16
 
ltbytyn 发表于 2013-12-29 22:49
void disp_adc2(u16 d)
{
    float temp = d*3.3/4096;

我是每发送一个字符才等待的,一次电压值发送完成之后,怎么会停留在while里呢?
此帖出自stm32/stm8论坛

点评

抱歉,那一块我看错了。 下一次的ADC,你在什么地方启动ADC了?  详情 回复 发表于 2013-12-30 20:31
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

17
 
dzgcsj_hz 发表于 2013-12-30 19:57
我是每发送一个字符才等待的,一次电压值发送完成之后,怎么会停留在while里呢?

抱歉,那一块我看错了。
下一次的ADC采样,你在什么地方启动了?
此帖出自stm32/stm8论坛

点评

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;连续转换的  详情 回复 发表于 2013-12-31 15:16
 
 
 

回复

1万

帖子

16

TA的资源

版主

18
 
ADC_SoftwareStartConvCmd(ADC1, ENABLE);        

  while (1)
  {
                while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);
                res = ADC_GetConversionValue(ADC1);
                disp_adc2(res);
                ADC_ClearFlag(ADC1, ADC_FLAG_EOC);  
  }
}

应把最上一句加到while中第一句

  
此帖出自stm32/stm8论坛
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

回复

15

帖子

0

TA的资源

一粒金砂(初级)

19
 
ltbytyn 发表于 2013-12-30 20:31
抱歉,那一块我看错了。
下一次的ADC采样,你在什么地方启动了?

ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;连续转换的
此帖出自stm32/stm8论坛
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

20
 
在连续转换模式下,你如何保证读取AD结果时当前AD刚好转换完成,还没有启动新一轮转换。如果在AD采样过程中读AD结果寄存器,值能对吗?你的程序确实很奇葩。
建议:
1、如果用查询方式,你就用单次转换模式。
2、如果用连续转换模式,你就开启AD中断,转换完成后立即读AD结果寄存器。
此帖出自stm32/stm8论坛

点评

但是我先查询了EOC标志,while(ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET);这样不能保证转换已经完成了吗?  详情 回复 发表于 2014-1-2 17:34
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表