TI论坛
直播中

韦明

7年用户 284经验值
私信 关注
[问答]

TM4C123微处理器原理与实践例程错误该怎么办?

// CAN实验程序解析//头文件#include #include #include "inc/hw_memmap.h"#include "inc/hw_types.h"#include "inc/hw_can.h"#include "inc/hw_ints.h"#include "driverlib/can.h"#include "driverlib/interrupt.h"#include "driverlib/sysctl.h"#include "driverlib/gpio.h"#include "utils/uartstdio.h"#include "driverlib/rom.h"#include "driverlib/fpu.h"        // 变量定义部分// 一个计数器,用于记录所发送的数据包数volatile ui32 g_ulMsgCount_TX = 0;// 一个计数器,用于记录所接收的数据包数volatile ui32 g_ulMsgCount_RX = 0; // 用于指示在传输过程中是否出现错误以及错误类型volatile ui32 g_bErrFlag = 0; //用于指示是否接收到数据包volatile ui32 g_bRXFlag = 0; // 函数定义部分// UART0的配置及初始化部分。*// UART0模块用于通过计算机虚拟串口显示过程信息,主要包括InitConsole//函数和一些UARTprintf语句。void InitConsole(void)[    // 由于UART0使用PA0,PA1两个引脚,因此需要使能GPIOA模块    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);        // 将PA0和PA1两个引脚的功能选择为执行UART0模块的功能    GPIOPinConfigure(GPIO_PA0_U0RX);    GPIOPinConfigure(GPIO_PA1_U0TX);    // 对PA0和PA1两个引脚配置为UART功能    GPIOPinTypeUART(GPIO_PORTA_BASE, GPIO_PIN_0 | GPIO_PIN_1);    // UART的标准初始化    UARTStdioConfig(0,115200,50000000);]// 延时1s的函数Void SimpleDelay(void)[        //由于ROM_SysCtlDelay函数延时3个时钟周期,而ROM_SysCtlClockGet//函数返回系统时钟的频率,因此最终的结果就是延时1s    ROM_SysCtlDelay(ROM_SysCtlClockGet()/3);]// CAN的中断函数 // 该函数寻找产生中断的原因,并且计算已发送/接收的数据包数目。//由于要使用CAN0模块的中断函数,所以需要在startup_ccs.c文件的//vector table(中断函数列表)中声明CANIntHandler。void CANIntHandler(void)[    ui32 ulStatus;    // 通过CANIntStatus函数读取中断的状态    ulStatus = CANIntStatus(CAN0_BASE, CAN_INT_STS_CAUSE);    // 如果是控制器状态中断,则说明出现了某种错误    if(ulStatus == CAN_INT_INTID_STATUS)    [                //读取CAN模块所处的状态,并自动清除中断。        ulStatus = CANStatusGet(CAN0_BASE, CAN_STS_CONTROL);       //将g_bErrFlag这个状态指示变量置1,以指示有错误发生        g_bErrFlag = 1;    ]    // 检查是否是由message object 1引起的发送中断    else if(ulStatus == 1)    [        // 数据包发送已经完成,清除中断        CANIntClear(CAN0_BASE, 1);                 //发送完一个数据包,计数器g_ulMsgCount_TX增加        g_ulMsgCount_TX++;        // 发送已经完成,清除所有的错误信息.        g_bErrFlag = 0;    ]    // 检查是否是由于message object 2引起的接收中断    else if(ulStatus==2)    [        // 数据包接收已经完成,清除中断        CANIntClear(CAN0_BASE, 2);                // 接收完一个数据包,计数器g_ulMsgCount_RX增加                g_ulMsgCount_RX++;                // 设置Flag说明接收到的数据包正在等待处理        g_bRXFlag = 1;        // 发送已经完成,清除所有的错误信息.                g_bErrFlag = 0;    ]]// main 函数// 配置CAN模块,循环发送CAN格式数据包并通过LOOPBACK模式接收。// 运行过程中的信息通过UART向计算机机传输。int main(void)[        //使能FPU         FPUEnable();    FPULazyStackingEnable();    // 定义CAN的发送和接收对象    tCANMsgObject sCANMessage;    tCANMsgObject srCANMessage;    // 定义发送数据存储区和接收数据存储区    unsigned int uIdx;//一个循环语句使用的变量    ui8 ucMsgData[4];    ui8 ucrMsgData[8];    // 禁用中断。在进行中断配置时要保证中断没被使用。    IntMasterDisable();    // 设置系统时钟为50MHz    SysCtlClockSet(SYSCTL_SYSDIV_4 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHZ);    // 由于CAN0使用PN0、PN1两个引脚,需要使能GPION对应的时钟//信号    SysCtlPeripheralEnable(SYSCTL_PERIPH_GPION);    // 使能CAN0模块的时钟信号    SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN0);    //将PN0和PN1两个引脚的功能选择为执行CAN0模块的功能    GPIOPinConfigure(GPIO_PN0_CAN0RX);    GPIOPinConfigure(GPIO_PN1_CAN0TX);    // 对PN0和PN1两个引脚做有关CAN功能的配置    GPIOPinTypeCAN(GPIO_PORTN_BASE, GPIO_PIN_0 | GPIO_PIN_1);    // CAN控制器的初始化    CANInit(CAN0_BASE);    // 利用CANBitRateSet函数将CAN的传输速率设置为1MHz    CANBitRateSet(CAN0_BASE, SysCtlClockGet(), 1000000);    // 寄存器操作,将CAN0模块配置为运行于LOOPBACK模式    HWREG(CAN0_BASE + CAN_O_CTL) = HWREG(CAN0_BASE + CAN_O_CTL) | CAN_CTL_TEST;    HWREG(CAN0_BASE + CAN_O_TST) = HWREG(CAN0_BASE + CAN_O_TST) | CAN_TST_LBACK;     // 使能CAN0模块    CANEnable(CAN0_BASE);        // 使能CAN0模块的中断    IntEnable(INT_CAN0);        //设置可以引起CAN中断的中断源    CANIntEnable(CAN0_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);    //初始化配置message object,即待发送的报文对象//配置好报文对象后调用CANMessageSet函数进行设置,//这样报文就可以自动被发送出去// 待发送的数据为0    *(ui32 *)ucMsgData = 0;      // CAN message ID:使用1作为报文的ID    sCANMessage.ui32MsgID = 1;          // 没有MASK屏蔽sCANMessage.ui32MsgIDMask = 0;                    //使能发送中断sCANMessage.ui32Flags = MSG_OBJ_TX_INT_ENABLE; //发送数据包大小为4个字节sCANMessage.ui32MsgLen = sizeof(ucMsgData);   // 指向发送数据的指针sCANMessage.pucMsgData = ucMsgData;                  // 初始化配置用于接收的报文对象// 同样也是用CANMessageSet函数可以将某个message object(报文对象)//设置为如下的配置   // 可以接收任何ID的报文对象    srCANMessage.ui32MsgID = 0;                 // 没有屏蔽srCANMessage.ui32MsgIDMask = 0;             // 使能接收中断和ID过滤         srCANMessage.ui32Flags = MSG_OBJ_RX_INT_ENABLE|MSG_OBJ_USE_ID_FILTER;   // 允许最多8个字节的数据srCANMessage.ui32MsgLen = 8;                           //将message object 2设置为接收报文对象ROM_CANMessageSet(CAN0_BASE,2,&srCANMessage,MSG_OBJ_TYPE_RX);    // 使能UART模块    InitConsole();    //使能中断    IntMasterEnable();    // 开始进入发送数据包的循环, 每秒将发送一个数据包。    while(1)    [        // 将待发送的数据包内容通过UART传输并显示出来        UARTprintf("Sending msg: 0x%02X %02X %02X %02X",             ucMsgData[0], ucMsgData[1], ucMsgData[2], ucMsgData[3]);       // 将待发送的报文配置到message object 1中。        CANMessageSet(CAN0_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);        // 等待1s        SimpleDelay();        // 通过g_bErrFlag变量查看是否出错        if(g_bErrFlag)        [            UARTprintf(" error - cable connected?n");        ]        else        [            // 如果没有出错,则显示已经发送的报文数目            UARTprintf(" total count Transmit = %un", g_ulMsgCount_TX);        ]        // 每次发送完毕,都将报文中的数据内容+1        (*(ui32 *)ucMsgData)++;        // 接收报文程序        // 通过g_bRXFlag判断是否有已经接收到是数据包        if(g_bRXFlag)                [                // 建立指向报文数据的缓存区                srCANMessage.pucMsgData = ucrMsgData;                // 读取接收到的报文对象。                // 将message object中的信息读取到srCANMessage接收对象中                CANMessageGet(CAN0_BASE,2,&srCANMessage,0);                // 将g_bRXFlag置为0。          //等到下个报文到来时,中断函数会再次将它置1的                g_bRXFlag=0;                // 如果出现数据丢失等错误,则输出提示信息                if(srCANMessage.ui32Flags & MSG_OBJ_DATA_LOST)                [                        UARTprintf("CAN message loss detectedn");                ]                // 通过UART输出接收到的报文信息                UARTprintf("Receive Msg ID=0x%08X len=%u data=0x",srCANMessage.ui32MsgID,srCANMessage.ui32MsgLen);                // 输出报文中的数据内容                for(uIdx=0;uIdx

