本帖最后由 袁胜富 于 2024-12-17 02:24 编辑
#申请原创# 一、CAN基本知识
CAN(控制局域网),总线分为CAN_H和CAN_L。CAN的数据包的帧ID分为:标准ID(0X00)和拓展ID(0X01),标准帧ID范围:0-0x7FF,拓展ID范围:0-0x1FFFFFFF。帧类型分为:数据帧(0X00)和远程帧(0X01)。数据包组成格式:standard_id(4Bytes)[标准ID]+extended_id(4Bytes)[拓展ID]+id_type(1Byte)[ID类型]+frame_type(1Byte)[帧类型]+dlc(1Byte)[帧数据长度]+data(8Bytes)[数据]。
CAN在许多领域都有应用,如汽车传感器,BMS,电机控制等。
二、G32A1465CAN配置流程
A.配置GPIO
PIN_SETTINGS_CFG_T g_pinsConfig[NUM_OF_CONFIGURED_PINS0] = {
{
//解释为:PME4为CAN0的RX数据接收引脚,不接上下拉电阻,低驱动能力,复用功能5
.base = PME,
.pinPmIdx = 4U,
.pullCfg = PM_INTERNAL_PULL_NOT_ENABLED,
.drvSel = PM_LOW_DRIVE_STRENGTH,
.passiveFilt = false,
.mux = PM_MUX_ALT5,
.pinLk = false,
.intCfg = PM_DMA_INT_DISABLED,
.clrInt** = false,
.gpioBase = NULL,
.digitFilt = false,
},
{
//解释为:PME5为CAN0的TX数据发送引脚,不接上下拉电阻,低驱动能力,复用功能5
.base = PME,
.pinPmIdx = 5U,
.pullCfg = PM_INTERNAL_PULL_NOT_ENABLED,
.drvSel = PM_LOW_DRIVE_STRENGTH,
.passiveFilt = false,
.mux = PM_MUX_ALT5,
.pinLk = false,
.intCfg = PM_DMA_INT_DISABLED,
.clrInt** = false,
.gpioBase = NULL,
.digitFilt = false,
}
};
B.配置CAN
/*最大邮箱3个两个数据接收邮箱,一个数据发送邮箱,工作发送为普通模式,不打开接收缓冲,使用8M时钟作为CAN的时钟源*/
/*通过用户手册可知:CAN的波特率 = fpclk/((preDiv+1)*(1+(propSeg+phaseSeg1+2)+(phaseSeg2+1)))*/
CAN_USER_CONFIG_T g_canConfig = {
.maxMbNumber = 3, /* 2 Rx MBs and 1 Tx MB */
.operationMode = CAN_MODE_NORMAL,
.rxFifoEnable = false,
.rxFifoFilterNum = CAN_RXFIFO_ID_FILTERS_8,
.rxFifoTransferType = CAN_RXFIFO_USE_INTERRUPT,
.rxFifoDmaChannel = 0,
.fdEnable = false,
.fdPayloadSize = CAN_FD_PAYLOAD_SIZE_16,
.clockSource = CAN_CLOCK_SOURCE_OSC,
.bitrate = {
/*根据手册测试出常用波特率的配置如下,250K bps,500K bps,1Mbps*/
/*250k bps*/
// .preDiv = 1,
// .propSeg = 7,
// .phaseSeg1 = 4,//propSeg+phaseSeg1 = timeSegment1
// .phaseSeg2 = 1,//phaseSeg2 = timeSegment2
// .resyncJumpWidth = 2
/*500kbps*/
// .preDiv = 0,
// .propSeg = 7,
// .phaseSeg1 = 4,//propSeg+phaseSeg1 = timeSegment1
// .phaseSeg2 = 1,//phaseSeg2 = timeSegment2
// .resyncJumpWidth = 2
/*1M bps*/
.preDiv = 0,
.propSeg = 1,
.phaseSeg1 = 2,//propSeg+phaseSeg1 = timeSegment1
.phaseSeg2 = 1,//phaseSeg2 = timeSegment2
.resyncJumpWidth = 2
},
.fdBitrate = {
.preDiv = 0,
.propSeg = 0,
.phaseSeg1 = 0,
.phaseSeg2 = 0,
.resyncJumpWidth = 0
}
};C.发送邮箱配置
/*配置为标准帧,8字节长度*/
/* Configure Tx MB */
CAN_DATA_INFO_T txMbInfo = {
.msgIdType = CAN_ID_STANDARD, /* Standard CAN ID */
.dataLen = 8, /* Used only to initialize the MB, will be updated when send data */
.fdEnable = false, /* Disable CAN FD */
.isRemote = false};
CAN_ConfigureTxMb(CAN0_INSTANCE, TX_MB, &txMbInfo, 0);
D.接收邮箱配置
/* Use individual Rx masking for the MBs */
CAN_SetRxMaskType(CAN0_INSTANCE, CAN_RX_MASK_INDIVIDUAL);
/* Configure Rx MB0, it will receive standard frames with ID 1 */
CAN_DATA_INFO_T rxMb0Info = {
.msgIdType = CAN_ID_STANDARD, /* Standard CAN ID */
.dataLen = 8, /* Max data length for classic CAN is 8 bytes */
.fdEnable = false, /* Disable CAN FD */
.isRemote = false};
CAN_ConfigureRxMb(CAN0_INSTANCE, RX_MB_0, &rxMb0Info, RX_CAN_MESSAGE_ID);
CAN_SetRxIndividualMask(CAN0_INSTANCE, CAN_ID_STANDARD, RX_MB_0, 0xFFFFFFFF);
/* Configure Rx MB1, it will receive extended frames with ID 1 */
CAN_DATA_INFO_T rxMb1Info = {
.msgIdType = CAN_ID_EXTENDED, /* Extended CAN ID */
.dataLen = 8, /* Max data length for classic CAN is 8 bytes */
.fdEnable = false, /* Disable CAN FD */
.isRemote = false};
CAN_ConfigureRxMb(CAN0_INSTANCE, RX_MB_1, &rxMb1Info, RX_CAN_MESSAGE_ID);
CAN_SetRxIndividualMask(CAN0_INSTANCE, CAN_ID_EXTENDED, RX_MB_1, 0x000000);
/* Set the CAN event callback handler */
CAN_InstallEventCallback(CAN0_INSTANCE, &CanEventCallback, NULL);
E.设置数据接收结构体变量
/* Receive CAN frames from MB0 and MB1 */
CAN_MSG_BUF_T rxFrame0;
CAN_MSG_BUF_T rxFrame1;
三、实验
A.按下按键Key1发送
/*!
* @brief This function is called when the KEY1 button is pressed
*/
void Key1Handler(void)
{
/* Send standard CAN frame */
uint8_t payload[8] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37};
CAN_DATA_INFO_T txDataInfo = {
.msgIdType = CAN_ID_STANDARD, /* Standard CAN ID */
.dataLen = sizeof(payload), /* Payload size */
.fdEnable = false,
.isRemote = false};
CAN_SendNonBlocking(CAN0_INSTANCE, TX_MB, &txDataInfo, TX_CAN_MESSAGE_ID_1, payload);
}
B.按下按键Key2发送
/* Send extended CAN frame */
uint8_t payload[7] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36};
CAN_DATA_INFO_T txDataInfo = {
.msgIdType = CAN_ID_EXTENDED, /* Extended CAN ID */
.dataLen = sizeof(payload), /* Payload size */
.fdEnable = false,
.isRemote = false};
CAN_SendNonBlocking(CAN0_INSTANCE, TX_MB, &txDataInfo, TX_CAN_MESSAGE_ID_2, payload);
C.接收邮箱0经过过滤设置,只接收ID为1的标准帧。
D.接收邮箱1没有经过过滤设置,可以接收范围内合法的所有拓展帧ID。
四、实验结果
A:
B:
C:
D:
五、心得体会
新的MCU需要阅读数据手册和用户手册,知识的学习需要理论和实践才能得到新知。非常感谢极海半导体提供这次机会,在忙里偷闲中参加此次活动,希望和大家一起探讨学习新的知识技术。谢谢官方机会,谢谢大家。
|
|