280049M ADC模块学习记录(软件触发)

4 篇文章 0 订阅

主要记录一下,自己最近处学习的DSP的ADC模块。

(自用记录,防止遗忘!!)

采用的是软件触发,TI官方的第一个例子。

输入电压为编码器输出的2.5V的sin+、sin-、cos+、cos-电压,最后利用差分信号进行实际示波器中观察到的图形模拟。

上代码:

(可能会比较乱,因为是自己反复修改,同时添加了好几种方式来实现的。)

#include "driverlib.h"
#include "device.h"


//uint16_t adcAResult0;
//uint16_t adcAResult1;
//uint16_t adcBResult0;
//uint16_t adcBResult1;
uint16_t a1[1024] = {0};
uint16_t a2[1024] = {0};
uint16_t a3[1024] = {0};
uint16_t a4[1024] = {0};
uint16_t a5[1024] = {0};
uint16_t a6[1024] = {0};
uint16_t i = 0 ,j = 0 ;
uint16_t p = 0 ,q =0 ;
uint16_t u = 0 ,v =0 ;


void initADCs(void);
void initADCSOCs(void);


void main(void)
{
    Device_init();
    Device_initGPIO();
    Interrupt_initModule();
    Interrupt_initVectorTable();

    // 初始化ADC,初始化SOC为软件触发。
    initADCs();
    initADCSOCs();

    EINT;
    ERTM;

    while(1)
    {
        // 软件触发ADC转换。
        // Convert, wait for completion, and store results
        ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER0);
        ADC_forceSOC(ADCA_BASE, ADC_SOC_NUMBER1);
        ADC_forceSOC(ADCB_BASE, ADC_SOC_NUMBER0);
        ADC_forceSOC(ADCB_BASE, ADC_SOC_NUMBER1);
        ADC_forceSOC(ADCC_BASE, ADC_SOC_NUMBER0);
        ADC_forceSOC(ADCC_BASE, ADC_SOC_NUMBER1);

        // 等待ADC转换完成,并清除中断标志位
        while(ADC_getInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1) == false)
        {
        }
        ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

        while(ADC_getInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1)== false)
        {
        }
        ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1);

        while(ADC_getInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1) == false)
        {
        }
        ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
        //static uint16_t a1[100] = {0};
        //static uint16_t a2[100] = {0};
        //分别将采集到的结果存放至数组a1[100],a2[100]

        a1[i++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
//        if(i >= sizeof(a1) / sizeof(a1[0]))  //(400/4=100)同i>=100,此方法不用修改两处,只用将定义数组处的数组内数据随意修改即可。
        if(i >= 1024)
        {
            i=0;
//            ESTOP0;
        }

        a2[j++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
//        if(j >= sizeof(a2) / sizeof(a2[0]))
        if(j >= 1024)
        {
            j=0;
        }

        a3[p++] = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER0);
        if(p >= 1024)
        {
            p=0;
        }

        a4[q++] = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER1);
        if(q >= 1024)
        {
            q=0;
            ESTOP0;
        }

        a5[u++] = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER0);
        if(u >= 1024)
        {
            u=0;
        }

        a6[v++] = ADC_readResult(ADCCRESULT_BASE, ADC_SOC_NUMBER1);
        if(v >= 1024)
        {
            v=0;
        }
        // 储存结果
//        adcAResult0 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER0);
//        adcAResult1 = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
//        adcBResult0 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER0);
//        adcBResult1 = ADC_readResult(ADCBRESULT_BASE, ADC_SOC_NUMBER1);

        // 用于调试的软件暂停。
        // Software breakpoint. At this point, conversion results are stored in
        // adcAResult0, adcAResult1, adcBResult0, and adcBResult1.
        // Hit run again to get updated conversions.

//            ESTOP0;


        //延时20us