回帖(2)

李造吉

2019-9-6 13:44:56
// 寄存器操作,将CAN0模块配置为运行于LOOPBACK模式 HWREG(CAN0_BASE + CAN_O_CTL) = HWREG(CAN0_BASE + CAN_O_CTL) | CAN_CTL_TEST; HWREG(CAN0_BASE + CAN_O_TST) = HWREG(CAN0_BASE + CAN_O_TST) | CAN_TST_LBACK; 将以上两行注释后就不能发出报文了(当然也就谈不上接收发出去的报文了),经测试,注释后进不了中断服务程序。请教您一下,多谢。
举报

韦明

2019-9-6 14:02:48
引用: juwyewerq 发表于 2019-9-6 13:44
// 寄存器操作,将CAN0模块配置为运行于LOOPBACK模式 HWREG(CAN0_BASE + CAN_O_CTL) = HWREG(CAN0_BASE + CAN_O_CTL) | CAN_CTL_TEST; HWREG(CAN0_BASE + CAN_O_TST) = HWREG(CAN0_BASE + CAN_O_TST) | CAN_TST_LBACK; 将以上两行注释后就不能发出报文了(当然也就谈不上接收发出去的报文了),经测试,注释后进不了中断服务 ...

楼主的问题解决了没有,有关我的回复,在另一个帖子中有说明,如果您已经解决了问题,希望您能够分享经验。
举报

更多回帖

发帖
×
20
完善资料,
赚取积分