嗨,我对 RTR 有疑问,如何在 s32k144 中设置 RTR 位以及如何接收 RTR 请求和发送响应?你能帮我一下吗?
void FLEXCAN0_init(void) {
#define MSG_BUF_SIZE 4 /* 消息缓冲区大小。(CAN 2.0AB: 2 hdr + 2 data= 4 words) */
uint32_t i=0;
PCC->PCCn[PCC_FlexCAN0_INDEX] |= PCC_PCCn_CGC_MASK;/* CGC=1: 使能时钟到 FlexCAN0 */
CAN0->MCR |= CAN_MCR_MDIS_MASK;/* MDIS=1: 在选择时钟之前禁用模块 */
CAN0->CTRL1 &= ~CAN_CTRL1_CLKSRC_MASK; /* CLKSRC=0: 时钟源 = 振荡器 (8 MHz) */
CAN0->MCR &= ~CAN_MCR_MDIS_MASK;/* MDIS=0; 启用模块配置。(设置 FRZ,暂停)*/
while (!((CAN0->MCR & CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT)) {}
/* 好的做法:在冻结模式进入/退出时等待 FRZACK=1 */
CAN0->CTRL1 = 0x00DB0006;/* 配置 500 KHz 位时间 */
/* 时间份额 freq = 16 时间份额 x 500 KHz 位时间 = 8MHz */
/* PRESDIV+1 = Fclksrc/Ftq = 8 MHz/8 MHz = 1 */ /
* 所以PRESDIV = 0 */
/* PSEG2 = Phase_Seg2 - 1 = 4 - 1 = 3 */
/* PSEG1 = PSEG2 = 3 */
/* PROPSEG= Prop_Seg - 1 = 7 - 1 = 6 */ /
* RJW: 自 Phase_Seg2 >=4,RJW+1=4 所以 RJW=3。*/
/* SMP = 1:每个 CAN 样本使用 3 位 */
/* CLKSRC=0(未更改):Fcanclk= Fosc= 8 MHz */
for(i=0; i<128; i++ ) { /* CAN0: 清除 32 msg bufs x 4 words/msg buf = 128 words*/ CAN0->RAMn[
i] = 0; /* 清除 msg buf 字 */
}
for(i=0; i<16; i++ ) { /* 在 FRZ 模式下,初始化 CAN0 16 msg buf 过滤器 */
CAN0->RXIMR[i] = 0xFFFFFFFF; /* 检查传入消息的所有 ID 位 */
}
CAN0->RXMGMASK = 0xFFFFFFFF; /* 全局接受掩码:检查所有 ID 位 */
// CAN0->RAMn[ 0*MSG_BUF_SIZE + 0] = 0x0C400000 | 8
/* EDL、BRS、ESI=0:CANFD 未使用 */
/* CODE=4:MB 设置为 RX 未激活 */
/* IDE=0:标准 ID */
/* SRR、RTR、
tiME STAMP = 0:不适用 */
// CAN0->RAMn[ 0*MSG_BUF_SIZE + 0] = 0x0C500000 | 8
#else /* 节点 B 接收标准 ID 为 0x555 的消息 */
CAN0->RAMn[ 4*MSG_BUF_SIZE + 1] = 0x15540000; /* 消息缓冲区 4,字 1:标准 ID = 0x555 */
#endif
/* PRIO = 0: CANFD 未使用 */
CAN0->MCR = 0x0000001F; /* 否定 FlexCAN 1 暂停状态 32 MB */
while ((CAN0->MCR && CAN_MCR_FRZACK_MASK) >> CAN_MCR_FRZACK_SHIFT) {}
/* 好的做法:等待 FRZACK 清除(不处于冻结模式)*/
while ((CAN0 ->MCR && CAN_MCR_NOTRDY_MASK) >> CAN_MCR_NOTRDY_SHIFT) {}
/* 好的做法:等待 NOTRDY 清除(模块准备就绪)*/
}
void FLEXCAN0_transmit_msg(uint32_t sndId,uint8_t *pdata) { /* 假设:消息缓冲区 CODE 未激活 */
CAN0->IFLAG1 = 0x00000001;/* 清除 CAN 0 MB 0 标志而不清除其他标志 */
CAN0->RAMn[0*MSG_BUF_SIZE + 2] = 0xA5112233;/* MB0 字 2:数据字 0 */
CAN0->RAMn[ 0*MSG_BUF_SIZE + 3] = 0x44556677; /* MB0 字 3:数据字 1 */
#ifdef NODE_A
// CAN0->RAMn[ 0*MSG_BUF_SIZE + 1] = 0x15540000; /* MB0 字 1:发送带有 STD ID 0x555 的消息 */
CAN0->RAMn[ 0*MSG_BUF_SIZE + 1] = sndId << 18; /* MB0 字 1:带有 STD ID 0x555 的 Tx 消息 */
#else
CAN0->RAMn[ 0*MSG_BUF_SIZE + 1] = 0x14440000; /* MB0 字 1:带有 STD ID 0x511 的 Tx 消息 */
#endif
CAN0->RAMn[ 0*MSG_BUF_SIZE + 0] = 0x0C400000 | 8
> 24; /* 读取代码字段 */
// RxID = (CAN0->RAMn[ 4*MSG_BUF_SIZE + 1] & CAN_WMBn_ID_ID_MASK) >> CAN_WMBn_ID_ID_SHIFT ;
*msgId =((CAN0->RAMn[ 4*MSG_BUF_SIZE + 1] & 0x1ffc0000UL) >> 18) ;
RxLENGTH = (CAN0->RAMn[ 4*MSG_BUF_SIZE + 0] & CAN_WMBn_CS_DLC_MASK)>>CAN_WMBn_CS_DLC_SHIFT ;
// RxLENGTH = (CAN0->RAMn[ 4*MSG_BUF_SIZE + 0] & CAN_WMBn_CS_DLC_MASK) >>CAN_WMBn_CS_DLC_MASK ;
for (j=0; j<2; j++) { /* 读取两个字的数据(8字节) */
RxDATA[j] = CAN0->RAMn[ 4*MSG_BUF_SIZE + 2 + j];
}
RxTIMESTAMP = (CAN0->RAMn[ 0*MSG_BUF_SIZE + 0] & 0x000FFFF);
虚拟= CAN0->定时器;/* 读取 TIMER 以解锁消息缓冲区 */
CAN0->IFLAG1 = 0x00000010; /* 清除 CAN 0 MB 4 标志而不清除其他标志 */
}