OpenEdv-开源电子网

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

关于ADC的一些疑惑

[复制链接]

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-2-18
在线时间
0 小时
发表于 2011-2-22 17:40:59 | 显示全部楼层 |阅读模式
1、STM32F103xC的数据手册上的,管脚标示的ADC123_XX,ADC12_XX,ADC3_XX,这些那个是参考手册上所说的ADC1,ADC2,ADC3呢?
2、我要用5个ADC通道,而且想每次ADC转换完后都进入中断处理,如果我选扫描模式+连续工作模式对吗?
  因为我是第一次用,有什么需要注意的吗?谢谢
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-2-22 18:06:29 | 显示全部楼层
回复【楼主位】comeon_lsl:
-------------------------------
首先,STM32内部最多有3个ADC转换器。
大容量的(超过128Kflash)才有3个ADC,对于我们的STM32F103RBT6,只有2个ADC转换器。
不同的ADC转换器可以并行工作,而不同的通道,同一时间只能单个工作。

1,ADC123_XXX,代表内部ADC转换器1、2、3的第XX通道。也就是说这个通道是3个ADC共用的,一个时间只能由一个ADC转换器占有。
ADC12_XX,意义同上,代表ADC转换器1、2的第XX通道。
ADC3_XX,我想你自己都知道什么意思了?

2,5个通道,可以用1个ADC的5个通道即可,比如ADC1的5个通道。你的转换模式是 对的,不过这种模式的中断我没试过。
另外一个好一点的办法,就是用DMA操作,这样省事。当然,前提是你能灵活使用DMA和ADC了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-2-18
在线时间
0 小时
 楼主| 发表于 2011-2-23 10:23:42 | 显示全部楼层
如果按我选那种工作模式,只有在5个通道都转换完毕才可以中断!但是,是不是这时候转换结果就只能得到最后一次转换的,前面四次被覆盖掉了!那还是用单次转换好了!
另外,ADC1->CR2|=1<<20;      //使用用外部触发(SWSTART)!!!          必须使用一个事件来触发
       有点儿不懂!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-2-23 11:26:08 | 显示全部楼层
回复【3楼】comeon_lsl:
-------------------------------
那可能连续转换需要用DMA。


ADC1->CR2|=1<<20;  就是选择使用外部触发adc。
具体请看 《STM32参考手册》的外部触发转换一章(10.7节)
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-2-18
在线时间
0 小时
 楼主| 发表于 2011-2-23 17:23:01 | 显示全部楼层
有没有什么,介绍应用DMA比较详细的资料!很晕,现在
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-2-23 18:06:10 | 显示全部楼层
回复【5楼】comeon_lsl:
-------------------------------
DMA其实比较简单的。
你看看STM32参考手册的DMA部分,然后看看我的那个DMA串口代码。基本就能理解了。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-2-18
在线时间
0 小时
 楼主| 发表于 2011-2-23 20:17:40 | 显示全部楼层
       我的目的:就是用5个ADC通道不断地在采集5个物理量,并且每个量采集后都想去做些中断处理(实时),应该大概什么思路!不好意思,麻烦了!谢谢!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-2-23 20:21:52 | 显示全部楼层
回复【7楼】comeon_lsl:
-------------------------------
单次采集,完成后中断。
循环5次。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2011-2-18
在线时间
0 小时
 楼主| 发表于 2011-2-24 10:29:40 | 显示全部楼层
1、如果我设置了EOCIE,是表示我在启动规则通道转换完成后,自动进入ADC1_2_IRQHandler()函数中吗?
         (对ADC1_2_IRQChannel设置了优先级)。
2、因为我对5个量的中断处理都不一样,这里貌似只有一个中断服务函数可写,那我的5种处理方法如何实施?我的理解哪里有错误?
3、大概看了下DMA,ADC配置为使用DMA模式,结果是:5个规则通道每个通道转换结束时都发送DMA请求来进行数据传输吗??(DMA的相关配置应该是固定了吧,目标地址定了,那传输的5个数据量可以连续存储在这个地址上吗) 不过这种方式,不能满足我及时中断判断的要求吧!
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2011-3-3
在线时间
12 小时
发表于 2011-3-3 22:15:24 | 显示全部楼层
今天刚也刚刚学了ADC不过还没看过DMA,不过在循环扫描模式((SCAN==1)  && ( CONT == 1))下,应该是每有一个通道转换完毕后就会有一个DMA请求,因为转换后数据只能存入一个寄存器中(ADC_DR),如果不是一次一取,DMA就没意义了,毕竟DMA主要就是给扫描方式配置的,怕的就是数据重叠。如果真那样,那硬件就该改进。(呵呵,初学者,以交流的心态留言,若理解不对,必须给我指正)
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-3-4 10:39:22 | 显示全部楼层
回复【10楼】爱上cmu:
-------------------------------
有的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

