8543|10

1万

帖子

16

TA的资源

版主

楼主
 

LM3S811DDLLXXRR笔记之四:AD转换 [复制链接]

为了能够使用数字系统(如MCU)处理模拟信号,必须把模拟信号转换成相应的数字
信号。能够实现这种转换的电路称为ADC(Analog-to-Digital Converter,模-数转换器)。

ADC能够将连续变化的模拟电压转换成离散的数字量。

Stellaris系列ARM集成有一个10位的ADC模块,支持8个输入通道,以及一个内部温度传感器。

 

ADC模块含有一个可编程的序列发生器,可在无需控制器干涉的情况下对多个模拟输入源进行采样。

每个采样序列均对完全可配置的输入源、触发事件、中断的产生和序列优先级提供灵活的编程。

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

 ADC功能描述

Stellaris系列ARM的ADC通过使用一种基于序列(sequence-based)的可编程方法来收集采样数据,取代了传统ADC模块使用的单次采样或双采样的方法。每个采样序列均为一系列程序化的连续(back-to-back)采样,使得ADC可以从多个输入源中收集数据,而无需控制器对其进行重新配置或处理。对采样序列内的每个采样进行编程,包括对某些参数进行编程,如输入源和输入模式(差分输入还是单端输入),采样结束时的中断产生,以及指示序列最后一个采样的指示符。

1. 采样序列发生器

采样控制和数据捕获由采样序列发生器(Sample Sequencer)进行处理。所有序列发生器的实现方法都相同,不同的只是各自可以捕获的采样数目和FIFO深度。每个序列发生器可捕获的最大采样数及相应的FIFO深度。在本实现方案中,每个FIFO入口均为32位(1个字),低10位包含的是转换结果。

 ADC序列发生器的采样数和FIFO深度
序列发生器   采样数    FIFO深度
SS0               8           8
SS1               4           4
SS2               4           4
SS3               1           1

对于一个指定的采样序列,每个采样均可以选择对应的输入管脚,以及温度传感器的选择、中断使能、序列末端和差分输入模式。


当配置一个采样序列时,控制采样的方法是灵活的。每个采样的中断均可使能,这使得在必要时可在采样序列的任意位置产生中断。同样地,也可以在采样序列的任何位置结束采样。例如,如果使用序列发生器0,那么可以在第5个采样后结束并产生中断,中断也可以在第3个采样后产生。

在一个采样序列执行完后,可以利用函数ADCSequenceDataGet( )从ADC采样序列FIFO里读取结果。上溢和下溢可以通过函数ADCSequenceOverflow( )和ADCSequenceUnderflow( )进行控制。


2. 模块控制
在采样序列发生器的外面,控制逻辑的剩余部分负责对中断产生、序列优先级设置和触发配置等任务。

大多数的ADC控制逻辑都是14~18MHz的ADC时钟速率下运行。当选择了系统XTAL时,内部的ADC分频器通过硬件自动配置。自动时钟分频器的配置对所有Stellaris系列ARM均以16.667MHz操作频率为目标。

3. 中断
采样序列发生器虽然会对引起中断的事件进行检测,但它们不控制中断是否真正被发送到中断控制器。ADC模块的中断信号由相应的状态位来控制。ADC中断状态分为原始的中断状态和屏蔽的中断状态,这可以通过函数ADCIntStatus( )来查知。函数ADCIntClear( )可以清除中断状态。

4. 优先级设置
当同时出现采样事件(触发)时,可以将为这些事件设置优先级,安排它们的处理顺序。优先级值的有效范围是0到3,其中0代表优先级最高,而3代表优先级最低。优先级相同的多个激活采样序列发生器单元不会提供一致的结果,因此软件必须确保所有激活采样序列发生器单元的优先级是唯一的。

5. 采样事件
采样序列发生器可以通过多种方式激活,如处理器(软件)、定时器、模拟比较器、PWM、GPIO。对于某些型号如LM3S1138并不存在专门的硬件PWM模块,因此也不会存在PWM触发方式。外部的外设触发源随着Stellaris家族成员的变化而改变,但所有器件都公用“控制器”和“一直(Always)”触发器。软件可通过函数ADCProcessorTrigger( )来启动采样。
在使用“一直(Always)”触发器时必须非常小心。如果一个序列的优先级太高,那么可能会忽略(starve)其它低优先级序列。

6. 硬件采样平均电路
使用硬件平均电路可产生具有更高精度的结果,然而结果的改善是以吞吐量的减小为代价的。硬件平均电路可累积高达64个采样值并进行平均,从而在序列发生器FIFO中形成一个数据入口。吞吐量根据平均计算中的采样数而相应地减小。例如,如果将平均电路配置为对16个采样值进行平均,则吞吐量也减小了16因子(factor)。
平均电路默认是关闭的,因此,转换器的所有数据直接传送到序列发生器FIFO中。进行平均计算的硬件由相关的硬件寄存器进行控制。ADC中只有一个平均电路,所有输入通道(不管是单端输入还是差分输入)都是接收相同数量的平均值。

