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.
工具与软件:
您好!
我将尝试使用这些功能vimEnableInterrupt
、并vimDisableInterrupt
启用或禁用特定的中断矢量。 在我的例子中、它是为adcGROUP1
。
但是、我无法使它正常工作。 似乎的中断adcGROUP1
从未被指令启用vimEnableInterrupt(15, SYS_IRQ)
。
我已经在下面附上了sys_main.c
和notification.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
}