I attach the main() function code below:
#define LED1(x) PINS_DRV_WritePin(PTA,1,!x);//RED
#define LED2(x) PINS_DRV_WritePin(PTB,8,!x);//GREEN
#define LED3(x) PINS_DRV_WritePin(PTB,9,!x);//BLUE
can_message_t canX_Tx_msg[10] = {
{.cs = 0U, .id = 0x06, .data = "01234567", .length = 8},
{.cs = 0U, .id = 0x06, .data = "12345678", .length = 8},
{.cs = 0U, .id = 0x06, .data = "23456789", .length = 8},
{.cs = 0U, .id = 0x06, .data = "34567890", .length = 8},
{.cs = 0U, .id = 0x06, .data = "45678901", .length = 8},
{.cs = 0U, .id = 0x06, .data = "56789012", .length = 8},
{.cs = 0U, .id = 0x06, .data = "67890123", .length = 8},
{.cs = 0U, .id = 0x06, .data = "78901234", .length = 8},
{.cs = 0U, .id = 0x06, .data = "89012345", .length = 8},
{.cs = 0U, .id = 0x06, .data = "90123456", .length = 8},
};
#define Rx_Filter 0x0
char IRQ_CAN0_RX = 0;
char IRQ_CAN1_RX = 0;
char IRQ_CAN2_RX = 0;
char IRQ_CAN0_RX_SUCC = 0;
char IRQ_CAN1_RX_SUCC = 0;
char IRQ_CAN2_RX_SUCC = 0;
uint32_t can0_tx_total_cnt = 0;
uint32_t can0_rx_total_cnt = 0;
uint32_t can0_rx_succ_cnt = 0;
uint32_t can0_rx_fail_cnt = 0;
uint32_t can1_tx_total_cnt = 0;
uint32_t can1_rx_total_cnt = 0;
uint32_t can1_rx_succ_cnt = 0;
uint32_t can1_rx_fail_cnt = 0;
can_message_t recvMsg_CAN0;
can_message_t recvMsg_CAN1;
can_message_t recvMsg_CAN2;
#define RX_MAILBOX_CAN0 (0UL)
#define TX_MAILBOX_CAN0 (1UL)
#define RX_MAILBOX_CAN1 (2UL)
#define TX_MAILBOX_CAN1 (3UL)
#define RX_MAILBOX_CAN2 (4UL)
#define TX_MAILBOX_CAN2 (5UL)
void can_normal_en(int canSn)
{
if(canSn == 0)
{
PINS_DRV_ClearPins(PTD, 1 << 9);
}
if(canSn == 1)
{
PINS_DRV_ClearPins(PTB, 1 << 4);
}
if(canSn == 2)
{
PINS_DRV_ClearPins(PTC, 1 << 11);
}
}
void can_silent_en(int canSn)
{
if(canSn == 0)
{
PINS_DRV_SetPins(PTD, 1 << 9);
}
if(canSn == 1)
{
PINS_DRV_SetPins(PTB, 1 << 4);
}
if(canSn == 2)
{
PINS_DRV_SetPins(PTC, 1 << 11);
}
}
/*CAN0回调函数*/
void CAN0_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState; //此处防止警报
(void)instance;
(void)buffIdx;
if(CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0) == STATUS_SUCCESS)//接收报文并重新注册回调函数
IRQ_CAN0_RX_SUCC = 1;
else
IRQ_CAN0_RX_SUCC = 0;
switch(event) //回调事件
{
case CAN_EVENT_RX_COMPLETE: //接收完成事件
IRQ_CAN0_RX = 1;
break;
case CAN_EVENT_TX_COMPLETE: //发送完成事件
break;
default:
break;
}
}
void CAN1_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)instance;
(void)buffIdx;
if(CAN_Receive(&can_pal1_instance, RX_MAILBOX_CAN1, &recvMsg_CAN1) == STATUS_SUCCESS)//接收报文并重新注册回调函数
IRQ_CAN1_RX_SUCC = 1;
else
IRQ_CAN1_RX_SUCC = 0;
switch(event)
{
case CAN_EVENT_RX_COMPLETE:
IRQ_CAN1_RX = 1;
break;
case CAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
void CAN2_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)instance;
(void)buffIdx;
if(CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2) == STATUS_SUCCESS)//接收报文并重新注册回调函数
IRQ_CAN2_RX_SUCC = 1;
else
IRQ_CAN2_RX_SUCC = 0;
switch(event)
{
case CAN_EVENT_RX_COMPLETE:
IRQ_CAN2_RX = 1;
break;
case CAN_EVENT_TX_COMPLETE:
break;
default:
break;
}
}
void CAN0_Init(void)
{
CAN_Init(&can_pal0_instance, &can_pal0_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
CAN_ConfigRxBuff(&can_pal0_instance, RX_MAILBOX_CAN0, &Rx_buffCfg, Rx_Filter); //注册接收配置和MSGID过滤器(如过滤器配置为0x1,则只接受msgid 0x1发来的报文)
CAN_ConfigTxBuff(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_buffCfg); //配置发送
/*设置MSGID的掩码,掩码粗略可以理解为对11bit MSGID地址的过滤
如果某bit位需要过滤设置为1,不过滤设置为0,例如掩码设置为0x7ff则过滤全部标准id,如果设置为0x7fe,这只能接受0x01的报文(不存在0x0的地址)*/
CAN_SetRxFilter(&can_pal0_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN0,0); //设置MSGID掩码,
CAN_InstallEventCallback(&can_pal0_instance,&CAN0_Callback_Func,(void*)0); //注册回调函数
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //*****重点****此函数不只有接收作用 还有续订回调函数的作用.
}
void CAN1_Init(void)
{
CAN_Init(&can_pal1_instance, &can_pal1_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
CAN_ConfigRxBuff(&can_pal1_instance, RX_MAILBOX_CAN1, &Rx_buffCfg, Rx_Filter);
CAN_ConfigTxBuff(&can_pal1_instance, TX_MAILBOX_CAN1, &Tx_buffCfg);
CAN_SetRxFilter(&can_pal1_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN1,0);
CAN_InstallEventCallback(&can_pal1_instance,&CAN1_Callback_Func,(void*)0);
CAN_Receive(&can_pal1_instance, RX_MAILBOX_CAN1, &recvMsg_CAN1);
}
void CAN2_Init(void)
{
CAN_Init(&can_pal2_instance, &can_pal2_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
can_buff_config_t Tx_buffCfg = {
.enableFD = false,
.enableBRS = false,
.fdPadding = 0U,
.idType = CAN_MSG_ID_STD,
.isRemote = false
};
CAN_ConfigRxBuff(&can_pal2_instance, RX_MAILBOX_CAN2, &Rx_buffCfg, Rx_Filter);
CAN_ConfigTxBuff(&can_pal2_instance, TX_MAILBOX_CAN2, &Tx_buffCfg);
CAN_SetRxFilter(&can_pal2_instance,CAN_MSG_ID_STD,RX_MAILBOX_CAN2,0);
CAN_InstallEventCallback(&can_pal2_instance,&CAN2_Callback_Func,(void*)0);
CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2);
}
int main(void)
{
int MCU_Freq;
int sendGap = 200;
/*** Processor Expert internal initialization. DON'T REMOVE THIS CODE!!! ***/
#ifdef PEX_RTOS_INIT
PEX_RTOS_INIT(); /* Initialization of the selected RTOS. Macro is defined by the RTOS component. */
#endif
/*** End of Processor Expert internal initialization. ***/
CLOCK_SYS_Init(g_clockManConfigsArr, CLOCK_MANAGER_CONFIG_CNT,g_clockManCallbacksArr, CLOCK_MANAGER_CALLBACK_CNT);
CLOCK_SYS_UpdateConfiguration(0U, CLOCK_MANAGER_POLICY_AGREEMENT);
MCU_Freq = delay_init();//初始化delay函数
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); //初始化IO
CAN0_Init();
CAN1_Init();
CAN2_Init();
FLEXIO_UART_init(); /*! Initialize Timer 0, Shifter 0 to emulate
* an UART transmitter instance, using:
* FXIO_D2 to generate baud-rate (output disabled).
* FXIO_D1 as output shifter pin.
*/
FLEXIO_100KHz_PWM_init(50); /*! Initialize Timer 1 and FXIO_D0 to emulate PWM. */
FLEXIO_UART("CAN_TX_RX_Demo. MCU Run Frequency is %d Mhz \r\n",MCU_Freq);
can_normal_en(0);
can_normal_en(1);
can_normal_en(2);
CAN_Send(&can_pal0_instance, TX_MAILBOX_CAN0, &canX_Tx_msg[can0_tx_total_cnt%10]);
delay_us(sendGap);
while(1)
{
if (IRQ_CAN0_RX)//如果接收到CAN报文会通过串口打印出来
//if(1)
{
IRQ_CAN0_RX = 0;
if(IRQ_CAN0_RX_SUCC)
//if(1)
{
if(strcmp((char *)recvMsg_CAN0.data, (char *)canX_Tx_msg[can0_tx_total_cnt%10].data) == 0)
//if(1)
{
delay_us(sendGap);
IRQ_CAN0_RX_SUCC = 0;
can0_tx_total_cnt++;
CAN_Send(&can_pal0_instance, TX_MAILBOX_CAN0, &canX_Tx_msg[can0_tx_total_cnt%10]);
delay_us(sendGap);
}
else
can0_rx_fail_cnt++;
}
else
can0_rx_fail_cnt++;
if(can0_tx_total_cnt%1000 == 0)
{
FLEXIO_UART("Transmit sendGap=%dus,TxCnt=%d,LastData=<%s>\r\n",sendGap,can0_tx_total_cnt,canX_Tx_msg[can0_tx_total_cnt%10].data);
}
}
if (IRQ_CAN1_RX)//如果接收到CAN报文会通过串口打印出来
{
IRQ_CAN1_RX = 0;
can1_rx_total_cnt++;
if(IRQ_CAN1_RX_SUCC)
{
if(strcmp((char *)recvMsg_CAN1.data, (char *)canX_Tx_msg[can0_tx_total_cnt%10].data) == 0)
{
delay_us(sendGap);
IRQ_CAN1_RX_SUCC = 0;
can1_rx_succ_cnt++;
recvMsg_CAN1.id = 0x08;
CAN_Send(&can_pal1_instance, TX_MAILBOX_CAN1, &recvMsg_CAN1);
delay_us(sendGap);
}
else
can1_rx_fail_cnt++;
}
else
can1_rx_fail_cnt++;
if(can1_rx_total_cnt%1000 == 0)
{
FLEXIO_UART("Receive sendGap=%dus,RxCnt=%d,FailCnt=%d,LastData=<%s>\r\n",sendGap,can1_rx_total_cnt,can1_rx_fail_cnt,recvMsg_CAN1.data);
}
}
}
/*** Don't write any code pass this line, or it will be deleted during code generation. ***/
/*** RTOS startup code. Macro PEX_RTOS_START is defined by the RTOS component. DON'T MODIFY THIS CODE!!! ***/
#ifdef PEX_RTOS_START
PEX_RTOS_START(); /* Startup of the selected RTOS. Macro is defined by the RTOS component. */
#endif
/*** End of RTOS startup code. ***/
/*** Processor Expert end of main routine. DON'T MODIFY THIS CODE!!! ***/
for(;;) {
if(exit_code != 0) {
break;
}
}
return exit_code;
/*** Processor Expert end of main routine. DON'T WRITE CODE BELOW!!! ***/
} /*** End of main routine. DO NOT MODIFY THIS TEXT!!! ***/