This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS570LS1224:vimEnableInterrupt /vimDisableInterrupt 函数不起作用、以启用/禁用中断

Guru**** 2185245 points
Other Parts Discussed in Thread: HALCOGEN
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1466672/tms570ls1224-vimenableinterrupt-vimdisableinterrupt-functions-not-working-to-enable-disable-interrupts

器件型号:TMS570LS1224
主题中讨论的其他器件:HALCOGEN

工具与软件:

您好!

我将尝试使用这些功能vimEnableInterrupt、并vimDisableInterrupt启用或禁用特定的中断矢量。 在我的例子中、它是为adcGROUP1

但是、我无法使它正常工作。 似乎的中断adcGROUP1从未被指令启用vimEnableInterrupt(15, SYS_IRQ)

我已经在下面附上了sys_main.cnotification.c文件、便于您查看。 感谢您对此问题的帮助。

sys_main.c

/*包含文件*/

#include "sys_common.h"

/*用户代码 begin (1)*/
#include "ADC.h"
#include "sci.h"
#include "Gio.h"
#include "stdlib.h"
#include "stdio.h"
#include "sys_vim.h"
/*用户代码结束*/

/**@fn void main (void)
*@简要应用程序主函数
*@注意此函数默认为空。
*
*此函数在启动后调用。
*用户可以使用此函数来实现应用程序。
*/

/*用户代码 begin (2)*/

/*用户代码结束*/

int main (void)

/*用户代码 begin (3)*/

sciInit();
adcInit ();
gioInit ();
//_enable_irq ();
vimInit ();

vimEnableInterrupt (15、SYS_IRQ);
// vimChannelMap (15、15、adc1Group1Interrupt);
// vimDisableInterrupt (15);

adcEnableNotification (adcREG1、adcGROUP1);
/*开始 ADC 转换*/
adcStartConversion (adcREG1、adcGROUP1);
printf ("\n");
fflush (stdout);

while (1)


gioSetBit (gioPORTB、0、1);
printf ("Sen by Serial Port \n");
fflush (stdout);
gioSetBit (gioPORTB、0、0);

}
/*用户代码结束*/

返回0;
}


/*用户代码 begin (4)*/
/*用户代码结束*/

notification.c

/*包含文件*/

#include "ESM.h"
#include "sys_selftest.h"
#include "ADC.h"
#include "Gio.h"
#include "sci.h"
#include "sys_dma.h"

/*用户代码 begin (0)*/
#include "stdio.h"
#include "stdlib.h"
#include "sys_vim.h"

#pragma weak (adcNotification)
void adcNotification (adcbase_t * ADC、uint32组)

/*在用户代码开始和用户代码结束之间输入用户代码。 */
/*用户代码 begin (11)*/


adcData_t ADC_data;
adcData_t * ptr;
uint32 i = 0;
uint32 c = 0;


C = adcGetData (adcREG1、adcGROUP1、&ADC_DATA);

ptr =&ADC_DATA;

对于(i = 0;i < c;i++)

printf ("adc 值[%d]:%d;\n"、i、ptr->value);
fflush (stdout);
PTR++;

}


// vimDisableInterrupt (15);


返回;

/*用户代码结束*/
}

