当前位置:首页 > 电源 > 数字电源
[导读] 例1 利用驱动库函数的8x过采样代码段1.a ADC配置-驱动库函数// // 初始化ADC,使用定序器0对通道1进行8x过采样// 定序器将被其中一个通用定时器触发// ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 0);

 

1 利用驱动库函数的8x过采样
代码段1.a ADC配置-驱动库函数
//
// 初始化ADC,使用定序器0对通道1进行8x过采样
// 定序器将被其中一个通用定时器触发
//
ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 0);
ADCSoftwareOversampleConfigure(ADC_BASE, 0, 8);
ADCSoftwareOversampleStepConfigure(ADC_BASE, 0, 0, (ADC_CTL_CH1
| ADC_CTL_IE | ADC_CTL_END));
//
// 初始化定时器0,每隔10ms触发一次ADC转换
//
TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 100);
TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
代码段1.aADC配置表示在采样完成时产生一个中断,这样就必须具有中断处理程序(见代码段1.b)。驱动库的过采样函数自动将采样的数据进行平均,因此,中断处理函数相对来说也是很基础的。但要记住:要将每次中断中计算的平均值和计算的开销提供给中断处理程序。
代码段1.b ADC中断处理程序
void
ADCIntHandler(void)
{
long lStatus;
//
// 清除ADC中断
//
ADCIntClear(ADC_BASE, 0);
//
// 获得ADC的平均数据
//
lStatus = ADCSoftwareOversampleDataGet(ADC_BASE, 0, &g_ulAverage);
//
// 占位符,供ADC处理数据
//
}
在将配置步骤和中断处理程序放在适当位置后,启动转换处理。定时器打开(开始计数)之前,ADC定序器和中断必须使能(见代码段1.c)。
代码段1.c 使能ADC和中断
//
// 使能ADC定序器0及其中断 (ADCNVIC)
//
ADCSequenceEnable(ADC_BASE, 0);
ADCIntEnable(ADC_BASE, 0);
IntEnable(INT_ADC0);
//
//使能定时器并启动转换处理
//
TimerEnable(TIMER0_BASE, TIMER_A);
使用多个定序器或一个定时器实现大于8倍的过采样
驱动库的过采样函数最大只能进行8倍过采样(根据采样定序器的硬件限制),因此需要更大过采样因子的应用必须使用其它的实现。本小节将描述如何使用下面的两种方法:在过采样频率下运行的多个采样定序器和一个定时器来解决这个问题。
2:使用多个采样定序器的16x过采样
采样定序器的灵活性允许对其进行多种配置。将采样定序器0-2累积起来可获得16个采样(8+4+4),因此使用采样定序器0-2可实现16倍过采样。为使该级别的过采样能够工作,定序器中的所有阶段必须设置为对相同的模拟输入进行采样,这意味着丢弃了使用一个定序器采样多个输入的功能。
代码段2.a使用定序器0-2配置一个10ms的周期转换。使用一个定时器触发就可启动所有3个定序器的采样操作,而无需复杂的触发配置。为获得所需的结果,要对采样定序器的优先级进行配置,这样,采样定序器2的优先级最低(即它最后采样),并且在采样定序器2的最后一步之后,配置为发出一个转换结束中断。
代码段2.a ADC配置-多个采样定序器
//
// 初始化ADC,以便使用定序器0-2对通道1进行16x过采样
// 转换操作通过GPTM触发
//
ADCSequenceConfigure(ADC_BASE, 0, ADC_TRIGGER_TIMER, 0);
ADCSequenceConfigure(ADC_BASE, 1, ADC_TRIGGER_TIMER, 1);
ADCSequenceConfigure(ADC_BASE, 2, ADC_TRIGGER_TIMER, 2);
//
// 配置定序器0的序列步骤(sequence step
//
ADCSequenceStepConfigure(ADC_BASE, 0, 0, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 0, 1, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 0, 2, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 0, 3, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 0, 4, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 0, 5, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 0, 6, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 0, 7, (ADC_CTL_CH1 | ADC_CTL_END));
//
//配置定序器1的序列步骤
//
ADCSequenceStepConfigure(ADC_BASE, 1, 0, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 1, 1, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 1, 2, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 1, 3, (ADC_CTL_CH1 | ADC_CTL_END));
//
//配置定序器2的序列步骤
//
ADCSequenceStepConfigure(ADC_BASE, 2, 0, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 2, 1, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 2, 2, ADC_CTL_CH1);
ADCSequenceStepConfigure(ADC_BASE, 2, 3, (ADC_CTL_CH1 | ADC_CTL_IE
| ADC_CTL_END));
//
// 初始化定时器0,每隔10ms触发一次ADC转换
//
TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 100);
TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
在代码段2.b中,中断处理程序必须收集FIFO的数据并进行平均计算。因为不需要处理函数开销就可以获得所需的结果,所以不使用ADCSequenceDataGet函数,并且使用直接的寄存器读操作来清空定序器的FIFO。而使用ADCSequenceDataGet时,要求函数定义一个额外的8入口采样缓冲区,即使使用直接的寄存器读操作,中断处理程序中执行的总和计算和平均计算仍然会有可计算的开销。
代码段2.b ADC中断处理程序
void
ADCIntHandler(void)
{
unsigned long ulIdx;
unsigned long ulSum = 0;
//
// 清除中断
//
ADCIntClear(ADC_BASE, 2);
//
// 获得来自定序器0的数据
//
for(ulIdx = 8; ulIdx; ulIdx--)
{
ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO0);
}
//
// 获得来自定序器12的数据
//
for(ulIdx = 4; ulIdx; ulIdx--)
{
ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO1);
ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO2);
}
//
// 将过采样的数据进行平均
//
g_ulAverage = ulSum >> 4;
//
// 占位符,以便ADC处理代码
//
}
在启动转换处理之前,将采样定序器和中断使能(见代码段2.c)。
代码段2.c 使能ADC和中断
//
// 使能定序器和中断
//
ADCSequenceEnable(ADC_BASE, 0);
ADCSequenceEnable(ADC_BASE, 1);
ADCSequenceEnable(ADC_BASE, 2);
ADCIntEnable(ADC_BASE, 2);
IntEnable(INT_ADC2);
//
// 使能定时器并启动转换处理
//
TimerEnable(TIMER0_BASE, TIMER_A);
3 使用在fOS下运行的定时器进行16x过采样
另一个实现16x过采样的方法(无需消耗ADC定序器的大部分资源)是使用一个在过采样频率下运行的周期定时器。例如,如果转换处理每10ms必须返回到主应用程序并且即将进行16倍过采样,则能够将定时器配置为每625µs获得一个采样值。让定时器在过采样频率下触发一次转换明显地产生了额外的ADC中断,这必须在应用程序中说明。
ADC和定时器配置为执行上述操作的代码见代码段3.a
代码段3.a ADC配置-在fOS下运行的定时器
//
// 初始化ADC,以便在检测到一次触发时在通道1、定序器3上获得一个采样值。
// 
//
ADCSequenceConfigure(ADC_BASE, 3, ADC_TRIGGER_TIMER, 0);
ADCSequenceStepConfigure(ADC_BASE, 3, 0, (ADC_CTL_CH1 | ADC_CTL_IE
| ADC_CTL_END));
//
//初始化定时器0,每625µs触发一次ADC转换
//
TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 1600);
TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
既然ADC在过采样频率下进行采样操作,中断处理程序必须知道已获得的采样数以及总和(见代码段3.b)。在累积了16次转换后,将这16个采样值进行平均,并清除全局采样计数变量和总和变量。
代码段3.b ADC中断处理程序
void
ADCIntHandler(void)
{
//
// 清除中断
//
ADCIntClear(ADC_BASE, 3);
//
// 将新的采样值加到全局总和中
//
g_ulSum += HWREG(ADC_BASE + ADC_O_SSFIFO3);
//
// g_ucOversampleCnt1
//
g_ucOversampleCnt++;
//
// 如果累积了16个采样值,则将它们平均并将全局变量复位
//
if(g_ucOversampleCnt == 16)
{
g_ulAverage = g_ulSum >> 4;
g_ucOversampleCnt = 0;
g_ulSum = 0;
}
//
// 占位符,以便ADC处理代码
//
}
最后,在使能定时器之前,将定序器3及其中断使能,并清除全局计数器和总和变量(见代码段3.c)。
代码段3.c 使能ADC、中断并清除全局变量
//
// 使能定序器和中断
//
ADCSequenceEnable(ADC_BASE, 3);
ADCIntEnable(ADC_BASE, 3);
IntEnable(INT_ADC3);
//
// 将过采样计数器和总和变量清零
//
g_ucOversampleCnt = 0;
g_ulSum = 0;
//
// 使能定时器并启动转换处理
//
TimerEnable(TIMER0_BASE, TIMER_A);
使用滑动平均进行过采样
当采样频率接近ADC的最大采样率时,滑动平均非常有用。滑动平均应用中的主要元件是采样缓冲区,它在每次转换完成时减去/加上数据。
4ADC配置为每隔100µs进行一次采样,采样缓冲区含有16个入口。注意:应用程序不向采样缓冲区预先填充有效的数据,这样,前16个采样值必须相应地由软件来处理。ADC配置为在定时器触发时采样,并在每次转换之后将处理器中断。
4 使用滑动平均每100µs过采样
代码段4.a ADC配置-滑动平均
//
// 初始化ADC,以便在检测到触发时在通道1、定时器3上获得一个采样值。
// 
//
ADCSequenceConfigure(ADC_BASE, 3, ADC_TRIGGER_TIMER, 0);
ADCSequenceStepConfigure(ADC_BASE, 3, 0, (ADC_CTL_CH1 | ADC_CTL_IE
| ADC_CTL_END));
//
// 初始化定时器0,每100µs触发一次ADC转换
//
TimerConfigure(TIMER0_BASE, TIMER_CFG_32_BIT_PER);
TimerLoadSet(TIMER0_BASE, TIMER_A, SysCtlClockGet() / 10000);
TimerControlTrigger(TIMER0_BASE, TIMER_A, true);
中断处理程序必须更新采样缓冲区并进行平均计算(见代码段4.b)。在每次ADC中断时,去掉采样缓冲区中的最后一个元素,缓冲区中剩下的数据移动一个位置。然后,在计算平均值之前将新的转换结果放在采样缓冲区的开始处。中断处理程序中执行的额外计算又一次增加了开销,这一点必须要考虑到。
代码段4.b ADC中断处理程序
void
ADCIntHandler(void)
{
//
// 清除中断
//
ADCIntClear(ADC_BASE, 3);
//
// 检查g_ucOversampleIdx,确保它的值在范围内
//
if(g_ucOversampleIdx == 16)
{
g_ucOversampleIdx = 0;
}
//
// 从全局总和中减去最早的值
//
g_ulSum -= g_ulSampleBuffer[g_ucOversampleIdx];
//
// 用新的采样值代替最早的值
//
g_ulSampleBuffer[g_ucOversampleIdx] = HWREG(ADC_BASE + ADC_O_SSFIFO3);
//
// 将新的采样值加到总和中
//
g_ulSum += g_ulSampleBuffer[g_ucOversampleIdx];
//
// g_ucOversampleIdx1
//
g_ucOversampleIdx++;
//
// 从采样缓冲区的数据中获得平均值
//
g_ulAverage = g_ulSum >> 4;
//
// 占位符,供ADC处理代码
//
}
在启动定时器之前,使能定时器及其中断(见代码段4.c)。
代码段4.c 使能ADC和中断
//
// 使能定序器和中断
//
ADCSequenceEnable(ADC_BASE, 3);
ADCIntEnable(ADC_BASE, 3);
IntEnable(INT_ADC3);
//
// 使能定时器并启动转换处理
//
TimerEnable(TIMER0_BASE, TIMER_A);
需考虑的问题
本文档中描述的过采样技术需要额外的代码来执行平均计算,附加中断,和/或大部分采样定序器资源,因此它在整个系统性能上有一个显著的影响。在选择最适合应用的技术时,需在增加的中断和庞大的中断处理程序之间进行权衡。
结论
Luminary Micro的采样定序器结构为过采样技术的实现提供了大量的选项。当与软件平均技术相结合时,该结构能够使系统设计人员有效地在采样频率、系统性能和采样解决方案之间进行权衡。
本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