7

主题

85

帖子

0

精华

初级会员

Rank: 2

积分
163
金钱
163
注册时间
2011-3-3
在线时间
12 小时
发表于 2011-3-4 18:35:02 | 显示全部楼层
额 有的是什么意思??理解不对给我指正一下,呵呵
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
42
金钱
42
注册时间
2010-12-17
在线时间
4 小时
发表于 2011-3-4 20:47:32 | 显示全部楼层
我觉得中断服务程序里面就写DMA,因为每次转换完成,触发中断之后,A/D转换的数据都是储存在ADC_DR里面的,所以只要每次进入IRQ之后用DMA读出ADC_DR就可以了。
不知道这样可不可以?
班门弄斧了哈
见贤思齐!
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2011-3-5 00:35:37 | 显示全部楼层
回复【13楼】lyz980926:
-------------------------------
如果每次都进入中断的话,那就不是DMA了...

ADC,DMA的概念,就是,当你设定好通道之后,启动DMA转换,然后ADC的值,按顺序存放 在DMA设定的地址.等转换完成,触发DMA转换完成中断.在此期间,CPU是不需要介入的!

欢迎大家多提意见!
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

2

帖子

0

精华

新手入门

积分
26
金钱
26
注册时间
2011-3-18
在线时间
0 小时
发表于 2011-3-18 10:07:24 | 显示全部楼层
恩,我和楼主卡在同一个地方。现在正在看DMA,不然没办法把每次每个通道转换完后的数据提取出来。不然就要被下一个覆盖。
大家都是从不懂到懂的
回复 支持 反对

使用道具 举报

1

主题

12

帖子

0

精华

新手上路

积分
36
金钱
36
注册时间
2013-7-17
在线时间
0 小时
发表于 2013-7-24 16:48:22 | 显示全部楼层


随遇而安~
回复 支持 反对

使用道具 举报

25

主题

139

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-5-10
在线时间
0 小时
发表于 2014-5-23 12:25:14 | 显示全部楼层
回复【14楼】正点原子:
---------------------------------
原子哥,我用注入通道,然后它可以存放4个转换数值,就可以处理4组通道的值了,然后再加一组规则通道的,这样就可以实现5组数值的转化了。是吗?
可是我今天用注入通道,设置0和1通道,然后转化,结果不好使,我就看着手册编的,不知道哪里配置出错了,请原子哥帮忙看看
#include "adc.h"
#include "delay.h"
#include  "led.h"
void Adc_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
ADC_InitTypeDef  ADC_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOA,ENABLE);
        RCC_ADCCLKConfig(RCC_PCLK2_Div6);

 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;   //模拟输入
 GPIO_Init(GPIOA, &GPIO_InitStructure);  //根据设定参数初始化GPIOA.1


     ADC_DeInit(ADC1);

 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_Init(ADC1,&ADC_InitStructure);

     ADC_Cmd(ADC1,ENABLE);
 ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_None);

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

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

}


u16 Get_Adcx(u8 ADC_Channel_x)
{
     ADC_InjectedChannelConfig(ADC1,ADC_Channel_x,1,ADC_SampleTime_239Cycles5);
 ADC_InjectedSequencerLengthConfig(ADC1,2);



    ADC_SoftwareStartConvCmd(ADC1,ENABLE);

// while(ADC_GetSoftwareStartConvStatus(ADC1));     //返回为0, 我操,跟理解的不一样,具体看寄存器操作

 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC ));

 return ADC_GetInjectedConversionValue(ADC1,ADC_Channel_x);     
}

u16 Get_Adcy(u8 ADC_Channel_y)
{
     ADC_InjectedChannelConfig(ADC1,ADC_Channel_y,2,ADC_SampleTime_239Cycles5);
 ADC_InjectedSequencerLengthConfig(ADC1,2);



    ADC_SoftwareStartConvCmd(ADC1,ENABLE);

// while(ADC_GetSoftwareStartConvStatus(ADC1));     //返回为0, 我操,跟理解的不一样,具体看寄存器操作

 while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC ));

 return ADC_GetInjectedConversionValue(ADC1,ADC_Channel_y);       
}

