我在使用英飞凌TC377芯片,当我改变CAN 控制器状态,将
```
CCCRi.INIT -- >NORMAL
```,但是PSRi.ACT一直保持在SYNCHRONIZING状态,应该时IDLE状态才对,我检查了时钟和波特率的设置,没有发现问题,到底是哪里的问题呢?怎么解决?
以下答案由GPT-3.5大模型与博主波罗歌共同编写:
根据您提供的信息,您的CAN控制器状态从INIT(初始化)转变为NORMAL,但是PSRi.ACT状态一直保持在SYNCHRONIZING状态。这通常表明您的CAN控制器正在等待同步,因此使用一个正确的时钟可以解决这个问题。
以下是一些可能有助于解决您的问题的建议:
确保CAN控制器的时钟源正常连接,并且每个CAN节点的时钟设定相同。因为CAN总线需要在所有节点之间进行同步,否则数据传输将被破坏。
检查波特率的设置是否正确,确保在所有节点之间使用相同的波特率设置,并确认波特率不太高或太低。频率较高,容易发生同步问题。
检查CAN总线上是否存在干扰,例如在毗邻的线路上运行的电机或让设备附近在其他电子产品的电磁干扰。
下面是一个代码示例,可以尝试使用该代码看看是否能够解决问题,代码中假设时钟源是一个外部晶振,波特率设置为500kbps:
#include <mcp_can.h> //可以使用mcp_can库操作CAN控制器
#include <SPI.h>
// MCP2515 CAN Module
MCP_CAN CAN(10); // CS Pin 10 for MCP2515
unsigned char canData[8] = {'H', 'E', 'L', 'L', 'O', ' ', 'W', 'D'};
void setup()
{
Serial.begin(115200);
if(CAN_OK == CAN.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ))
{
Serial.println("CAN BUS Shield init ok!");
}
else
{
Serial.println("CAN BUS Shield init failed");
}
CAN.setMode(MCP_NORMAL);
// Send data on CAN BUS
CAN.sendMsgBuf(0x123, 0, 8, canData);
}
void loop()
{
unsigned char len = 0;
unsigned char buf[8];
if(CAN_MSGAVAIL == CAN.checkReceive())
{
CAN.readMsgBuf(&len, buf);
Serial.println("-----------------------------");
Serial.print("Get Data from ID: ");
Serial.println(CAN.getCanId());
for(int i = 0; i<len; i++)
{
Serial.print(buf[i]);
}
Serial.println();
}
}
希望这些信息对您有所帮助!
如果我的回答解决了您的问题,请采纳!
c
// 设置时钟和波特率
CAN_SetClockAndBaudrate(CAN_CONTROLLER, CAN_CLOCK_FREQUENCY, CAN_BAUDRATE);
// 检查时钟和波特率设置是否正确
if (CAN_GetClockFrequency(CAN_CONTROLLER) != CAN_CLOCK_FREQUENCY || CAN_GetBaudrate(CAN_CONTROLLER) != CAN_BAUDRATE) {
// 时钟和波特率设置不正确
// 处理错误
}
c
// 检查CAN总线上的错误
if (CAN_GetErrorCount(CAN_CONTROLLER) > 0) {
// 发现错误
// 处理错误
}
c
// 检查CAN控制器状态
if (CAN_GetControllerStatus(CAN_CONTROLLER) != CAN_STATUS_IDLE) {
// CAN控制器状态不正确
// 处理错误
}
// 检查CAN控制器是否正常工作
if (!CAN_IsControllerWorking(CAN_CONTROLLER)) {
// CAN控制器不正常工作
// 处理错误
}
首先,您可以检查以下几个方面,以确定可能的问题原因:
确认信号电平:确保CAN控制器和网络上的其他节点正确连接并且具有正确的信号电平。如果信号线接地或者短路,就会导致CAN控制器无法正常工作。
检查波特率匹配:确保CAN控制器设置的波特率与网络上的其他节点匹配,并且在规定误差范围内。如果两者之间的波特率不匹配,则CAN控制器无法正常同步。
确认时钟源:确保使用相同的时钟源。如果网络上的其他节点使用了不同的时钟源,那么CAN控制器可能无法正常同步。
检查过滤设置: 确认CAN ID是否符合要求,并且启用/禁用显式/隐式帧过滤设置是否正确。
如果以上步骤都没有解决问题,您可以尝试重新初始化CAN控制器。同时,请参考英飞凌TC377芯片手册中与CAN相关章节查找更多帮助。
不知道你这个问题是否已经解决, 如果还没有解决的话:#include "Ifx_Types.h"
#include "IfxCpu.h"
#include "IfxScuWdt.h"
#include "SysSe/Bsp/Bsp.h"
#include "Port/Io/IfxPort_Io.h"
#include "Multican/Can/IfxMultican_Can.h" //包含CAN控制API
IfxCpu_syncEvent g_cpuSyncEvent = 0;
//定义CAN模块、节点、MessageObject:
// CAN handle
IfxMultican_Can can;
// Nodes handles
IfxMultican_Can_Node canSrcNode;
// Message Object handles
IfxMultican_Can_MsgObj canSrcMsgObj;
//定义中断等级和中断函数,报文发送完成后进入中断,翻转LED电平
#define ISR_PRIORITY_CAN_TX 2 /* Define the CAN TX interrupt priority */
#define TX_INTERRUPT_SRC_ID IfxMultican_SrcId_0 /* Transmit interrupt service request ID */
IFX_INTERRUPT(canIsrTxHandler, 0, ISR_PRIORITY_CAN_TX);
void canIsrTxHandler(void)
{
IfxPort_togglePin(&MODULE_P14, 9);
}
//CAN初始化函数:
void CanApp_init(void)
{
// create configuration
IfxMultican_Can_Config canConfig;
IfxMultican_Can_initModuleConfig(&canConfig, &MODULE_CAN);
// initialize interrupt priority
canConfig.nodePointer[TX_INTERRUPT_SRC_ID].priority = ISR_PRIORITY_CAN_TX;
// initialize module
IfxMultican_Can_initModule(&can, &canConfig);
// create CAN node config
IfxMultican_Can_NodeConfig canNodeConfig;
IfxMultican_Can_Node_initConfig(&canNodeConfig, &can);
canNodeConfig.baudrate = 500000; // 1 MBaud
canNodeConfig.nodeId = IfxMultican_NodeId_0;
canNodeConfig.rxPin = &IfxMultican_RXD0A_P02_1_IN;
canNodeConfig.txPin = &IfxMultican_TXD0_P02_0_OUT;
IfxMultican_Can_Node_init(&canSrcNode, &canNodeConfig);
// create message object config
IfxMultican_Can_MsgObjConfig canMsgObjConfig;
IfxMultican_Can_MsgObj_initConfig(&canMsgObjConfig, &canSrcNode);
// assigned message object:
canMsgObjConfig.msgObjId = 0;
canMsgObjConfig.frame = IfxMultican_Frame_transmit;
canMsgObjConfig.control.messageLen = IfxMultican_DataLengthCode_8;
canMsgObjConfig.control.extendedFrame = FALSE;
canMsgObjConfig.txInterrupt.enabled = TRUE;
canMsgObjConfig.txInterrupt.srcId = TX_INTERRUPT_SRC_ID;
// initialize receive message object
IfxMultican_Can_MsgObj_init(&canSrcMsgObj, &canMsgObjConfig);
}
//CAN发送函数
void CAN_SendSingle(uint32 id, uint32 high, uint32 low)
{
// Initialise the message strcture
IfxMultican_Message txMsg;
IfxMultican_Message_init(&txMsg, id, low, high, IfxMultican_DataLengthCode_8);
// Transmit Data
while( IfxMultican_Can_MsgObj_sendMessage(&canSrcMsgObj, &txMsg) == IfxMultican_Status_notSentBusy );
}
//主函数
int core0_main(void)
{
IfxCpu_enableInterrupts();
/* !!WATCHDOG0 AND SAFETY WATCHDOG ARE DISABLED HERE!!
* Enable the watchdogs and service them periodically if it is required
*/
IfxScuWdt_disableCpuWatchdog(IfxScuWdt_getCpuWatchdogPassword());
IfxScuWdt_disableSafetyWatchdog(IfxScuWdt_getSafetyWatchdogPassword());
/* Wait for CPU sync event */
IfxCpu_emitEvent(&g_cpuSyncEvent);
IfxCpu_waitEvent(&g_cpuSyncEvent, 1);
initTime();
IfxPort_setPinMode(&MODULE_P14, 9, IfxPort_Mode_outputPushPullGeneral);
//初始化CAN_STB引脚(我的开发板上CAN收发器的STB引脚是软件控制的所以需要程序拉低,如果是硬件拉低则不需要)
IfxPort_setPinMode(&MODULE_P11, 11, IfxPort_Mode_outputPushPullGeneral);
//IfxPort_setPinMode(&MODULE_P02, 8, IfxPort_Mode_outputPushPullGeneral);
CanApp_init();
while(1)
{
CAN_SendSingle(0x200,(uint32)0x01020304, (uint32)0x01020304);
wait(TimeConst_1s);
}
return (1);
}
结果如下,同时LED灯随着CAN报文的发送闪烁:
根据您的描述,可能是以下几个原因导致PSRi一直保持在SYNCHRONIZING状态:
CAN总线上的其他节点未正确配置或初始化。
波特率设置错误,导致与其他节点无法同步。
CAN控制器的时钟信号源不正确,导致时钟不稳定或与其他节点不同步。
CAN总线上存在错误的信号传输,如电缆接触不良、信号干扰等。
建议您按照以下步骤进行排查和解决:
确认CAN总线上的其他节点已正确配置和初始化。
确认波特率设置正确,并与其他节点一致。
确认CAN控制器的时钟信号源正确,并与其他节点一致。
检查CAN总线上的信号传输质量,如电缆连接是否牢固、是否存在信号干扰等。
如果以上步骤均已确认无误,可以尝试重置CAN控制器,并重新初始化。如果问题仍然存在,建议您咨询英飞凌技术支持人员,以获取更具体的解决方案。
引用chatGPT作答,从你提供的信息来看,可能出现了以下几种情况:
1.错误的时钟源选择:确保时钟源正确选择,例如外部晶体或内部振荡器,并且时钟频率设置正确。
2.错误的波特率设置:确保所有设备的波特率设置相同,并且满足CAN总线的最大长度和传输速率的要求。
3.错误的过滤器设置:检查过滤器设置,确保它们与期望的CAN ID匹配。
4.CAN控制器初始化错误:确保CAN控制器初始化正确完成,并且没有其他错误。
针对以上问题,你可以尝试以下方法解决问题:
1.确保时钟源正确选择,并且时钟频率设置正确。
2.确保所有设备的波特率设置相同,并且满足CAN总线的最大长度和传输速率的要求。
3.检查过滤器设置,确保它们与期望的CAN ID匹配。
4.确保CAN控制器正确初始化,如果有其他错误,请查看错误代码并尝试解决它们。