问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

CCS中实时显示ADC采样波形

创作时间:
作者:
@小白创作中心

CCS中实时显示ADC采样波形

引用
CSDN
1.
https://blog.csdn.net/qq_20222919/article/details/137709564

在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的方波、三角波和正弦波等。通过波形可以看出,虽然使用数组显示波形比直接使用变量显示波形效果要好很多,但是用数组显示的波形还是有点失真,不确定是采样的问题还是这个波形显示工具的问题。

虽然这个波形显示比起示波器还差点,但是在调试代码的时候有个参考还是不错的。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号