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.

[参考译文] TM4C123GH6PM:使用 TIVAARE 时需要帮助

Guru**** 2455360 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/635476/tm4c123gh6pm-help-needed-in-using-tivaware

器件型号:TM4C123GH6PM

大家好、  

我尝试编写实现 CAN 串行协议的简单代码、这里是发送器 Launchpad 代码。  

当我单步执行时、我会观察到这一点  

CANIntRegister (CAN0_BASE、CANIntHandler);

函数白色 LED 只是亮起(查看处理程序代码)、执行在下一行停止

当我单步执行时、我尝试在启动文件中静态注册处理程序  

IntEnable (INT_CAN0);   

函数它打开白色 LED、执行在代码的下一行停止。  

在这两种情况下,我都尝试继续步进以查看 CANmsgSet()之后发生的情况。 我发现代码一直卡在处理程序中(LED 持续闪烁)。

有人能帮忙吗?  

此致、  

斯里特

#pragma diag_push
#pragma CHECK_MISRA ("无")

#include 
#include 
include "stdlib.h"
//#include "ih/hw_ints.h"
#include "inc/hw_memmap.h"
#include "inc/hw_uart.h"
#include "inc/hw_gpio.h"
#include "driverlib/driverh/driver.h"



#include "driverlib/driver.h"#include "driverline/driver.h"#driverlib/driver.h"#include "driverlib#driverline"#driverlib.driver.h"#driverlib.driver.h"#include "driverlib.driver.h"#driverlib#driverlib.driverlib#driver.h"#include "driverline"#include "driver.h"#driverlib.driverlib.driver.h"#include "driverlib.driver.h"#include "driverlib.driver.h"#include "driverlib.driver.h"#driverlib#driverlib#driver.h"#include "driverlib.driverlib#driverlib.driver.h"#include "driver.h"#driver











#include 
#include 
#include 

#pragma diag_pop

void CANIntHandler (void);
int main (void);

int main (void){
SysCtlClockSet (SYSCTL_SYSDIV_2_5|SYSCTL_USE_PLL|SYSCTL_OSC_MAIN|SYSCTL_XTAL_16MHz);
PORTF_Init();


// CAN0和 Porte 配置
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOE);
while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOE)){}
GPIOPinConfigure (GPIO_PE4_CAN0RX);
GPIOPinConfigure (GPIO_PE5_CAN0TX);
GPIOPinTypeCAN (GPIO_Porte _BASE、GPIO_PIN_4|GPIO_PIN_5);


SysCtlPeripheralEnable (SYSCTL_Periph_CAN0);
while (!SysCtlPeripheralReady (SYSCTL_Periph_CAN0)){}
CANInit (CAN0_BASE);
CANBitRateSet (CAN0_BASE、SysCtlClockGet ()、50000);
CANIntRegister (CAN0_BASE、CANIntHandler);
CANIntEnable (CAN0_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
IntEnable (INT_CAN0);
CANEnable (CAN0_BASE);


//设置 CAN 消息对象

tCANMsgObject msg;
uint32_t msgData;
uint8_t *msgDataPtr =(uint8_t *)&msgData;

msgData = 0;
MSG.ui32MsgID = 1;
MSG.ui32MsgIDMask = 0;
MSG.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
MSG.ui32MsgLen = sizeof (msgDataPtr);
MSG.pui8MsgData = msgDataPtr;





while (1){
CANMessageSet (CAN0_BASE、1、&msg、MSG_OBJ_TYPE_TX);

SysTick80_delay_10ms (300);

}
返回0;
}


void CANIntHandler (void){
GPIO_PORTF_DATA_R θ^= 0x0E;//切换白色 LED
SysTick80_DELAY_10ms (300);

CANIntClear (CAN0_BASE、1);//清除中断

无符号长整型状态= CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST);//读取中断状态