【2024年5月13日,德国慕尼黑和斯图加特讯】随着汽车行业向软件定义汽车和新E/E架构过渡,市场对高性能硬件和强大网络安全解决方案的需求也逐渐增加。为满足这一需求,全球功率系统和物联网领域的半导体领导者英飞凌科技股份公...

关键字: 微控制器 半导体 物联网

本文针对电动两轮车自燃防控装置的开发与分析进行了研究。通过电动两轮车自燃原因分析,提出了电动两轮车的自燃防控智能装置设计思路,介绍了电动两轮车的自燃防控智能

关键字: STC89C52RC 单片机 微控制器

5月8日,中星联华技术支持总监苏水金给带来《精密测试关键技术大揭秘!》,详解中星联华超低相噪微波信号源的6大核心特色,助您快速精准测试,解决尖端测试的苛刻要求。

关键字: ADC 自动编程 相噪

【2024年5月9日,德国慕尼黑讯】信息安全与功能安全在汽车行业发挥着日益重要的作用,即便在低端微控制器应用中也不例外。与此同时,汽车制造商正在用触摸表面取代机械按钮,实现简洁的驾驶舱和方向盘。因此,电子电路的空间受到很...

关键字: 物联网 电子电路 微控制器

【2024年5月8日,德国慕尼黑讯】Rust编程语言凭借其独特的内存安全特性,已经成为汽车软件开发中C/C++的有效补充和潜在替代品。全球功率系统和物联网领域的半导体领导者英飞凌科技股份公司(FSE代码:IFX / OT...

关键字: 编译器 微控制器

2024年5月6日 – 专注于引入新品的全球电子元器件和工业自动化产品授权代理商贸泽电子 (Mouser Electronics) 即日起开售Analog Devices, Inc. (ADI) 的MAX32690微控制...

关键字: 可穿戴设备 微控制器 片上系统

【2024年4月29日, 德国慕尼黑讯】嵌入式安全被认为是物联网(IoT)应用部署的一个重要属性。英飞凌科技股份公司(FSE代码:IFX / OTCQX代码:IFNNY)近日宣布,其新型PSOC™ Edge E8x MC...

关键字: 微控制器 MCU 物联网

2024年4月26日,中国 – 服务多重电子应用领域、全球排名前列的半导体公司意法半导体 (STMicroelectronics,简称ST;纽约证券交易所代码:STM) 公布了按照美国通用会计准则 (U.S. GAAP)...

关键字: 微控制器 模拟器件

利用LogiCoA™微控制器,以更低功耗实现与全数字控制电源同等的功能

关键字: 微控制器 电源 CPU

台湾新竹 – 2024年4月23日 – 著名的微控制器供货商新唐科技公司,与全软件开发生命周期提供跨平台解决方案的全球软件公司Qt Group宣布深化合作,扩展新唐科技人机界面(HMI)平台支持「Qt for MCUs」...

关键字: 微控制器 嵌入式系统 MCU
关闭
关闭