7. 模数转换器
转换器本身会为所选模拟输入产生10位输出值。通过某些特定的模拟端口,输入的失真可以降到最低。转换器必须工作在16MHz左右,如果时钟偏差太多,则会给转换结果带来很大误差。

8. 差分采样
除了传统的单边采样(single-ended sampling)外,ADC模块还支持两个模拟输入通道的差分采样(differential Sampling)。
当队列步(a sequence step)被配置为差分采样,会形成4个差分对(differential pairs)之一,编号0~3。差分对0采样模拟输入0和1,差分对1采样模拟输入2和3,依此类推。ADC不会支持其它差分对形式,比如模拟输入0跟模拟输入

 

3。差分对所支持的编号有赖于模拟输入的编号(详见表1.2)。

差分对   模拟输入

0           0和1
1           2和3
2           4和5
3           6和7
在差分模式下被采样的电压是奇数和偶数通道的差值,即:
ΔV = VIN_ENEN - VIN_ODD
其中ΔV是差分电压,VIN_EVEN是偶数通道,VIN_ODD是奇数通道。因此:
􀂄 如果ΔV = 0,则转换结果 = 0x1FF
􀂄 如果ΔV > 0,则转换结果 > 0x1FF(范围在0x1FF~0x3FF)
􀂄 如果ΔV < 0,则转换结果 < 0x1FF(范围在0~0x1FF)

 

好了,理论讲完了,我的例子调通了也不太容易,我用了两个晚上在琢磨,终于搞定哈

 

大家注意两点:

 

      一、不管你用什么作为主时钟源,频率毕需大于16MHZ

      二、采样序列完全可配成深度为1,就象以前用51单片机一样的AD转换

 

我这个例子,没有输出,但我用仿真读出值为0x00000665转换成电压后为1637

就是1.637伏,我用胜利表量下,真准啊

 

       拿出分享哈!!!!!!

 

 

上程序:

 

 

等明后天调一下输出再分享个哈:

 

 

#include <LM3Sxxx.H>
#include <systick.h>  


#include <adc.h>
#include <stdio.h>
#define ADCSequEnable ADCSequenceEnable
#define ADCSequDisable ADCSequenceDisable
#define ADCSequConfig ADCSequenceConfigure
#define ADCSequStepConfig ADCSequenceStepConfigure
#define ADCSequDataGet ADCSequenceDataGet
tBoolean ADC_EndFlag = false; // 定义ADC转换结束的标志
//unsigned long TheSysClock;


//  防止JTAG失效
void jtagWait(void)
{
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOC);          //  使能KEY所在的GPIO端口
GPIOPinTypeGPIOInput(GPIO_PORTC_BASE,GPIO_PIN_4);     //  设置KEY所在管脚为输入
if (GPIOPinRead(GPIO_PORTC_BASE,GPIO_PIN_4) == 0x00)  //  若复位时按下KEY,则进入
    {
       while(1);                             //  死循环,以等待JTAG连接
    }
  SysCtlPeripheralDisable(SYSCTL_PERIPH_GPIOC);   //  禁止KEY所在的GPIO端口
}
// ADC初始化
void adcInit(void)
{
SysCtlLDOSet(SYSCTL_LDO_2_75V);    //配置PLL前需将LDO电压设置为2.75V                   
        SysCtlClockSet(SYSCTL_USE_PLL |    // 系统时钟设置,采用PLL                         
        SYSCTL_OSC_MAIN |                  // 主振荡器         
  SYSCTL_XTAL_6MHZ |                 // 外接6MHz晶振        
  SYSCTL_SYSDIV_4);        // 分频结果为50MHz


SysCtlPeripheralEnable(SYSCTL_PERIPH_ADC); // 使能ADC模块
SysCtlADCSpeedSet(SYSCTL_ADCSPEED_125KSPS); // 设置ADC采样速率
ADCSequDisable(ADC_BASE, 0); // 配置前先禁止采样序列
// 采样序列配置:ADC基址,采样序列编号,触发事件,采样优先级
ADCSequConfig(ADC_BASE, 0, ADC_TRIGGER_PROCESSOR, 0);
// 采样步进设置:ADC基址,采样序列编号,步值,通道设置
ADCSequStepConfig(ADC_BASE, 0, 0, ADC_CTL_CH0 |
ADC_CTL_END |
ADC_CTL_IE);
ADCIntEnable(ADC_BASE, 0); // 使能ADC中断
IntEnable(INT_ADC0); // 使能ADC采样序列中断
IntMasterEnable( ); // 使能处理器中断
ADCSequEnable(ADC_BASE, 0); // 使能采样序列
}
// ADC采样
unsigned long adcSample(void)
{
unsigned long ulValue;
ADCProcessorTrigger(ADC_BASE, 0); // 处理器触发采样序列
while (!ADC_EndFlag); // 等待采样结束
ADC_EndFlag = false; // 清除ADC采样结束标志
ADCSequDataGet(ADC_BASE, 0, &ulValue); // 读取ADC转换结果
return(ulValue);
}
// 主函数(程序入口)
int main(void)
{
unsigned long ulVal;
char cBuf[30];
jtagWait( ); // 防止JTAG失效,重要!

SysTickEnable( ); // 使能SysTick计数器
adcInit( ); // ADC初始化
for (;;)
{
ulVal = adcSample( ); // ADC采样
ulVal = (ulVal * 3000) / 1024; // 转换成电压值
//sprintf(cBuf, "ADC0 = %ld(mV)\r\n", ulVal); // 输出格式化
//uartPuts(cBuf); // 通过UART显示结果
SysCtlDelay(1500 * (SysTickValueGet( ) / 3000)); // 延时约1500ms
}
}
// ADC采样序列0的中断
void ADC_Sequence_0_ISR(void)
{
unsigned long ulStatus;
ulStatus = ADCIntStatus(ADC_BASE, 0, true); // 读取中断状态
ADCIntClear(ADC_BASE, 0); // 清除中断状态,重要
if (ulStatus != 0) // 如果中断状态有效
{
ADC_EndFlag = true; // 置位ADC采样结束标志
}
}


 