u16 Get_Adc_Averagex(u8 ch,u8 times)
{
u32 temp_Val=0;
u8 t;
for(t=0;t<times;t++)
{
 temp_Val+=Get_Adcx(ch);
 delay_ms(5);
}

return  temp_Val/times;
 
}


u16 Get_Adc_Averagey(u8 ch,u8 times)
{
u32 temp_Val=0;
u8 t;
for(t=0;t<times;t++)
{
 temp_Val+=Get_Adcy(ch);
 delay_ms(5);
}

return  temp_Val/times;
 
}>
愈挫愈勇
回复 支持 反对

使用道具 举报

0

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2014-5-4
在线时间
0 小时
发表于 2014-5-23 14:25:39 | 显示全部楼层
回复【17楼】非常完美:
---------------------------------
我来替原子哥回复你。
以前对多通道ADC规则转换和DMA研究较多,对注入转换比较少关注,但是看到楼猪发了这个注入组的程序,于是乎闲着无聊调试了一下,下面给出楼猪程序上需要改动的地方。
1、楼猪对注入组的理解基本上是没有问题的,但是从程序上看有明显地从规则通道ADC转换程序移植过来的痕迹,首先第一个很明显的错误就是楼猪在软件启动注入组转换的时候,例如在Get_Adcx(u8 ADC_Channel_x) 还有Get_Adcy(u8 ADC_Channel_y) 函数里,楼猪的代码是:ADC_SoftwareStartConvCmd(ADC1,ENABLE); 这尼玛是规则组的软件开启转换函数好不好,应该改为:ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
2、在获取注入组转换结果的时候,楼猪的代码也有问题,楼猪获取注入组转换数据的代码:return ADC_GetInjectedConversionValue(ADC1,ADC_Channel_x); 建议楼猪仔细看一下库函数中这个函数的详细说明,第二个形参是注入通道的偏移量,而不是通道偏移量。
ADC_GetInjectedConversionValue(ADC1,ADC_Channel_x);应该改为ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1); 

ADC_GetInjectedConversionValue(ADC1,ADC_Channel_y);应该改为ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2); 

3、楼猪程序里虽然不一定有问题,但是我觉得不合适的地方,楼猪把获取注入组两个通道的采集数据的函数分开写,而每获取一个通道的数据,就要加一个注入组转换结束的判断,这样我觉得不好,应该在注入组转换结束的判断里面一口气把两个通道的数据都取出来,不知道这样说楼猪能不能理解。
回复 支持 反对

使用道具 举报

0

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2014-5-4
在线时间
0 小时
发表于 2014-5-23 14:30:35 | 显示全部楼层
回复【17楼】非常完美:
---------------------------------
把我调通的程序发给你,供你参考,不过有些地方需要你改一下,我用的不是PA0和PA1,而是PC3和PC4(也就是通道13和通道14)

#include "stm32f10x.h"
#include <stdio.h>

/* rivate define ------------------------------------------------------------*/
#define ADC1_DR_Address    ((u32)0x4001244C)
/* rivate function prototypes -----------------------------------------------*/
void ADC_Configuration(void);

/* rivate variables ---------------------------------------------------------*/
vu16 ADC_ConvertedValue[2];  //定义保存AD采样值的数组

/*******************************************************************************
* Function Name: main
* Description : Main program
* Input       : None
* Output      : None
* Return      : None
* Attention : None
*******************************************************************************/
int main(void)
{
ADC_Configuration();
  ADC_InjectedSequencerLengthConfig(ADC1,2);
 ADC_InjectedChannelConfig(ADC1,ADC_Channel_13,1,ADC_SampleTime_239Cycles5);
 ADC_InjectedChannelConfig(ADC1,ADC_Channel_14,2,ADC_SampleTime_239Cycles5);
    ADC_SoftwareStartInjectedConvCmd(ADC1, ENABLE);
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_JEOC ));
  ADC_ConvertedValue[0]=ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_1);
ADC_ConvertedValue[1]=ADC_GetInjectedConversionValue(ADC1,ADC_InjectedChannel_2);
  while (1)
  {

  
  }
}