//        DEVICE_DELAY_US(20);

    }
}
// 初始化ADC
void initADCs(void)
{
    // ADC使用片内参考3.3V
    // Setup VREF as internal
    ADC_setVREF(ADCA_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
    ADC_setVREF(ADCB_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);
    ADC_setVREF(ADCC_BASE, ADC_REFERENCE_INTERNAL, ADC_REFERENCE_3_3V);

    // ADC时钟4分频
    // Set ADCCLK divider to /4
    ADC_setPrescaler(ADCA_BASE, ADC_CLK_DIV_4_0);
    ADC_setPrescaler(ADCB_BASE, ADC_CLK_DIV_4_0);
    ADC_setPrescaler(ADCC_BASE, ADC_CLK_DIV_4_0);

    // 设置转换结束时触发中断
    // Set pulse positions to late
    ADC_setInterruptPulseMode(ADCA_BASE, ADC_PULSE_END_OF_CONV);
    ADC_setInterruptPulseMode(ADCB_BASE, ADC_PULSE_END_OF_CONV);
    ADC_setInterruptPulseMode(ADCC_BASE, ADC_PULSE_END_OF_CONV);

    // 启动AD并延迟1ms
    // Power up the ADCs and then delay for 1 ms
    ADC_enableConverter(ADCA_BASE);
    ADC_enableConverter(ADCB_BASE);
    ADC_enableConverter(ADCC_BASE);
    DEVICE_DELAY_US(1000);
}

// 初始化ADCSOC
void initADCSOCs(void)
{
    // 采样窗口持续10个系统时钟
    // - SOC0 will convert pin A0 with a sample window of 10 SYSCLK cycles.
    // - SOC1 will convert pin A1 with a sample window of 10 SYSCLK cycles.
    //
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0, 10);
    ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN1, 10);

    // 设置中断为ADCINT1,并启用
    // Set SOC1 to set the interrupt 1 flag. Enable the interrupt and make
    // sure its flag is cleared.
    ADC_setInterruptSource(ADCA_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);
    ADC_enableInterrupt(ADCA_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCA_BASE, ADC_INT_NUMBER1);

    // 采样窗口持续10个系统时钟
    // - SOC0 will convert pin B0 with a sample window of 10 SYSCLK cycles.
    // - SOC1 will convert pin B1 with a sample window of 10 SYSCLK cycles.
    //
    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN0, 10);
    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN1, 10);

    // 设置中断为ADCINT1,并启用
    // Set SOC1 to set the interrupt 1 flag. Enable the interrupt and make
    // sure its flag is cleared.
    ADC_setInterruptSource(ADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);
    ADC_enableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1);


    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN15, 10);
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_SW_ONLY, ADC_CH_ADCIN15, 10);

    // 设置中断为ADCINT1,并启用
    // Set SOC1 to set the interrupt 1 flag. Enable the interrupt and make
    // sure its flag is cleared.
    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);
    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
}

附excle结果处理图:

这是sin与cos绘制出的圆

好了,这里来说一下我在实验中所以到的问题以及解决办法。

1. 由于起初,程序只能自动采集一次,后来就去掉了那个自动结束的语句。“ESTOP0”,增加循环。

2. 由于要采集1024个数据存放在一个数组中,因此存在寄存器内存不够的问题,可在.map文件中查看各寄存器内存使用情况,并在cmd文件中修改。

3. 发现ADCA/B/C三个模块中,A独立,B与C配置相同,若只配置B,则无法输出数字信号,须同时对C进行配置,采用其公用引脚,进行任意配置即可。

3.然后为实现采集1024个数据程序自动停止,再循环中添加了结束语句。

 4. 为使ADCA/B/C同时采样,删掉主程序中的延时。

 结束~~~

接下来想实验一下不用软件触发,用其他寄存器等触发,因为软件触发由上面的excle图中可以看出,除了没有添加滤波等外部因素外,软件触发在实现同时采样方面仍不太理想。

  • 3
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值