int CAN_Switch = 0;
void CAN1IntHandler(void)
{
int32_t ulStatus;
// 通过CANIntStatus函数读取中断的状态
ulStatus = CANIntStatus(CAN1_BASE, CAN_INT_STS_CAUSE);
// 如果是控制器状态中断,则说明出现了某种错误
if(ulStatus == CAN_INT_INTID_STATUS)
{
//读取CAN模块所处的状态,并自动清除中断。
ulStatus = CANStatusGet(CAN1_BASE, CAN_STS_CONTROL);
}
// 检查是否是由message object 1引起的发送中断
else if(ulStatus == 1)
{
// 数据包发送已经完成,清除中断
CANIntClear(CAN1_BASE, 1);
shell_printf("message object1 send succees");
}
// 检查是否是由于message object 2引起的接收中断
else if(ulStatus == 2)
{
// 数据包接收已经完成,清除中断
CANIntClear(CAN1_BASE, 2);
shell_printf("rec message object2 succees");
CAN_Switch = 1;//说明接收到数据
}
}
void Demo3_CANandPCcommunication(void)
{
UART_Init();//UART初始化
SysCtlClockFreqSet((SYSCTL_XTAL_16MHZ | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480), 120000000);
SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOB);
//将PN0和PN1两个引脚的功能选择为执行CAN0模块的功能
GPIOPinConfigure(GPIO_PB0_CAN1RX);
GPIOPinConfigure(GPIO_PB1_CAN1TX);
GPIOPinTypeCAN(GPIO_PORTB_BASE, GPIO_PIN_0 | GPIO_PIN_1);
SysCtlPeripheralEnable(SYSCTL_PERIPH_CAN1);
CANInit(CAN1_BASE);// CAN控制器的初始化
CANBitRateSet(CAN1_BASE, 120000000, 1000000);
CANIntRegister(CAN1_BASE, CAN1IntHandler);
CANEnable(CAN1_BASE);
CANIntEnable(CAN1_BASE, CAN_INT_MASTER | CAN_INT_ERROR | CAN_INT_STATUS);
tCANMsgObject sCANMessage;
tCANMsgObject srCANMessage;
//初始化配置message object,即待发送的报文对象
//配置好报文对象后调用CANMessageSet函数进行设置,
//这样报文就可以自动被发送出去
// 待发送的数据为0
uint8_t ucMsgData[4];
uint8_t ucrMsgData[8];
*(uint32_t *)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.pui8MsgData = 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设置为接收报文对象
CANMessageSet(CAN1_BASE, 2, &srCANMessage, MSG_OBJ_TYPE_RX);//接收
unsigned int uIdx;
while(1)
{
CANMessageSet(CAN1_BASE, 1, &sCANMessage, MSG_OBJ_TYPE_TX);//发送
delay_DelayMs(5000);
if(CAN_Switch)
{
// 建立指向报文数据的缓存区
srCANMessage.pui8MsgData = ucrMsgData;
// 读取接收到的报文对象。
// 将message object中的信息读取到srCANMessage接收对象中
CANMessageGet(CAN1_BASE, 2, &srCANMessage, 0);
// 将CAN_Switch置为0。
//等到下个报文到来时,中断函数会再次将它置1的
CAN_Switch = 0;
// 如果出现数据丢失等错误,则输出提示信息
if(srCANMessage.ui32Flags & MSG_OBJ_DATA_LOST)
{
shell_printf("CAN message loss detected\n");
}
// 通过UART输出接收到的报文信息
shell_printf("ReceiveMsgID = 0x%08X\nlen=%u\ndata=0x",srCANMessage.ui32MsgID,srCANMessage.ui32MsgLen);
// 输出报文中的数据内容
// for(uIdx=0;uIdx<srCANMessage.ui32MsgLen;uIdx++)
// {
// shell_printf("%02X",ucrMsgData[uIdx]);
// }
for(uIdx=0;uIdx<srCANMessage.ui32MsgLen;uIdx++)
{
shell_printf("%02X",srCANMessage.pui8MsgData[uIdx]);
}
shell_printf("\n");
delay_DelayMs(1000);
}
}
}//end Demo3_CANandPCcommunication