5332|9

81

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

LM3开发笔记_5.ADC采集 [复制链接]

       由于项目需要监测一些模拟量所以要用到ADC,这两天试了试LM3S8962的ADC功能,有一些收获,不敢独享和拿出来和大家分享。

 

       ADC用于将连续变化的模拟电压转换成离散的数字量。LM3S8962集成有一个 10 位的 ADC 模块,支持 8 个输入通道,以及一个内部温度传感器。ADC 模块含有一个可编程的序列发生器,可在无需控制器干涉的情况下对多个模拟输入源进行采样。每个采样序列均对完全可配置的输入源、触发事件、中断的产生和序列优先级提供灵活的编程。

 

       Stellaris系列的ADC 模块提供系列特性:
   8 个模拟输入通道 
   单端和差分输入配置; 
   内部温度传感器; 
   高达 1Msps(每秒采样一百万次)的采样率;
   4个可编程的采样转换序列, 入口长度1到8, 每个序列均带有相应的转换结果FIFO; 
   灵活的触发控制:处理器(软件) 、定时器、模拟比较器、PWM、GPIO; 
   硬件可对多达 64 个采样值进行平均计算(牺牲速度换取精度); 
   转换器采用内部的 3V参考电压; 
   分开的模拟电源和模拟地,跟数字电源和数字地分离。

 

       直接上示例程序:

 

//ADC初始化
void ADC_Init(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC); //使能ADC模块
    SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS); //设置ADC采样速率
    ADCSequenceDisable(ADC_BASE, 3);   //配置前先禁止采样序列 
 
    //采样序列配置:ADC基址,采样序列编号,触发事件,采样优先级
    ADCSequenceConfigure(ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);
 
    //采样步进设置:ADC基址,采样序列编号,步值,温度传感器|中断使能
    ADCSequenceStepConfigure(ADC_BASE, 3, 0, ADC_CTL_TS|ADC_CTL_END|ADC_CTL_IE);


    //使能采样序列
    ADCSequenceEnable(ADC_BASE, 3);

}

 

//ADC查询采样
unsigned long ADC_Sample(void)
{
    unsigned long ulValue;
 
    ADCProcessorTrigger(ADC_BASE, 3);   //处理器触发采样序列
    while(!ADCIntStatus(ADC_BASE, 3, false)); //等待采样结束

    ADCSequenceDataGet(ADC_BASE, 3, &ulValue);  //读取ADC转换结果
 
    return(ulValue);
}

 

//温度发送到串口
void SendCelsius(unsigned long ulValue)
{
 unsigned long ulTmp;
 ulTmp = 151040UL - 225*ulValue;
 
 printf("Temperature=%d.%d\n", ulTmp/1024, (ulTmp % 1024) / 102);
}

 

int main(void)
{
    unsigned long ulValue;
 
    SysCtlClockSet(SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_8MHZ|SYSCTL_SYSDIV_4); //50MHz


    ADC_Init();
 
    //while
    while(1)
    {
      ulValue=ADC_Sample();
      SendCelsius(ulValue);
      Delay_nMS(1000);
    }
}

 

       由于手上没有合适的信号源,就把ADC配置为内部温度传感器,采用扫描的方式进行采样.

      

       ADC采样值和温度的关系如下:       T =(151040 -  225 ×  N )/  1024

       ADC 配置为温度传感器模式后,只要得到 10 位采样值N,就能推算出摄氏温度T。

 

 

 

从串口收到的数据来看,有一些跳动应该是ADC的±1 个 LSB造成的。

[ 本帖最后由 liongt 于 2010-11-17 21:10 编辑 ]

最新回复

想请问一下楼主,,为什么我测得的温度总在30度左右,无论环境温度和芯片温度的变化,,测得的温度变化不大,我不知道是不是程序的问题  详情 回复 发表于 2011-7-27 20:24
 
点赞 关注

回复
举报

81

帖子

0

TA的资源

一粒金砂(中级)

沙发
 