Halcogen

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Ariel:

    Unknown 说:
    /_enable_irq ();

    您为什么评论此启用 IRQ API?

    该 API 在 VIM 中断生成中非常重要、如果没有该 API、可能无法生成中断。

    ——
    谢谢、此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Jagadish:

    感谢您的时间和支持。

    我将该行添加了注释_enable_IRQ();、因为我假设它启用了所有 IRQ、而vimEnableInterrupt(15, SYS_IRQ)仅启用 ADC 组1 IRQ。

    一般而言、我的软件设计为启用一次 ADC 组1中断、然后在adcNotification(adcBASE_t *adc, uint32 group)中断 API 中将其禁用。

    主代码运行一次、之后 IRQ 矢量调用中断 API 并使用线路禁用 IRQ 矢量vimDisableInterrupt(15);。 此 API 也执行一次且不返回到主代码。

    总体想法是主代码运行、当一个中断被 ADC 组1触发时、中断 API 禁用 IRQ 并返回到主代码。

    我期待您的反馈。

    谢谢!

    阿里尔·G·加西亚

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Ariel:

    要获取任何中断都需要_ENABLE_IRQ、因此我建议在初始化代码中默认使用此 API、现在 只要您在初始化后需要、便可以使用 vimDisableInterrupt 和 vimEnableInterrupt 分别禁用或启用各个中断。

    ——

    谢谢、此致、

    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

     Jagadish、您好!

    我对我的代码应用了您的建议、现在可以使用vimEnableInterrupt和启用/禁用中断vimDisableInterrupt。 然而、我遇到了另外一个问题:中断运行正常、但是代码永远不会返回到主例程。 我不确定是什么原因导致了此问题。

    您能举手吗? 我已经阅读了 TMS570LS12x/11x 16/32位 RISC 闪存微控制器技术参考手册、但是我无法完全掌握 VIM 相关的详细信息。

    非常感谢您的指导。

    此致!

     阿里尔·G·加西亚

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Ariel:

    您能否验证 处理程序中 GxINTFLG 寄存器的值? 因为我怀疑我们可能遇到了溢出错误?

    在连续模式下可能会出现此误差。

    您能否请验证以下主题一次、我在这里提到了有关此错误的更多详细信息。

    (+) LAUNCHXL2-570LC43:ADC 连续转换模式使用中断、设置溢出标志-基于 Arm 的微控制器-内部论坛-基于 Arm 的微控制器-内部- TI E2E 支持论坛

    ——

    谢谢、此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    在连续转换模式中似乎存在溢出错误。 此中断只执行一次。

    我已经复制了主代码和调试部分来监控 超限 中的哪个位 INTFLG 非常重要。 但是、我不确定如何解决此问题。 此外、指向该线程的链接无法正常工作(未找到页面)。

    非常感谢您的指导。

    此致、

    阿里尔·G·加西亚

    主代码


    /*包含文件*/

    #include "sys_common.h"

    /*用户代码 begin (1)*/
    #include "ADC.h"
    #include "sci.h"
    #include "Gio.h"
    #include "stdlib.h"
    #include "stdio.h"
    #include "sys_vim.h"
    uint32 cont_int = 0;
    /*用户代码结束*/

    /**@fn void main (void)
    *@简要应用程序主函数
    *@注意此函数默认为空。
    *
    *此函数在启动后调用。
    *用户可以使用此函数来实现应用程序。
    */

    /*用户代码 begin (2)*/

    /*用户代码结束*/

    int main (void)

    /*用户代码 begin (3)*/

    sciInit();
    adcInit ();
    gioInit ();
    _enable_irq();
    vimInit ();
    uint32 i = 0;
    uint32 cont = 0;
    UINT32转换= 0;
    UINT32溢出= 0;

    //vimEnableInterrupt (15、SYS_IRQ);
    // vimChannelMap (15、15、adc1Group1Interrupt);
    // vimDisableInterrupt (15);

    adcEnableNotification (adcREG1、adcGROUP1);
    /*开始 ADC 转换*/
    adcStartConversion (adcREG1、adcGROUP1);

    while (1)


    CONT = CONT+1;
    对于(i = 0;i < 1000;i++);//延迟以观察 LED 闪烁
    gioSetBit (gioPORTB、1、0);

    if (adcIsConversionComplete (adcREG1、adcGROUP1)=8)

    转换=8;
    } else{Conversion =0;}

    if (G1_MEM_OVERRIDE (adcREG1、adcGROUP1)=2)

    超限=2;
    } else{overflow =0;}

    //溢出= G1_MEM_OVERRIDE (adcREG1、adcGROUP1);
    //Indicador = adcIsConversionComplete (adcREG1、adcGROUP1);
    // printf ("\n");
    //fflush(stdout);
    // gioSetBit (gioPORTB、0、0);//停止转换
    //adcStartConversion (adcREG1、adcGROUP1);

    }
    /*用户代码结束*/

    返回0;

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    首先我要确保这一点、

    是否在中断处理程序中为测试设置了任何断点? 如果您这样做、那也可能会导致溢出错误、我们可以忽略此类溢出错误、因为是由断点引起的。

    所以、我的建议是不要在处理程序中设置任何断点。  如果我们持续获得数据而没有任何问题、那么我们可以假定代码正在正常运行、而不是只连续读取您的数据并在 UART 终端上打印出来。

    另一种方法是将数据持续复制到一个缓冲区中、我们使用新值持续更新缓冲区、然后可以假定代码运行正常。

    ——
    谢谢、此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如果您在单次触发模式下工作、我们可以在代码中设置断点、因为转换只会在我们调用启动转换 API 后发生。 因此、我们可以在调用该 API 之前设置断点、并且可以在调试模式下使用断点查看每个样本的数据。 但是、对于连续模式、最好是使用断点来查看数据、因为如果我们设置的断点不会停止后台 ADC 转换、这会产生溢出错误。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、 Jagadish。

    我一直在努力寻求您的建议、并实施了下面的新代码。 主循环执行一次、然后中断接管。 在终端上、字符串"Helloooooooooo---- !!!!" 中、后跟连续模式(如环路)下的所有 ADC 转换数据。 然而、此程序从不返回中断。

    Thx 和 Regars

    代码:

    /*包含文件*/

    #include "sys_common.h"

    /*用户代码 begin (1)*/
    #include "ADC.h"
    #include "sci.h"
    #include "Gio.h"
    #include "stdlib.h"
    #include "stdio.h"
    #include "string.h"
    #include "sys_vim.h"
    /*用户代码结束*/

    /**@fn void main (void)
    *@简要应用程序主函数
    *@注意此函数默认为空。
    *
    *此函数在启动后调用。
    *用户可以使用此函数来实现应用程序。
    */

    /*用户代码 begin (2)*/
    //--- 串行端口变量-----------------------------------------------------------
    static char Tx[5];// array de 5 Elementos para enviar los digitos del adc rango 12 bits 0-4095 (es decir、hista 4 dígitos decales)。

    //--------------------------------------------------------------------------------------------------------------------------------------

    //---Conversor Variables (逆变或变量)-------------------------------------------------------

    adcData_t ADC_data;// ADC 数据结构
    adcData_t * ptr =&adc_data;// ADC 数据指针
    //------------------

    /*用户代码结束*/

    int main (void)

    /*用户代码 begin (3)*/
    sciInit();
    adcInit ();
    gioInit ();
    vimInit ();
    _enable_irq();

    adcEnableNotification (adcREG1、adcGROUP1);
    /*开始 ADC 转换*/
    adcStartConversion (adcREG1、adcGROUP1);

    while (1)

    volatile int i;
    sciSend(scilinREG, 25,(unsigned char*)"Helloooooooo--- !!!!");
    对于(i = 0;i < 1000000;i++);

    }

    /*用户代码结束*/

    返回0;
    }

    /*用户代码 begin (4)*/
    void adcNotification (adcbase_t * ADC、uint32组)

    adcStopConversion (adcREG1、adcGROUP1);
    adcGetData (adcREG1、adcGROUP1、ptr);
    sprintf (Tx、"%d"、ptr->value);//数据转换缓冲区到字符串 Tx
    sciSend (scilinREG、strlen (Tx)、(unsigned char*)&Tx);//strlen (Tx)长度字符串 Tx
    sciSend (scilinREG、2、(unsigned char*)"\r\n");//将 Tx 发送到终端
    adcREG1->GxINTFLG[1U]= 0x1001bU;//清除中断标志
    adcStartConversion (adcREG1、adcGROUP1);
    返回;

    }
    /*用户代码结束*/

    Halcogen ADC 配置

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Ariel:

    我怀疑可能会发生这种情况:

    当我们选择一个 ADC 通道时、转换时间太短、我的意思是转换通道的时间为1.6 μ s。 那么、如果这不足以从中断处理程序返回到在主循环中执行的话、该怎么办呢。

    您能否再启用3个通道并进行一次测试? 如果问题仍然存在、我将尝试在结尾创建一个新示例、然后对该问题进行进一步的调试。

    ——
    谢谢、此致、
    Jagadish。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    你好、 Jagadish

    中断函数问题是由在 adcNotification 内调用 sprintf 引起的。 由于 sprintf 具有阻塞行为、因此会导致执行流程卡在中断处理程序内。 此外、adcStartConversion 函数必须位于 adcNotification 之外、因为在中断处理程序中运行该函数会产生一个循环。

    解决方案是将 sprintf 和 adcStartConversion 从 adcNotification 移出、并改为在主代码中处理它们。

    正确代码如下。 感谢您的所有帮助! 我从您的反馈中学到了很多东西

    /*用户代码 begin (0)*/
    /*用户代码结束*/

    /*包含文件*/

    #include "sys_common.h"

    /*用户代码 begin (1)*/
    #include "ADC.h"
    #include "sci.h"
    #include "Gio.h"
    #include "stdlib.h"
    #include "stdio.h"
    #include "string.h"
    #include "sys_vim.h"
    /*用户代码结束*/

    /**@fn void main (void)
    *@简要应用程序主函数
    *@注意此函数默认为空。
    *
    *此函数在启动后调用。
    *用户可以使用此函数来实现应用程序。
    */

    /*用户代码 begin (2)*/
    //--- 串行端口变量-----------------------------------------------------------
    static char Tx[5];// array de 5 Elementos para enviar los digitos del adc rango 12 bits 0-4095 (es decir、hista 4 dígitos decales)。
    // int buffer;// ADC Data buffer
    //--------------------------------------------------------------------------------------------------------------------------------------

    //---Conversor Variables (逆变或变量)-------------------------------------------------------

    adcData_t ADC_data;// ADC 数据结构
    adcData_t * ptr =&adc_data;// ADC 数据指针
    //------------------
    volatile uint8_t ADC_flag = 0;
    /*用户代码结束*/

    int main (void)

    /*用户代码 begin (3)*/
    sciInit();
    adcInit ();
    gioInit ();
    vimInit ();
    _enable_irq();

    adcEnableNotification (adcREG1、adcGROUP1);
    /*开始 ADC 转换*/
    adcStartConversion (adcREG1、adcGROUP1);

    while (1)

    volatile int i;
    sciSend (scilinREG、5、(unsigned char*)"Hola\0");
    对于(I = 0;I < 1000000;I++)

    adcStartConversion (adcREG1、adcGROUP1);

    if (ADC_FLAG)// Solo si hay nueva conversión

    sprintf (Tx、"%d"、ptr->value);
    sciSend (scilinREG、strlen (Tx)、(unsigned char*) Tx);
    sciSend (scilinREG、2、(unsigned char*)"\r\n");
    ADC_FLAG = 0;//复位标志

    adcStartConversion (adcREG1、adcGROUP1);// Ahora sí、iniciar nueva conversión
    }


    }

    /*用户代码结束*/

    返回0;
    }

    /*用户代码 begin (4)*/
    void adcNotification (adcbase_t * ADC、uint32组)

    adcStopConversion (adcREG1、adcGROUP1);
    adcGetData (adcREG1、adcGROUP1、ptr);
    ADC_FLAG = 1;//指示干草运行 nuevo valor listo
    adcREG1->GxINTFLG[1U]= 1U;// Limpiar la interrupción ó n

    }