打包上传:

 

myADC.zip (1.52 KB, 下载次数: 97)

 

 

 

 

 

 

 

 

最新回复

10年前的内容了,,,这咋挖出来的?   详情 回复 发表于 2021-4-23 15:36

点评

请问楼主,你程序中选了序列发生器0的,它是支持八个采样数,为什么只设置了一个输入通道?是否会在那一个通道采样八次还是就采样一次?另外,中断信号是由什么事件触发的?。。 PS:我还想问一下,那个一直采样触  详情 回复 发表于 2012-9-1 18:15
 
点赞 关注(1)
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr

回复
举报

7183

帖子

195

TA的资源

五彩晶圆(高级)

沙发
 
版主 请问下 串口显示  怎么注释了呢 那这个AD转换如何显示呢
 
 

回复

1万

帖子

16

TA的资源

版主

板凳
 

我都说明了,板凳你没认真看

我用仿真器仿地,至于输出么,我根本不想用串口输出,我想输出到我地5110上,我明天调,今天休息,累死我了
 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

回复

4138

帖子

0

TA的资源

五彩晶圆(中级)

4
 
不错,支持嘿嘿
 
 
 

回复

10

帖子

0

TA的资源

一粒金砂(中级)

5
 

AD

请问版主,AD的序列号是什么意思?FIFO又是什么意思
 
 
 

回复

58

帖子

0

TA的资源

一粒金砂(高级)

6
 

回复 5楼 尘封的熊猫 的帖子

FIFO 指的是队列
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(中级)

7
 

回复 楼主 ddllxxrr 的帖子

请问楼主,你程序中选了序列发生器0的,它是支持八个采样数,为什么只设置了一个输入通道?是否会在那一个通道采样八次还是就采样一次?另外,中断信号是由什么事件触发的?。。
PS:我还想问一下,那个一直采样触发事件设置为一直采样是什么情况?是隔多少时间进行采样?
假如我想要在一个通道上连续多次采样,是否可以选用序列3,然后,循环进行AD转换?还是可以选择一直采样?
我之前只接触过最普通的AD,序列器的还是第一次见,完全不懂,求指导!谢谢!!
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(中级)

8
 
 
 
 

回复

1

帖子

0

TA的资源

一粒金砂(初级)

9
 

不懂

 
 
 

回复

7504

帖子

2

TA的资源

五彩晶圆(高级)

10
 

10年前的内容了,,,这咋挖出来的?

点评

鬼才知道  详情 回复 发表于 2021-4-23 20:24
 
个人签名

默认摸鱼,再摸鱼。2022、9、28

 
 

回复

1万

帖子

16

TA的资源

版主

11
 
freebsder 发表于 2021-4-23 15:36 10年前的内容了,,,这咋挖出来的?

鬼才知道

 
个人签名http://shop34182318.taobao.com/
https://shop436095304.taobao.com/?spm=a230r.7195193.1997079397.37.69fe60dfT705yr
 
 

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

随便看看
查找数据手册?

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
快速回复 返回顶部 返回列表