if (status =CAN_INT_INTID_STATUS){//控制器状态中断
状态= CANStatusGet (CAN0_BASE、CAN_STS_CONTROL);//读回错误位,对它们执行什么操作?
} 否则、如果(status = 1){//消息对象1
CANIntClear (CAN0_BASE、1);//清除中断

}

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

    您拥有什么"SysTick80_DELAY_10ms"函数? 您能否发布它的源代码? 我在任何 TivaWare 文件中都没有看到这一点。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、sarea、

    此外、是否可以使用断点或某些 UART print 语句来查找 CANIntStatus API 的返回结果?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    同意 Ralph、但除了 SysTick80_delay_10ms 的合理定义外、该用法:

    [引用 user="sarea Hariri"] void CANIntHandler (void){GPIO_PORTF_DATA_R ^= 0x0E;//切换白色 LED SysTick80_DELAY_10ms (300);

    不能再好了。

    为了获得良好的二次逼近效果、绝不应出现延迟或中断输出。

    还有一个问题、您是否实施了示例 CAN 代码?

    Robert

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

    谢谢 Ralph、

    以下是我对函数和编辑后的处理程序的定义:  

    void SysTick80_delay_10ms (uint32_t ms){
    Int I;
    
    对于(i = 0;i 

    空 CANIntHandler (空){
    GPIO_PORTF_DATA_R θ^= 0x0E;//切换白色 LED
    //SysTick80_DELAY_10ms (300);
    
    //CANIntClear (CAN0_BASE、1);//清除中断
    
    uint32_t status;
    STATUS = CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST);//读取中断状态
    
    if (status =CAN_INT_INTID_STATUS){//控制器状态中断
    状态= CANStatusGet (CAN0_BASE、CAN_STS_CONTROL);//读回错误位,对它们执行什么操作?
    } 否则、如果(status = 1){//消息对象1
    CANIntClear (CAN0_BASE、1);//清除中断
    
    }
    

    以下 是发生的确切情况:  

    执行 CANIntRegister (CAN0_BASE、CANIntHandler)之后;函数. 它会进入处理程序(直到现在我不知道为什么?)   

    2.在处理程序开始时,我观察到状态变量==1。 但是在执行处理程序中的第二行之后。 状态= CANStatusGet (CAN0_BASE、CAN_STS_CONTROL);.. 状态将为0。 因此、请不要输入 if、也不要输入 if statement。

    3.在 while 中设置 msg 后(1)。 它会转到处理程序.. 开始时。 我的状态为=0。 但在执行第2行之后。 状态=32768. 然后输入 if 语句和 status =4,这是 CANStatusGE()的返回值; 然后它会在处理程序中永久循环??

    此致、

    斯里特

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Robert
    感谢有关处理程序中延迟和打印的建议。
    我阅读了 TivaWare 中的 TX 示例和驱动程序库用户指南中 CAN 模块的编程示例。
    但我不想复制并粘贴。 相反、我认为它是一个指南、可帮助我编写类似的代码

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

    Robert 的观点是:" ISR 中的负担和/或延长时间肯定是有效的。"    和-供应商代码(通常)采用"printf"、这确实增加了完全执行的时间。

    现在、您需要确认您的代码已"达到特定的关键/关键点"、但可以通过设置一个(或多个) LED 来实现这一目标、并且速度要快得多。   我建议可能使用一个完整的 GPIO 端口(或至少一半)和这4个 LED -可以确认已输入/执行多达16个不同的代码块-但"减去"任何"引起闪烁或切换"的 ISR 延长延迟。

    在开发过程中、我的公司采用"专用、微型、PCB LED 插件"、始终连接到 GPIO 端口、我们保留该端口用于此类用途。   因此、驱动代码"可重用"且简单-只有其"放置"与受监控的代码块中的代码发生变化。

    监测准则的进展情况非常有用(通常是强制性的)、但正如上文的建议所揭示的、在 ISR 中不必强制执行"不必要的时间支出"。

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

    [引用 user="sarea Hariri ]void SysTick80_DELAY_10ms (uint32_t ms){int i;for (i = 0;i

    这会带来多个问题。 为什么要多次初始化系统节拍函数? 为什么不使用 TIVAWare 函数?

    [引用 user="sarea Hariri ]2. 在处理程序开始时、我观察到状态变量=1

    嗯、你尚未对它进行初始化、所以它可以是任何东西。 从技术上讲、它甚至还不在范围内、更糟糕的是、它仅对 C++和 C99有效。 许多编译器尚不支持 C99、因此我担心的是您可能正在使用 C++、在这种情况下、这不是一个有效的中断例程。

    [引用 user="sarea Hariri"] status =4,这是 CANStatusGet ()函数的返回[/引用]

    这会告诉您什么?

    Robert

    从已知良好的例行程序开始、有很多事情要说。 当您的工作不起作用时、恢复到已知良好的程序将会有更多话要说。

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

    Robert

    感谢你。 由于我是 TivaWare 的新用户、我不知道我可以使用 SysCtlDelay 进行延迟。 但是、这是新的编辑处理程序。

    我仍然有问题。 执行该操作

      CANIntRegister (CAN0_BASE、CANIntHandler);

    它会转到处理程序(你能告诉我为什么?)!!  状态变量已分配为零值。

    调用此函数之后

       CANMessageSet (CAN0_BASE、1、&msg、MSG_OBJ_TYPE_TX);

    它进入处理程序,状态=32768 ,这意味 着它的状态中断.. 然后输入 if 语句,status ==4,这是 CANStatusGet ()的返回值;

    但是当调用状态中断时,该函数不应该清除它??? 如果是,为什么处理程序重新执行?

    如果函数应该为't. 在这一点上,我能帮我清除标记吗? 以便我们可以从中断处理程序返回?

    最后一个问题是,如果 CAN 控制器发送了一条消息并且 总线上没有其它节点,它是否会触发状态中断?

    此致、  

    斯里特

    空 CANIntHandler (空){
    GPIO_PORTF_DATA_R θ^= 0x0E;//切换白色 LED
    
    SysCtlDelay (SysCtlClockGet ()/3);//延迟一秒
    
    
    
    
    uint32_t status;
    STATUS = CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST);//读取中断状态
    
    if (status =CAN_INT_INTID_STATUS){//控制器状态中断
    状态= CANStatusGet (CAN0_BASE、CAN_STS_CONTROL);//读回错误位,对它们执行什么操作?
    } 否则、如果(status = 1){//消息对象1
    CANIntClear (CAN0_BASE、1);//清除中断
    
    }
    
    

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

    [引用 user="sarea Hariri"]

    我仍然有问题。 执行该操作

      CANIntRegister (CAN0_BASE、CANIntHandler);

    [/报价]

    您是否清除了中断?

    [引用 user="sarea Hariri">进入处理程序,状态=32768 ,这意味 着它的状态中断.. 然后输入 if 语句,status =4,这是 CANStatusGet ()的返回;

    返回4意味着什么? 确定之后、我们可以解决您提出的下一个问题。

    现在跳过这个、看看您的最后一个问题。

    [引用 user="sarea Hariri"]最后一个问题,如果 CAN 控制器发送消息并且 总线上没有其他节点,它是否会触发状态中断?

    这将导致错误(以及相当快的总线关闭条件)、因此根据您的设置、您将需要一个中断。

    您尚未回答是编译为 C 还是 C++

    Robert

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

    CANIntRegister API 只能在需要动态分配矢量表的情况下使用。 我不建议在您的第一个应用中使用此功能。 尝试删除该内容、查看是否有任何行为变化。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    首先,我认为 CANIntRegisterI()不应产生中断本身。

    对于第二个问题、如果 I 胖正确、根据数据表、CAN 状态寄存器返回4表示位1错误(位1错误表示器件想要发送高电平(逻辑1)、但监控的总线值为低电平(逻辑1)
    0)。) 这可能是因为噪声信号、因为我在测试第一个电路板(发送器)时没有将任何导线连接到电路板。

    最后、我在 CCS 的选项中使用 TI 编译器。 我真的不知道在哪里可以找到它的编译是 c 还是 c++?

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

    Ralph

    我只是错误地按下了“这解决了我的问题”!!  
    我尝试在启动文件中静态分配 ISR 并删除 CANIntRegister()函数。 然后、完全相同的事情发生、并且通过代码为 STATUS 变量提供相同的值。 唯一的区别是,它不是在执行 CANIntRegister()之后转到处理程序(现在我注释掉它),而是在执行 IntEnable (INT_CAN0)之后跳转到处理程序;

    此致、
    斯里特

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

    [引用 user="sarea Hariri ]最后、我在 CCS 的选项中使用 TI 编译器。 我真的不知道在哪里可以找到它的编译是 c 还是 c++?

    它应该在您的选项中。

    [引用 user="sarea Hariri"]
    对于第二个问题、如果 I 胖正确、根据数据表、CAN 状态寄存器返回4表示位1错误(位1错误表示器件想要发送高电平(逻辑1)、但监控的总线值为低电平(逻辑1)
    0)。) 这可能是因为噪声信号、因为我在测试第一个电路板(发送器)时没有将任何导线连接到电路板。 [/报价]

    好的、但暂停一下、思考是否需要噪声才能获得此结果。 我认为不是。

    下一步、这需要您执行什么操作?

    Robert

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

    [引用 user="sarea Hariri">我刚才错误地按了"这解决了我的问题!!  [/报价]

    论坛继续降低、显然现在无法纠正这种误击。

    Robert

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    Robert
    这是个好消息。 我只需连接 CAN 总线的2根导线、就尝试了很多次。
    最后、我可以说它工作正常...

    我使用环路技术在配置中添加以下两行代码来测试电路板:

    CAN0_CTL_R |= CAN_CTL_TEST; //启用测试模式
    CAN0_TST_R |= CAN_TST_LBACK; //启用回路模式

    通过观察寄存器和状态变量,我可以在总线上发送 MSG。 回路忽略该 ACK。
    但我还有2个问题:

    1.为什么在此行后执行到处理程序:
    IntEnable (INT_CAN0);?

    2.当我调用 CanMessageSet()时,它会作为控制器状态中断进入处理程序,并输入调用 CanStatusGet ()的 if 语句。
    然后它重新进入处理程序(在第一次从处理程序返回后)并输入 else if block,该块正在调用 CanIntClear (),然后它返回给调用方(while (1))... 问题是为什么在调用 CanMessageSet()之后两次进入处理程序??


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

    [引用 user="sarea Hariri ]以下是好消息。 我只需连接 CAN 总线的2根导线、就尝试了很多次。
    最后、我可以说它工作正常...

    如果您是指连接 Tx 和 Rx 线路、则表示没有、则表示您无法使其正常工作。 您的写作远不清楚。

    [引用 user="sarea Hariri ]1. 为什么在此行之后执行会转到处理程序:
    IntEnable (INT_CAN0);?

    您是否清除了中断?

    [引用 user="sarea Hariri ]2. 当我调用 CanMessageSet()时,它作为控制器状态中断进入处理程序,并输入调用 CanStatusGet ()的 if 语句。
    然后它重新进入处理程序(在第一次从处理程序返回后)并输入 else if block,该块正在调用 CanIntClear (),然后它返回给调用方(while (1))... 问题是为什么在调用 CanMessageSet()之后两次进入处理程序?? [/报价]

    如何处理多个同步中断?

    Robert