查看: 4447|回复: 11

[已解决] FreeDom板KL25内部ADC模块问题(已解决)

[复制链接]

该用户从未签到

37

主题

132

帖子

0

新手上路

Rank: 1

积分
40
最后登录
1970-1-1
发表于 2013-9-24 11:29:56 | 显示全部楼层 |阅读模式
被KL25内部的ADC模块困扰很久了,它总是不能读出正确的数值,跟例程对比了很多次了也没有发现那里写的有问题。求FAE帮忙,不要跟我给什么例程的链接,谢谢啦!代码见附件
//============================================================================//
//函数说明:ADC 初始化配置
//输入:
//输出:
//============================================================================//
void ADC0_InitCfg(void)
{
  SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;                    // enable PORTB clock
  SIM_SCGC6 |= SIM_SCGC6_ADC0_MASK;                    // enable ADC0 clock
 
  PORTB_PCR0 = PORT_PCR_MUX(0);
 
  ADC0_CFG1 = ADC_CFG1_ADIV(3)                          // clock divide ratio is 8
            | ADC_CFG1_ADLSMP_MASK                      // long sample time
            | ADC_CFG1_MODE(3)                          // based on DIFF,single-ended 16bit/differential 16bit conversion
            | ADC_CFG1_ADICLK(0);                        // Bus clock as ADC0 clock source
 
  ADC0_CFG2 = ADC_CFG2_ADLSTS(0);                     // long sample time select :20 extra ADCK cycles,24 ADCK cycles total
   
  ADC0_SC3 = ADC_SC3_AVGE_MASK                          // hardware average enable
           | ADC_SC3_AVGS(3)                            // 32 samples average
           | ADC_SC3_ADCO_MASK;                         // continuous conversion
 
  ADC0_SC1A = ADC_SC1_ADCH(31) & (~ADC_SC1_AIEN_MASK);                        // close ADC
 
  ADC0_SC1B = ADC_SC1_ADCH(31) & (~ADC_SC1_AIEN_MASK);
}

//============================================================================//
//函数说明:ADC 校正
//输入:
//输出: 
//============================================================================//
unsigned char ADC0_Calibration(void)
{
  unsigned short cal_var;
 
  ADC0_SC2 &=  ~ADC_SC2_ADTRG_MASK ;                            // Enable Software Conversion Trigger for Calibration Process    - ADC0_SC2 = ADC0_SC2 | ADC_SC2_ADTRGW(0);  
  ADC0_SC3 &= ( ~ADC_SC3_ADCO_MASK & ~ADC_SC3_AVGS_MASK );      // set single conversion, clear avgs bitfield for next writing
  ADC0_SC3 |= ( ADC_SC3_AVGE_MASK | ADC_SC3_AVGS(3) );    // Turn averaging ON and set at max value ( 32 )
 
 
  ADC0_SC3 |= ADC_SC3_CAL_MASK ;                                // Start CAL
  while ( !(ADC0_SC1A & ADC_SC1_COCO_MASK ) );                  // Wait calibration end
     
  if ((ADC0_SC3 & ADC_SC3_CALF_MASK) == ADC_SC3_CALF_MASK )
  { 
   return 1;                                                   // Check for Calibration fail error and return
  }
 
  // Calculate plus-side calibration
  cal_var = 0x00;
 
  cal_var =  ADC0_CLP0;
  cal_var += ADC0_CLP1;
  cal_var += ADC0_CLP2;
  cal_var += ADC0_CLP3;
  cal_var += ADC0_CLP4;
  cal_var += ADC0_CLPS;

  cal_var = cal_var/2;
  cal_var |= 0x8000;                                            // Set MSB

  ADC0_PG = ADC_PG_PG(cal_var);
 

  // Calculate minus-side calibration
  cal_var = 0x00;

  cal_var =  ADC0_CLM0;
  cal_var += ADC0_CLM1;
  cal_var += ADC0_CLM2;
  cal_var += ADC0_CLM3;
  cal_var += ADC0_CLM4;
  cal_var += ADC0_CLMS;

  cal_var = cal_var/2;

  cal_var |= 0x8000; // Set MSB

  ADC0_MG = ADC_MG_MG(cal_var);
 
  ADC0_SC3 &= ~ADC_SC3_CAL_MASK ; /* Clear CAL bit */

  return 0;
}
 