/*******************************************************************************
* Function Name: ADC_Configuration
* Description : Configure the ADC.
* Input       : None
* Output      : None
* Return      : None
* Attention : None
*******************************************************************************/
void ADC_Configuration(void)
{   
  GPIO_InitTypeDef GPIO_InitStructure;
  ADC_InitTypeDef ADC_InitStructure;

  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOC |     RCC_APB2Periph_GPIOA, ENABLE);
  RCC_ADCCLKConfig(RCC_PCLK2_Div6);

  GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0|GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;   //模拟输入
  GPIO_Init(GPIOA, &GPIO_InitStructure);  //根据设定参数初始化GPIOA.1 

  /* Configure C? (ADC12 Channel4)as analog input -------------------------*/
   GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
  GPIO_Init(GPIOC, &GPIO_InitStructure);  //选择端口PC1,最大输出速度50MHZ,模拟输入 

  ADC_DeInit(ADC1);
  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //ADC1工作在独立模式 缺省值
  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数据右对齐
  ADC_Init(ADC1, &ADC_InitStructure);  //选择ADC1

  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE); //使能AD
  ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_None); 
  /* Enable ADC1 reset calibaration register */   
  ADC_ResetCalibration(ADC1);  //重置ADC1的校准寄存器
  /* Check the end of ADC1 reset calibration register */
  while(ADC_GetResetCalibrationStatus(ADC1)); //判断重置ADC1校准寄存器是否完毕,如果返回值0,表示完毕

  /* Start ADC1 calibaration */
  ADC_StartCalibration(ADC1); //开始指定ADC的校准状态
  /* Check the end of ADC1 calibration */
  while(ADC_GetCalibrationStatus(ADC1));  //获取指定ADC的校准程序,如果返回值0,表示完毕
}
回复 支持 反对

使用道具 举报

25

主题

139

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-5-10
在线时间
0 小时
发表于 2014-5-23 15:07:22 | 显示全部楼层
回复【18楼】cdshkf:
---------------------------------
好的,非常感谢,谢谢大神,感谢。
愈挫愈勇
回复 支持 反对

使用道具 举报

25

主题

139

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-5-10
在线时间
0 小时
发表于 2014-5-23 15:08:46 | 显示全部楼层
回复【19楼】cdshkf:
---------------------------------
感谢大神啊,小弟菜鸟,再次谢过,东西太多,没条理过来,经常忽略些细节,也是不熟悉的表现,谢谢哥,非常感谢
愈挫愈勇
回复 支持 反对

使用道具 举报

25

主题

139

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-5-10
在线时间
0 小时
发表于 2014-5-23 15:19:22 | 显示全部楼层
回复【19楼】cdshkf:
---------------------------------
 ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_None); 
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
上面这两句是不多余的吧,其他的我感觉完美了,嘿嘿,真心写的好,都是有良好的写代码的习惯,向大神学习了
愈挫愈勇
回复 支持 反对

使用道具 举报

0

主题

59

帖子

0

精华

初级会员

Rank: 2

积分
79
金钱
79
注册时间
2014-5-4
在线时间
0 小时
发表于 2014-5-23 17:01:40 | 显示全部楼层
回复【22楼】非常完美:
---------------------------------
sorry,GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 这一句是不小心加上去的,输入模式下木有用。
ADC_ExternalTrigInjectedConvConfig(ADC1,ADC_ExternalTrigInjecConv_None);这一句尽量加上吧。
回复 支持 反对

使用道具 举报

25

主题

139

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-5-10
在线时间
0 小时
发表于 2014-5-23 19:28:10 | 显示全部楼层
回复【23楼】cdshkf:
---------------------------------
大神,看看我这个为啥出错了

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "usart.h"  
#include "adc.h"
#include "usmart.h"
//ALIENTEK战舰STM32开发板实验17
//ADC 实验  
//技术支持:www.openedv.com
//广州市星翼电子科技有限公司  

/*************************************
连接:LED连PB0和PB1
      ADC通道内部连接温度传感器  ((uint8_t)ADC_Channel_16)
  串口连接PA9和PA10
*************************************/ 
 int main(void)
 {  
    u16 adcx;
float temp;
  float temperate;
delay_init();       //延时函数初始化   
NVIC_Configuration();   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600);   //串口初始化为9600
  LED_Init();      //LED端口初始化  
  T_Adc_Init();    //ADC初始化      
