CCS中实时显示ADC采样波形
CCS中实时显示ADC采样波形
在DSP开发和嵌入式系统调试中,实时观察变量变化对于程序调试和系统优化至关重要。本文将详细介绍如何在CCS(Code Composer Studio)软件中使用波形显示工具,以直观地显示ADC(模数转换器)采样波形。通过实际代码示例和实验验证,帮助读者掌握这一实用技能。
显示单个变量
首先,我们来看一个简单的示例。在CCS中创建一个基于28335芯片的工程,并编写如下代码:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
int i = 0;
void main() {
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
while (1) {
i++;
if(i>=100)
i=0;
}
}
直接在循环中对变量 i
进行累加,然后用图形显示 i
的值。进入调试界面后,在变量 i
上单击鼠标右键,选择将变量添加到观察窗口中。运行程序后,在观察窗口中可以看到 i
的值一直在变化。接着在变量 i
的显示值上面,单击右键选择 Graph,就会打开一个图形显示窗口。
理论上波形应该是从0到100,然后又到0的一个锯齿波,但由于图形显示工具刷新速度较慢,而代码中 i
变化速度太快,导致显示的波形比较乱。为了解决这个问题,可以在代码中添加延时语句。
显示数组
如果不延时要实时显示的话,在这里就需要增加一个数组来存储变量的值,然后显示的时候直接从数组中取值。修改代码如下:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
int i = 0;
int buf[100];
void main() {
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
while (1) {
buf[i++]=i;
if(i>=100)
i=0;
}
}
编译运行代码,进入调试界面后选择 Tool — Graph — Single Time,设置完成后点击OK按钮。此时界面上会多出一个图形显示窗口。通过对比可以明显看出,用数组打印的曲线比较接近实际的曲线,直接打印变量的曲线没有多大的参考价值。
打印ADC采样曲线
通过上面的测试可以看出,要实时显示曲线必须要使用数组这种方式。下面将ADC采样的代码添加进来:
#include "adc.h"
void ADC_Init(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.ADCENCLK = 1; //使能ADC时钟
EDIS;
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK; //高速外设时钟HSPCLK 分频系数 2*3=6分频 150MHz/6=25MHz
EDIS;
InitAdc(); //调用系统ADC初始化函数,开启ADC时钟,内部校准,延时5ms
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS; //ADCCLK = 25MHz /(2*1) = 12.5M
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK; //ADC脉冲宽度 = (15+1)* ADCCLK周期 16个ADC clocks
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; //序列发生器工作在级联模式 SEQ为16通道
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0; //输入通道1寄存器的CONV00转换通道选择为通道0
AdcRegs.ADCTRL1.bit.CONT_RUN = 1; //连续运行模式
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x0; //一个序列内完成最大转换次数为0+1次
//回绕意思是0通过转换完成后,下一个结果依然存到0通道
//覆盖意思是0通过转换完成后,下一个结果存到1通道,依次递增存储,直到15通道之后,才返回0通道继续存储。
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 0; //0转换完成后回绕 1 转换完成后覆盖,只有在末端发生回绕
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1; //启动SEQ1序列转换
}
Uint16 Read_AdcValue(void)
{
while (AdcRegs.ADCST.bit.INT_SEQ1 == 0)
; //如果SEQ1中断事件为0 就一直等待
AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清除SEQ1中断标志INT_SEQ1
return AdcRegs.ADCRESULT0 >> 4; //返回通道0 转换结果值
}
主程序代码:
#include "DSP2833x_Device.h" // DSP2833x Headerfile Include File
#include "DSP2833x_Examples.h" // DSP2833x Examples Include File
#include "adc.h"
float value = 0.0;
int i;
float buf[100];
void main() {
InitSysCtrl();
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
ADC_Init();
while (1) {
value = (float)Read_AdcValue()*3.0/4096;
buf[i++] = value;
if (i >= 100)
i = 0;
}
}
按照上面的方法将采样值 value
和数组 buf
都添加到波形显示窗口中。使用函数发生器给AD口输入不同频率和类型的波形信号,如20Hz、50Hz的方波、三角波和正弦波等。通过波形可以看出,虽然使用数组显示波形比直接使用变量显示波形效果要好很多,但是用数组显示的波形还是有点失真,不确定是采样的问题还是这个波形显示工具的问题。
虽然这个波形显示比起示波器还差点,但是在调试代码的时候有个参考还是不错的。