int main(void)
{
  float result;
  unsigned char i;
  unsigned char m,n;
 
  ADC0_InitCfg();
  ADC0_Calibration();
  ADC0_InitCfg();
 
  ADC0_SC1A = ADC_SC1_ADCH(8) | ADC_SC1_AIEN_MASK;                         
 
  //ADC0_SC1B = ADC_SC1_ADCH(8) | ADC_SC1_AIEN_MASK;
 
  PITDelay_ms(1);                            // a little delay for decrease noise effect
 
  while(1)
  {
    if( (ADC0_SC1A & ADC_SC1_COCO_MASK) )
    {
      result = ADC0_RA;
      result = ((result * 33) / 655360) * 100;
      m = (unsigned int)(result) / 100;
      n = (unsigned int)(result) % 100;
      printf("%d.%dV \n",m,n);
    }
    for(i=0;i
我知道答案 目前已有10人回答
回复

使用道具 举报

该用户从未签到

35

主题

508

帖子

0

金牌会员

Rank: 6Rank: 6

积分
2167
最后登录
1970-1-1
发表于 2013-9-24 11:35:25 | 显示全部楼层

RE:FreeDom板KL25内部ADC模块问题

你现在的问题是ADC能正常工作,但是采集到的值不准备,对吗?差多少呢?
回复 支持 反对

使用道具 举报

该用户从未签到

37

主题

132

帖子

0

新手上路

Rank: 1

积分
40
最后登录
1970-1-1
 楼主| 发表于 2013-9-24 11:52:21 | 显示全部楼层

回复:FreeDom板KL25内部ADC模块问题

回复第 2 楼 于2013-09-24 11:35:25发表:
你现在的问题是ADC能正常工作,但是采集到的值不准备,对吗?差多少呢?
 
不是差多少的原因,关键是完全就是错的,但奇怪的是如果我将IO采样通道连上FreeDom板上的电源电压3.3v时,它就一直很准了,我以同样的方式接到开关电源上去也是3.3V,它就不准。
 
回复 支持 反对

使用道具 举报

该用户从未签到

27

主题

142

帖子

0

新手上路

Rank: 1

积分
329
最后登录
1970-1-1
发表于 2013-9-24 12:26:37 | 显示全部楼层

回复:FreeDom板KL25内部ADC模块问题

回复第 3 楼 于2013-09-24 11:52:21发表:
回复第 2 楼 于2013-09-24 11:35:25发表:
你现在的问题是ADC能正常工作,但是采集到的值不准备,对吗?差多少呢?
 
不是差多少的原因,关键是完全就是错的,但奇怪的是如果我将IO采样通道连上FreeDom板上的电源电压3.3v时,它就一直很准了,我以同样的方式接到开关电源上去也是3.3V,它就不准。
 
你的开关电源多少V啊,建议你用示波器测下啊,我用官方给的例程测试还是蛮准的呀
 

 
回复 支持 反对

使用道具 举报

该用户从未签到

37

主题

132

帖子

0

新手上路

Rank: 1

积分
40
最后登录
1970-1-1
 楼主| 发表于 2013-9-24 13:06:43 | 显示全部楼层

回复:FreeDom板KL25内部ADC模块问题

回复第 4 楼 于2013-09-24 12:26:37发表:
回复第 3 楼 于2013-09-24 11:52:21发表:
回复第 2 楼 于2013-09-24 11:35:25发表:
你现在的问题是ADC能正常工作,但是采集到的值不准备,对吗?差多少呢?
 
不是差多少的原因,关键是完全就是错的,但奇怪的是如果我将IO采样通道连上FreeDom板上的电源电压3.3v时,它就一直很准了,我以同样的方式接到开关电源上去也是3.3V,它就不准。
 
你的开关电源多少V啊,建议你用示波器测下啊,我用官方给的例程测试还是蛮准的呀
 
能不能把你的工程发给我试一下,电源输出的电压没有问题!你的是FreeDom KL25吗?huhaomcu@126.com
 

 

 
回复 支持 反对

使用道具 举报

该用户从未签到

37

主题

132

帖子

0

新手上路

Rank: 1

积分
40
最后登录
1970-1-1
 楼主| 发表于 2013-9-24 13:54:46 | 显示全部楼层

回复:FreeDom板KL25内部ADC模块问题

问题已解决!并非程序上的问题!
原因在于我的测试电压源选择的是直流稳压电源,所以结果就是乱七八糟的,具体原因不明白,有明白的人请赐教!
还有一个问题不明白,就是当我的AD采样通道处于悬空状态时即什么都不接,电压应该是0V啊,但为什么得到的值也是乱七八糟的呢!模电学的太差了,惭愧啊!
回复 支持 反对

使用道具 举报

该用户从未签到

27

主题

142

帖子

0

新手上路

Rank: 1

积分
329
最后登录
1970-1-1
发表于 2013-9-24 13:58:24 | 显示全部楼层

回复:FreeDom板KL25内部ADC模块问题

回复第 5 楼 于2013-09-24 13:06:43发表:
回复第 4 楼 于2013-09-24 12:26:37发表:
回复第 3 楼 于2013-09-24 11:52:21发表:
回复第 2 楼 于2013-09-24 11:35:25发表:
你现在的问题是ADC能正常工作,但是采集到的值不准备,对吗?差多少呢?
 
不是差多少的原因,关键是完全就是错的,但奇怪的是如果我将IO采样通道连上FreeDom板上的电源电压3.3v时,它就一直很准了,我以同样的方式接到开关电源上去也是3.3V,它就不准。
 
你的开关电源多少V啊,建议你用示波器测下啊,我用官方给的例程测试还是蛮准的呀
 
能不能把你的工程发给我试一下,电源输出的电压没有问题!你的是FreeDom KL25吗?huhaomcu@126.com
 
 
 
给你我的C文件吧,你可以移植到自己的工程里面,也是根据官方的自己修改的。
主函数中时钟
初始化值
  adc_init(0x01,0x03,0x00,0x00);//通道8
读取时
ADC = adc_read(8,0x00);
即可。祝你调试顺利
 

 

 

 

ADC.c.rar

2.04 KB, 下载次数: 40

回复 支持 反对

使用道具 举报

该用户从未签到

124

主题

3600

帖子

0

金牌会员

Rank: 6Rank: 6

积分
5781
最后登录
1970-1-1
发表于 2013-9-24 14:13:33 | 显示全部楼层

RE:FreeDom板KL25内部ADC模块问题

高阻输入悬空,正常是不允许的。
给你一个ADC悬空的主题讨论链接:
http://bbs.21ic.com/icview-312554-1-1.html
回复 支持 反对

使用道具 举报

该用户从未签到

27

主题

142

帖子

0

新手上路

Rank: 1

积分
329
最后登录
1970-1-1
发表于 2013-9-24 14:13:50 | 显示全部楼层

回复:FreeDom板KL25内部ADC模块问题

回复第 6 楼 于2013-09-24 13:54:46发表:
问题已解决!并非程序上的问题!
原因在于我的测试电压源选择的是直流稳压电源,所以结果就是乱七八糟的,具体原因不明白,有明白的人请赐教!
还有一个问题不明白,就是当我的AD采样通道处于悬空状态时即什么都不接,电压应该是0V啊,但为什么得到的值也是乱七八糟的呢!模电学的太差了,惭愧啊!
 
 
ADC的管脚设成悬浮输入,其IO口对电源及对地的电阻(是由于泄漏电流引起的)不是无穷大,如果它对地及对电源的电阻大致相等,则它的电压就很有可能是接近电源的一半
 
回复 支持 反对

使用道具 举报

  • TA的每日心情
    开心
    2018-7-2 06:04
  • 签到天数: 1 天

    [LV.1]初来乍到

    59

    主题

    2888

    帖子

    10

    金牌会员

    Rank: 6Rank: 6

    积分
    5968
    最后登录
    2020-9-28
    发表于 2013-9-24 14:32:53 | 显示全部楼层

    回复:FreeDom板KL25内部ADC模块问题

    开关电源的波动是蛮大的,如果你有示波器就能很明显地看出来电压波形类似锯齿波。
     
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-26 05:02 , Processed in 0.157127 second(s), 30 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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