usmart_dev.init(SystemCoreClock/1000000); //初始化USMART   

     
while(1)
{
// adcx=Get_Adc_Average(ADC_Channel_TempSensor,10);  
adcx=T_Get_Temp();
printf("ADC值: %d\n",adcx);//显示ADC的值
temp=(float)adcx*(3.3/4096);    //ADC为12位,2^12=4096
temperate=temp;//保存温度传感器的电压值
adcx=temp;
printf("电压值整数部分:%dV\n",adcx);//显示电压值整数部分
temp-=(u8)temp;      //减掉整数部分
printf("电压小数部分:%gV\n",temp*1000);
temperate=(1.43-temperate)/0.0043+25; //计算出当前温度值
printf("温度整数部分:%g",temperate); //显示温度整数部分
    temperate-=(u8)temperate;
printf("温度小数部分:%g",temperate*100);
LED0B=!LED0B;
delay_ms(300);

}
 }



结果成这样了:
ADC值: 2387
电压值整数部分:1V
电压小数部分:923.12V
温度整数部分:-89.6791温度小数部分:-17867.9ADC值: 2392
电压值整数部分:1V
电压小数部分:927.148V
温度整数部分:-90.6159温度小数部分:-18061.6ADC值: 2387
电压值整数部分:1V
电压小数部分:923.12V
温度整数部分:-89.6791温度小数部分:-17867.9ADC值: 2388
电压值整数部分:1V
电压小数部分:923.926V
温度整数部分:-89.8665温度小数部分:-17886.6ADC值: 2383
电压值整数部分:1V
电压小数部分:919.897V
温度整数部分:-88.9296温度小数部分:-17693
愈挫愈勇
回复 支持 反对

使用道具 举报

25

主题

139

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
259
金钱
259
注册时间
2014-5-10
在线时间
0 小时
发表于 2014-5-23 19:30:20 | 显示全部楼层
回复【23楼】cdshkf:
---------------------------------
我没有动原子哥的tsensor.h和tsensor.c文件,原封不动粘贴到我的acd.h和acd.c里面的,能出结果,说明驱动没问题,就是主函数出错了
原子哥的主函数是这样的:

#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"  
#include "tsensor.h"
//ALIENTEK战舰STM32开发板实验18
//内部温度传感器 实验  
//技术支持:www.openedv.com
//广州市星翼电子科技有限公司   
 int main(void)
 {  
u16 adcx;
float temp;
  float temperate;
delay_init();       //延时函数初始化   
NVIC_Configuration();   //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(9600);   //串口初始化为9600
  LED_Init();      //LED端口初始化
LCD_Init();  
   T_Adc_Init();    //ADC初始化

POINT_COLOR=RED;//设置字体为红色 
LCD_ShowString(60,50,200,16,16,"WarShip STM32");
LCD_ShowString(60,70,200,16,16,"ADC TEST");
LCD_ShowString(60,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(60,110,200,16,16,"2012/9/7");
//显示提示信息       
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,130,200,16,16,"TEMP_VAL:");       
LCD_ShowString(60,150,200,16,16,"TEMP_VOL:0.000V");       
LCD_ShowString(60,170,200,16,16,"TEMPERATE:00.00C");       
while(1)
{
adcx=T_Get_Adc_Average(ADC_CH_TEMP,10);
LCD_ShowxNum(132,130,adcx,4,16,0);//显示ADC的值
temp=(float)adcx*(3.3/4096);
temperate=temp;//保存温度传感器的电压值
adcx=temp;
LCD_ShowxNum(132,150,adcx,1,16,0);      //显示电压值整数部分
temp-=(u8)temp;      //减掉整数部分   
LCD_ShowxNum(148,150,temp*1000,3,16,0X80); //显示电压小数部分
  
temperate=(1.43-temperate)/0.0043+25; //计算出当前温度值  
LCD_ShowxNum(140,170,(u8)temperate,2,16,0); //显示温度整数部分
temperate-=(u8)temperate;   
LCD_ShowxNum(164,170,temperate*100,2,16,0X80);//显示温度小数部分
LED0=!LED0;
delay_ms(250);
}
 }
愈挫愈勇
回复 支持 反对

使用道具 举报

27

主题

259

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
387
金钱
387
注册时间
2014-8-19
在线时间
0 小时
发表于 2014-9-26 17:42:43 | 显示全部楼层
回复【7楼】comeon_lsl:
---------------------------------
使用效果怎么样?
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-1 03:11

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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