工具/软件:TI-RTOS
我使用的是 TM4C1294NCPDT、CCS 6.1.2、 TIRTOS 2.16.0.08和编译器5.2.7。
我查看了几个编写 CAN 驱动程序的示例、但我的驱动程序尚不能发送或接收 CAN 数据。
我正在使用的 CPU 可以连接到 CPU 引脚 PB0 (CAN RX)和 PB1 (CAN TX)。 我使用一个宽开滤波器/掩码为接收配置对象编号(CAN 邮箱) 1、并使用对象编号2、3和4来发送以测试代码。
总之、这是我的代码。
全局变量:
typedef 结构
{
bool 忙;
bool CAN_configured;
unsigned long g_ulMsg1Count、g_ulMsg2Count、g_ulMsg3Count、g_bMsgObj3Sent;
tCANMsgObject sMsgObjectRx;
tCANMsgObject sMsgObjectTx;
bool g_bErrFlag;
uint8_t message[message_length]; //数据缓冲区
} CAN_Manager;
静态 CAN_Manager CAN_Manager ={0、0、0、0、0、0、0、0、0};
tCANMsgObject testTx;
#define CAN_MSG_OBJ_RX 1.
主循环 init 可以反复发送消息。
int main (void){ //>>>>> 禁用看门狗以调试此情况、否则看门狗将在休息点 TMO 并重置电路板。
Board_initGeneral();
CAN_init();
while (1)
{
sendTestCAN_Message();
small_delay;
}
如何完成 CAN 初始化。
void CAN_init (void)
{
Hwi_handle myHwi;
ERROR_Block EB;
Hwi_Params HwiParams;
memset ((void*)&CAN_Manager、0x00、sizeof (CAN_Manager));
SysCtlPeripheralEnable (GPIO_PORTB_BASE);
small_delay;//调用 SysCtlPeripheralEnable()时、需要一个小延迟才能使用器件。
GPIOPinConfigure (GPIO_PB0_CAN1RX); // CAN RX 为 PB0
GPIOPinConfigure (GPIO_PB1_CAN1TX); // CAN TX 为 PB1
GPIOPinTypeCAN (GPIO_PORTB_BASE、GPIO_PIN_0 | GPIO_PIN_1);
SysCtlPeripheralEnable (SYSCTL_Periph_CAN0);
CANInit (CAN0_BASE);
CANBitRateSet (CAN0_BASE、120000000、50000);
printf ("CAN 0 init\n");
//CANBitRateSet (CAN0_BASE、SysCtlClockGet ()、50000);
printf ("CAN 0时钟集\n"\});
CANEnable (CAN0_BASE);
printf ("CAN 0已启用\n");
//p81/706 Periph 驱动程序库 spmu298a.pdf 启用 CAN 中断(全部三个 IRQ)
CANIntEnable (CAN0_BASE、CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
printf ("CAN 0 INT enabled \n"\n);
//配置接收对象。
CAN_Manager.sMsgObjectRx.ui32MsgID =(0x602);
CAN_Manager.sMsgObjectRx.ui32MsgIDMask = 0; //过滤器掩码。 0=接受所有 e2e.ti.com/.../568684
CAN_Manager.sMsgObjectRx.ui32Flags = MSG_OBJ_RX_INT_ENABLE | MSG_OBJ_USE_ID_FILTER; //启用 RX 上的中断
CAN_Manager.sMsgObjectRx.ui32MsgLen = 8; //最多允许8个字节
CANMessageSet (CAN0_BASE、1、CAN_Manager.sMsgObjectRx、MSG_OBJ_TYPE_RX);
/* 立即安装 IRQ */
ERROR_INIT (&EB);
Hwi_Params_init (hwiParams);
myHwi = Hwi_create (INT_CAN0_TM4C129、CANIntHandler、&hwiParams、&EB); //请参阅 TIvAware \inc\hw_ints.h
if (NULL ==myHwi)
{
LOG_EVENT (ERROR_CIB_APP_Board_ERROR、"Error installing IRQ for CAN0");
}
//IntEnable (INT_CAN0);//Enable CAN 中断
//CANEnable (CAN0_BASE);//Enable CAN for operation
CAN_Manager.CAN_Configured = true;
}//结束 CAN_init()
发送一条消息、在初始化后从 main 循环中调用。
void sendTestCAN_Message (void)
{
if (CAN_Manager.CAN_Configured = 0)
{
printf ("无法配置、从发送 CAN 消息\n 返回");
返回;
}
CAN_Manager.sMsgObjectTx.ui32MsgID = 0x7A7;
CAN_Manager.sMsgObjectTx.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
CAN_Manager.sMsgObjectTx.ui32MsgLen = 8;
CAN_Manager.sMsgObjectTx.pui8MsgData = CAN_Manager.message;// ptr 至 TX 消息内容
CANMessageSet (CAN0_BASE、2、&CAN_Manager.sMsgObjectTx、MSG_OBJ_TYPE_TX);//将消息发送到 mbx 2
CANMessageSet (CAN0_BASE、3、&CAN_Manager.sMsgObjectTx、MSG_OBJ_TYPE_TX);//将消息发送到 mbx 3.
CANMessageSet (CAN0_BASE、4、&CAN_Manager.sMsgObjectTx、MSG_OBJ_TYPE_TX);//将消息发送到 mbx 4
testTx.ui32MsgID = 0x7A7;
testTx.ui32Flags = MSG_OBJ_TX_INT_ENABLE;
testTx.ui32MsgLen = 8;
testTx.pui8MsgData = CAN_Manager.message;// ptr 至 TX 消息内容
CANMessageSet (CAN0_BASE、2、&testTx、MSG_OBJ_TYPE_TX);//发送消息
printf ("CAN TX\n");
}
IRQ 处理程序、请注意、这永远不会被调用。
空 CANIntHandler (UARg 参数)
{
unsigned long ulStatus;
//
//读取 CAN 中断状态以查找中断原因
ulStatus = CANIntStatus (CAN0_BASE、CAN_INT_STS_CAUST);
//
//如果原因是控制器状态中断,则获取状态
if (ulStatus = CAN_INT_INTID_STATUS)
{
//
//读取控制器状态。 这将返回状态字段
//可以指示各种错误的错误位。 错误处理
//本示例中不是为了简单起见。 请参阅
// API 文档,了解有关错误状态位的详细信息。
//读取此状态的操作将清除中断。 如果
// CAN 外设未与其它 CAN 器件连接到 CAN 总线
//存在,则会发生错误,并在中指示
//控制器状态。
//
ulStatus = CANStatusGet (CAN0_BASE、CAN_STS_CONTROL); // CAN_STS_NEWDAT
//
//设置一个标志来指示可能发生的某些错误。
//
CAN_Manager.g_BErrFlag = 1;
return; //我们是否要返回这里?
}
if (ulStatus = 1)//如果 msg 对象为1,则接收到的消息可以 obj 1
{
CANIntClear (CAN0_BASE、1);
CAN_Manager.g_ulMsg1Count++;
CAN_Manager.g_BErrFlag = 0;
}
否则、如果(ulStatus = 2) //如果 msg 对象为2、则接收到的消息可以 obj 2
{
CANIntClear (CAN0_BASE、2);
CAN_Manager.g_ulMsg2Count++;
CAN_Manager.g_BErrFlag = 0;
}
否则、如果(ulStatus = 3)
{
CANIntClear (CAN0_BASE、3);
CAN_Manager.g_ulMsg3Count++;
CAN_Manager.g_bMsgObj3Sent = 1;
CAN_Manager.g_BErrFlag = 0;
}
否则、如果(ulStatus = 8)
{
CANIntClear (CAN0_BASE、8);
CAN_Manager.g_ulMsg3Count++;
CAN_Manager.g_bMsgObj3Sent = 1;
CAN_Manager.g_BErrFlag = 0;
}
否则、如果(ulStatus = 16)
{
CANIntClear (CAN0_BASE、16);
CAN_Manager.g_ulMsg3Count++;
CAN_Manager.g_bMsgObj3Sent = 1;
CAN_Manager.g_BErrFlag = 0;
}
//
//否则,发生意外导致中断的情况。 这应该是
//永远不会发生。
//
其他
{
//
//可以在此处执行伪中断处理。
//
}
}
我可能错过了一些简单的东西、但我还没有找到。
谢谢、
道格