上面的例子用的是扫描方式,中断方式也很简单,只要把ADC配置函数改一下,再加上ADC中断服务函数就行了。

 

//ADC初始化
void ADC_Init(void)
{
    SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC); //使能ADC模块
    SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS); //设置ADC采样速率

    //采样序列配置:ADC基址,采样序列编号,触发事件,采样优先级
    ADCSequenceConfigure(ADC_BASE, 3, ADC_TRIGGER_PROCESSOR, 0);

    //采样步进设置:ADC基址,采样序列编号,步值,温度传感器|中断使能
    ADCSequenceStepConfigure(ADC_BASE, 3, 0, ADC_CTL_TS|ADC_CTL_END|ADC_CTL_IE);

    //硬件过采样配置
    ADCHardwareOversampleConfigure(ADC_BASE, 16);

    ADCIntEnable(ADC_BASE, 3); //使能ADC中断
    IntEnable(INT_ADC3);  //使能ADC采样序列中断
    IntMasterEnable();   //使能处理器中断

    ADCSequenceEnable(ADC_BASE, 3); //使能采样序列
}

 

//ADC采样
unsigned long ADC_Sample(void)
{
    unsigned long ulValue;
 
    ADCProcessorTrigger(ADC_BASE, 3);   //处理器触发采样序列
    while (!ADC_EndFlag);                       //等待采样结束
    ADC_EndFlag = false;                        //清除ADC采样结束标志
    ADCSequenceDataGet(ADC_BASE, 3, &ulValue);  //读取ADC转换结果
 
    return(ulValue);
}

 

//ADC采样序列3的中断
void ADC_Sequence_3_ISR(void)
{
    unsigned long ulStatus;
 
    ulStatus = ADCIntStatus(ADC_BASE, 3, true);             //  读取中断状态
    ADCIntClear(ADC_BASE, 3);                               //  清除中断状态
 
    if (ulStatus != 0)                                      //  如果中断状态有效
    {
        ADC_EndFlag = true;                                 //  置位ADC采样结束标志
    }
}

 

为了消除ADC ±1 个 LSB误差造成的影响,可以使用硬件平均或软件平均的处理方法,固件库对应的函数分别是

 

void ADCHardwareOversampleConfigure(unsigned long ulBase, unsigned long ulFactor)

ulBase:ADC模块的基址,取值ADC_BASE
ulFactor:采样平均数,取值2、4、8、16、32、64,如果取值0则禁止硬件过采样

 

void ADCSoftwareOversampleConfigure(unsigned long ulBase,  unsigned long ulSequenceNum, 
unsigned long ulFact)

 

ulBase:ADC模块的基址,取值ADC_BASE
ulSequenceNum:ADC采样序列的编号,取值0、1、2(采样序列3不支持软件过采样)
ulFactor:采样平均数,取值2、4、8

 

 

从串口收到的数据来看,改为硬件平均后,采样值稳定了很多。

 

[ 本帖最后由 liongt 于 2010-11-17 21:20 编辑 ]
 
 

回复

545

帖子

0

TA的资源

一粒金砂(高级)

板凳
 
学习了,不错
 
 
 

回复

978

帖子

0

TA的资源

一粒金砂(高级)

4
 
技术贴,呵呵
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(中级)

5
 
学习了 很不错!!
 
个人签名机遇总是给有准备的人呢
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

6
 
printf("Temperature=%d.%d\n", ulTmp/1024, (ulTmp % 1024) / 102);
可否解释一下?
 
 
 

回复

918

帖子

0

TA的资源

纯净的硅(中级)

7
 
 
 
 

回复

81

帖子

0

TA的资源

一粒金砂(中级)

8
 
ding
 
 
 

回复

41

帖子

0

TA的资源

一粒金砂(中级)

9
 
非常感谢LZ  呵呵
 
 
 

回复

146

帖子

0

TA的资源

一粒金砂(高级)

10
 
想请问一下楼主,,为什么我测得的温度总在30度左右,无论环境温度和芯片温度的变化,,测得的温度变化不大,我不知道是不是程序的问题
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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

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

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

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