F280049M ADC外部触发GPIO(改进)

4 篇文章 0 订阅
本文档介绍了一段基于DSP的程序,该程序通过配置GPIO输入输出,利用上升沿触发ADC进行数据采集。程序中初始化了ADC、SOC和GPIO,并在中断服务函数中处理XINT2中断,实现了1024次数据采集。在中断处理过程中避免了延时函数和死循环,确保了ADC转换的正常进行。同时,程序还包括了对GPIO翻转的处理,以触发新的ADC转换。
摘要由CSDN通过智能技术生成

对之前的手动上电进行了优化改进,配置了两个GPIO输入输出,外部硬件进行连接,从而实现输出给输入供电。采集1024个数据。

程序框架理解:

先进入主函数,对外设及设备时钟等初始化;ADC、SOC、GPIO初始化,GPIO1上升沿触发XINT2,计数加一;进while循环;ADC开始转化一次,结果存放至ADCRESULT寄存器中,再放至数组;然后翻转函数TOGGLE翻转GPIO1变为低电平,延时2ms,再变为高电平;XINT2再次触发,计数加一;ADC开始转化一次,结果存放至ADCRESULT寄存器中,再放至数组。and so on.

转换至1024个数据时跳出循环,程序结束。

(本人刚开始接触DSP,还有很多不懂的地方,欢迎各位大佬只进行指点   ///~-~\\\)


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

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 initExintGPIO(void);
interrupt void xint2ISR(void);

int testCount=0;

void main(void)
{
    Device_init();                                       //初始化设备时钟和外设
    Device_initGPIO();                                   //禁用引脚锁并启用内部上拉
    Interrupt_initModule();                              //初始化PIE并清除PIE寄存器。禁用CPU中断。
    Interrupt_initVectorTable();                         //用指向shell中断的指针初始化PIE向量表ISR服务程序。

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

    EINT;                                                //打开全局中断
    ERTM;                                                //当使用仿真器调试时 开启DEBUG中断

    while(1)
    {

        // 等待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);

        // 储存结果
        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;
        }

        a2[j++] = ADC_readResult(ADCARESULT_BASE, ADC_SOC_NUMBER1);
        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;
        }

        GPIO_togglePin(1);
        DEVICE_DELAY_US(2000);
        GPIO_togglePin(1);

    }
}

// 初始化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);  //在ADC转换前要延迟一段时间
}

void initExintGPIO(void)
{

    Interrupt_register(INT_XINT2, &xint2ISR);
    Interrupt_enable(INT_XINT2);                     // 使能 XINT2 中断

    GPIO_setPinConfig(GPIO_15_GPIO15);               // GPIO15 复用为GPIO功能
    GPIO_setDirectionMode(15, GPIO_DIR_MODE_IN);     // GPIO15 设置为输入
    GPIO_setQualificationMode(15, GPIO_QUAL_SYNC);   //GPIO15 的时钟周期同系统时钟周期

    GPIO_writePin(1, 0);                             //GPIO1 为输出。从低电平开始
    GPIO_setPinConfig(GPIO_1_GPIO1);
    GPIO_setDirectionMode(1, GPIO_DIR_MODE_OUT);

    GPIO_setInterruptPin(15, GPIO_INT_XINT2);                             // XINT2 connected to GPIO15

//    GPIO_setInterruptType(GPIO_INT_XINT2, GPIO_INT_TYPE_FALLING_EDGE);  //下降沿
    GPIO_setInterruptType(GPIO_INT_XINT2, GPIO_INT_TYPE_RISING_EDGE);     // XINT2 对应GPIO 15 ,上升沿触发(因为电压起初是低电平)
    GPIO_enableInterrupt(GPIO_INT_XINT2);                                 //使能XINT2 中断

    GPIO_writePin(1, 1);       // Raise GPIO1, trigger XINT2

}

interrupt void xint2ISR(void)
{
    testCount++;

    Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);

}
// 初始化ADCSOC
void initADCSOCs(void)
{
    // 采样窗口持续10个系统时钟
      ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_GPIO, ADC_CH_ADCIN0, 10);
      ADC_setupSOC(ADCA_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_GPIO, ADC_CH_ADCIN1, 10);

    // 设置中断为ADCINT1,并启用
    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个系统时钟
    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_GPIO, ADC_CH_ADCIN0, 10);
    ADC_setupSOC(ADCB_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_GPIO, ADC_CH_ADCIN1, 10);

    // 设置中断为ADCINT1,并启用
    ADC_setInterruptSource(ADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);
    ADC_enableInterrupt(ADCB_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCB_BASE, ADC_INT_NUMBER1);

    // 采样窗口持续10个系统时钟
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER0, ADC_TRIGGER_GPIO, ADC_CH_ADCIN15, 10);
    ADC_setupSOC(ADCC_BASE, ADC_SOC_NUMBER1, ADC_TRIGGER_GPIO, ADC_CH_ADCIN15, 10);

    // 设置中断为ADCINT1,并启用
    ADC_setInterruptSource(ADCC_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER1);
    ADC_enableInterrupt(ADCC_BASE, ADC_INT_NUMBER1);
    ADC_clearInterruptStatus(ADCC_BASE, ADC_INT_NUMBER1);
}

过程中的一些问题:

1. 中断函数中不能出现延时函数以及死循环!

2. 翻转函数起初放到了中断中,导致ADC采集无法进行;

3. 将翻转函数重新添加至主函数中,由于若翻转一次即,将GPIO高电平转为低电平,此后无法再触发中断,因此需要再添加一个翻转将低电平变为高电平,从而触发ADC开始转换。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值