SDKのCAN通信S32K144 DEMOを使い、修正を加えた結果、拡張フレームの送信は失敗しました。idTypeはすでにCAN_MSG_ID_EXTに変更しましたが、CANアダプターは標準フレームを受け取りました。私が送信したIDは1FFFFFFFでしたが、受信したIDは7FFでした。専門家の方がこの問題の解決に協力していただけるとありがたいです。
#include "Cpu.h"
#include "delay.h"
#include "uart.h"
#include"key.h"
#include"oled.h"
#include "stdint.h"
#include "stdbool.h"
volatile int exit_code = 0;
#define LED1(x) PINS_DRV_WritePin(PTD,16,!x);
#define LED2(x) PINS_DRV_WritePin(PTD,15,!x);
#define LED3(x) PINS_DRV_WritePin(PTD,1,!x);
#define LED4(x) PINS_DRV_WritePin(PTD,0,!x);
#define Rx_Filter 0x0
char IRQ_CAN0_RX;
char IRQ_CAN1_RX;
char IRQ_CAN2_RX;
can_message_t recvMsg_CAN0;
can_message_t recvMsg_CAN1;
can_message_t recvMsg_CAN2;
#define RX_MASK_ALL_EXT 0x1FFFFFFF
#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)
/*CAN0回调関数*/
void CAN0_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState; //此处防止警报
(void)インスタンス;
(void)buffIdx;
CAN_Receive(&can_pal0_instance, RX_MAILBOX_CAN0, &recvMsg_CAN0); //受信收报文并再注册回调関数
スイッチ(イベント情報) //回调事件
{
CASE CAN_EVENT_RX_COMPLETE: //接收完成 事件
IRQ_CAN0_RX = 1;
壊す;
CASE CAN_EVENT_TX_COMPLETE: //发送完成事件
壊す;
デフォルト:
壊す;
}
}
void CAN1_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)インスタンス;
(void)buffIdx;
CAN_Receive(&can_pal1_instance, RX_MAILBOX_CAN1, &recvMsg_CAN1);
スイッチ(イベント情報)
{
CASE CAN_EVENT_RX_COMPLETE:
IRQ_CAN1_RX = 1;
壊す;
CASE CAN_EVENT_TX_COMPLETE:
壊す;
デフォルト:
壊す;
}
}
void CAN2_Callback_Func (uint32_t instance,can_event_t event,uint32_t buffIdx,void *flexcanState)
{
(void)flexcanState;
(void)インスタンス;
(void)buffIdx;
CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2);
スイッチ(イベント情報)
{
CASE CAN_EVENT_RX_COMPLETE:
IRQ_CAN2_RX = 1;
壊す;
CASE CAN_EVENT_TX_COMPLETE:
壊す;
デフォルト:
壊す;
}
}
void CAN0_Init(void)
{
CAN_Init(&can_pal0_instance, &can_pal0_Config0);
can_buff_config_t Rx_buffCfg = {
.enableFD= 偽、
.enableBRS= 偽、
.fdPadding= 0U、
.idType= CAN_MSG_ID_EXT、
.isRemote= 偽
};
can_buff_config_t Tx_buffCfg = {
.enableFD= 偽、
.enableBRS= 偽、
.fdPadding= 0U、
.idType= CAN_MSG_ID_EXT、
.isRemote= 偽
};
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 のコードを設定します。コードの大まかな値は 11 ビットの MSGID アドレスのフィルタであると理解できます。
特定のビットを 1 に設定する必要がある場合は、0 に設定する必要はありません。たとえば、コードが 0x7ff に設定されている場合は、すべての標準 ID が必要です。0x7fe に設定されている場合、これは 0x01 の文 (0x0 のアドレスは存在しません)*/ のみを受け入れることができます。
CAN_SetRxFilter(&can_pal0_instance, CAN_MSG_ID_EXT, RX_MAILBOX_CAN0, 0x1FFFFFFFU);//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= 偽、
.enableBRS= 偽、
.fdPadding= 0U、
.idType= CAN_MSG_ID_EXT、
.isRemote= 偽
};
can_buff_config_t Tx_buffCfg = {
.enableFD= 偽、
.enableBRS= 偽、
.fdPadding= 0U、
.idType= CAN_MSG_ID_EXT、
.isRemote= 偽
};
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_EXT,RX_MAILBOX_CAN1,0x1FFFFFFFU);
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= 偽、
.enableBRS= 偽、
.fdPadding= 0U、
.idType= CAN_MSG_ID_EXT、
.isRemote= 偽
};
can_buff_config_t Tx_buffCfg = {
.enableFD= 偽、
.enableBRS= 偽、
.fdPadding= 0U、
.idType= CAN_MSG_ID_EXT、
.isRemote= 偽
};
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_EXT,RX_MAILBOX_CAN2,0x1FFFFFFFU);
CAN_InstallEventCallback(&can_pal2_instance,&CAN2_Callback_Func,(void*)0);
CAN_Receive(&can_pal2_instance, RX_MAILBOX_CAN2, &recvMsg_CAN2);
}
int main(void)
{
/* ここにローカル変数の定義を記述してください */
uint8_t pinstate;
int MCU_Freq;
uint8_t CANRXDATA_STR1[17];
uint8_t CANRXDATA_STR2[17];
/*** プロセッサ Expert 内部初期化。このコードを削除しないでください!!! ***/
#ifdef PEX_RTOS_INIT
PEX_RTOS_INIT(); /* 選択されたRTOSの初期化。マクロはRTOSコンポーネントによって定義されます。*/
#endif
/*** プロセッサエキスパートの内部初期化終了。 ***/
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 = late_init();//初期化遅延関数数
PINS_DRV_Init(NUM_OF_CONFIGURED_PINS, g_pin_mux_InitConfigArr); //初期化IO
I2C_MasterInit(&i2c1_instance, &i2c1_MasterConfig0);//初期化 I2C 外部設定、OLED 通讯用
LPUART_DRV_Init(INST_LPUART1, &lpuart1_State, &lpuart1_InitConfig0); //初期化串口
CAN0_Init();
CAN1_Init();
CAN2_Init();
oled_init(); //OLED 構成パラメータの初期化
OLED_TITLE((uint8_t*)"S32K144",(uint8_t*)" CAN");//OLED显示标题
u1_printf("初期化完了,MCU の動作周波数は %d Mhz \r\n",MCU_Freq);
while(1)
{
/*按键处理*/
pinstate = KEY_Proc (0);
/*if(pinstate ==BTN1_PRES )
{
can_message_t Tx_msg = {
.cs = 0U、
.id = 0x01、
.data[0] = 0x0、
.data[1] = 0x1、
.data[2] = 0x2、
.data[3] = 0x3、
.data[4] = 0x4、
.data[5] = 0x5、
.data[6] = 0x6、
.data[7] = 0x7、
.length = 8
};
CAN_Send(&can_pal0_instance, TX_MAILBOX_CAN0, &Tx_msg);
u1_printf("CAN0送信报文\r\n");
}
else if(pinstate == BTN2_PRES )
{
can_message_t Tx_msg = {
.cs = 0U、
.id = 0x02、
.data[0] = 0x20、
.data[1] = 0x21、
.data[2] = 0x22、
.data[3] = 0x23、
.data[4] = 0x24、
.data[5] = 0x25、
.data[6] = 0x26、
.data[7] = 0x27、
.length = 8
};
CAN_Send(&can_pal1_instance, TX_MAILBOX_CAN1, &Tx_msg);
u1_printf("CAN1送信报文\r\n");
}
else if(pinstate == BTN3_PRES )
{
can_message_t Tx_msg = {
.cs = 0U、
.id = 0x03、
.data[0] = 0x30、
.data[1] = 0x31、
.data[2] = 0x32、
.data[3] = 0x33、
.data[4] = 0x34、
.data[5] = 0x35、
.data[6] = 0x36、
.data[7] = 0x37、
.length = 8
};
CAN_Send(&can_pal2_instance, TX_MAILBOX_CAN2, &Tx_msg);
u1_printf("CAN2送信报文\r\n");
}*/
u1_printf("123456\r\n");
/* can_message_t Tx_msg = {
.cs = 0U、
.id = 0x03、
.data[0] = 0x30、
.data[1] = 0x31、
.data[2] = 0x32、
.data[3] = 0x33、
.data[4] = 0x34、
.data[5] = 0x35、
.data[6] = 0x36、
.data[7] = 0x37、
.length = 8
};
CAN_Send(&can_pal1_instance, TX_MAILBOX_CAN1, &Tx_msg);*/
// 標準コードを送信します(照合用)
delay_ms(100);
can_message_t std_msg0 = {
.cs = 0U、
.id = 0x1FFFF111U、
.data[0] = 0x30、
.data[1] = 0x31、
.data[2] = 0x32、
.data[3] = 0x33、
.data[4] = 0x34、
.data[5] = 0x35、
.data[6] = 0x36、
.data[7] = 0x37、
.length = 8
};
status_t ret = CAN_Send(&can_pal2_instance, TX_MAILBOX_CAN2, &std_msg0);
if(ret != STATUS_SUCCESS)
{
u1_printf("CAN2 std_msg0 送信失敗、戻り値:%d\r\n",ret);
}
delay_ms(100);
can_message_t Tx_msg0 = {
.cs = 0U、
.id = 0x1FFFFFFFU、
.data[0] = 0x30、
.data[1] = 0x31、
.data[2] = 0x32、
.data[3] = 0x33、
.data[4] = 0x34、
.data[5] = 0x35、
.data[6] = 0x36、
.data[7] = 0x37、
.length = 8
};
CAN_Send(&can_pal2_instance, TX_MAILBOX_CAN2, &Tx_msg0);
delay_ms(100);
if (IRQ_CAN0_RX == 1)
{
int i;
u1_printf("CAN0 RECV ID:0x%x \r\n",recvMsg_CAN0.id);
for(i=0; i
{
u1_printf("データ %d : %x\r\n",i,recvMsg_CAN0.data[i]);
if(i==recvMsg_CAN0.length-1) u1_printf("***************\r\n");
}
IRQ_CAN0_RX=0;
}
if (IRQ_CAN1_RX == 1)
{
int i;
u1_printf("CAN1 RECV ID:0x%x \r\n",recvMsg_CAN1.id);
for(i=0; i
{
u1_printf("データ %d : %x\r\n",i,recvMsg_CAN1.data[i]);
if(i==recvMsg_CAN1.length-1) u1_printf("***************\r\n");
}
IRQ_CAN1_RX=0;
}
if (IRQ_CAN2_RX == 1)
{
int i;
u1_printf("CAN2 RECV ID:0x%x \r\n",recvMsg_CAN2.id);
for(i=0; i
{
u1_printf("データ %d : %x\r\n",i,recvMsg_CAN2.data[i]);
if(i==recvMsg_CAN2.length-1) u1_printf("***************\r\n");
}
IRQ_CAN2_RX=0;
}
/*OLED表示*/
sprintf((char*)CANRXDATA_STR1,"CAN0 %02X %02X %02X %02X",
recvMsg_CAN2.data[0]、recvMsg_CAN2.data[1]、recvMsg_CAN2.data[2]、recvMsg_CAN2.data[3]);
// 変更点:删除(uint8_t)强转,格式符変更は%08X
sprintf((char*)CANRXDATA_STR2,"ID:%08X %02X %02X %02X %02X",
recvMsg_CAN2.id、recvMsg_CAN2.data[4]、recvMsg_CAN2.data[5]、recvMsg_CAN2.data[6]、recvMsg_CAN2.data[7]);
OLED_ShowString(0,2,CANRXDATA_STR1,8,0);
OLED_ShowString(0,3,CANRXDATA_STR2,8,0);
/*sprintf((char*)CANRXDATA_STR1,"CAN1 %02X %02X %02X %02X",recvMsg_CAN1.data[0],recvMsg_CAN1.data[1],recvMsg_CAN1.data[2],recvMsg_CAN1.data[3]);
sprintf((char*)CANRXDATA_STR2,"ID%02X %02X %02X %02X %02X",(uint8_t)recvMsg_CAN1.id,recvMsg_CAN1.data[4],recvMsg_CAN1.data[5],recvMsg_CAN1.data[6],recvMsg_CAN1.data[7]);
OLED_ShowString(0,4,CANRXDATA_STR1,8,0);
OLED_ShowString(0,5,CANRXDATA_STR2,8,0);
sprintf((char*)CANRXDATA_STR1,"CAN2 %02X %02X %02X %02X",recvMsg_CAN2.data[0],recvMsg_CAN2.data[1],recvMsg_CAN2.data[2],recvMsg_CAN2.data[3]);
sprintf((char*)CANRXDATA_STR2,"ID%02X %02X %02X %02X %02X",(uint8_t)recvMsg_CAN2.id,recvMsg_CAN2.data[4],recvMsg_CAN2.data[5],recvMsg_CAN2.data[6],recvMsg_CAN2.data[7]);
OLED_ShowString(0,6,CANRXDATA_STR1,8,0);
OLED_ShowString(0,7,CANRXDATA_STR2,8,0);*/
/*OLED表示*/
PINS_DRV_TogglePins(PTD, 1 << 0);
PINS_DRV_TogglePins(PTD, 1 << 1);
PINS_DRV_TogglePins(PTD, 1 << 15);
PINS_DRV_TogglePins(PTD, 1 << 16);
delay_ms(100);
}
/*** この行より先にコードを記述しないでください。記述すると、コード生成時に削除されます。***/
/*** RTOS 起動コード。マクロPEX_RTOS_STARTはRTOSコンポーネントによって定義されます。このコードを変更しないでください!!! ***/
#ifdef PEX_RTOS_START
PEX_RTOS_START(); /* 選択されたRTOSの起動。マクロはRTOSコンポーネントによって定義されます。*/
#endif
/*** RTOS起動コードの終了。***/
/*** プロセッサ Expert メインルーチン終了。このコードを変更しないでください!!! ***/
のために(;;) {
if(exit_code != 0) {
壊す;
}
}
終了コードを返します。
/*** プロセッサ Expert メインルーチン終了。以下にコードを書かないでください!!! ***/
} /*** メインルーチンの終了。このテキストは変更しないでください!!! ***/
/* メイン処理終了 */
/*!
** @}
*/
/*
** ###################################################################
**
** このファイルはプロセッサ Expert 10.1 [05.21]によって作成されました
** NXP S32Kシリーズのマイクロコントローラ用。
**
** ###################################################################
*/