5.2 bxCAN 使用说明
本章说明 N32G41x 标准外设库中 bxCAN 驱动的文件组成与 33 个公开函数,内容包括 CAN 的复位与初始化、过滤器配置、运行模式控制、报文发送与接收、错误管理与状态查询、中断与标志管理,并配合 CAN_LoopBack、CAN_Tx_Rx 两个示例演示回环模式与正常模式下的报文收发。寄存器位定义、工作模式、过滤器机制与位时序请配合用户手册的“控制器局域网 (CAN)”章节阅读,芯片已知问题以勘误手册为准。
5.2.1 相关文件
| 相对路径 | 作用 |
|---|---|
firmware/n32g41x_std_periph_driver/inc/n32g41x_can.h |
定义 CAN_InitType、CAN_FilterInitType、CanTxMessage、CanRxMessage 结构体与工作模式、位时序、过滤器、邮箱、标志等宏,并按复位与初始化、配置、运行模式控制、发送、接收、错误管理、状态查询、中断与标志管理八个区段声明 33 个公开函数 |
firmware/n32g41x_std_periph_driver/src/n32g41x_can.c |
实现上述 33 个函数:寄存器复位与位时序、过滤器与运行模式配置、邮箱报文收发、错误计数与状态查询、中断与标志的读写 |
projects/n32g41x_EVAL/examples/bxCAN/ |
bxCAN 示例根目录,含 CAN_LoopBack、CAN_Tx_Rx 2 个示例 |
projects/n32g41x_EVAL/examples/bxCAN/CAN_LoopBack/ |
该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt |
projects/n32g41x_EVAL/bsp/ |
两个示例的工程共同引用的板级支持目录:评估板资源定义与毫秒延时、日志打印等公共实现 |
5.2.2 API 参考
以下 33 个公开函数按 n32g41x_can.h 的声明顺序分为 8 组;每个条目给出功能摘要与 n32g41x_can.c 中该函数正上方的注释原文。
复位与初始化
CAN_DeInit、CAN_Init、CAN_InitStruct、CAN_InitFilter、CAN_SoftwareReset
配置
CAN_DebugFreeze、CAN_EnTTComMode
运行模式控制
CAN_OperatingModeReq、CAN_EnterSleep、CAN_WakeUp
发送
CAN_TransmitMessage、CAN_TransmitSTS、CAN_CancelTransmitMessage
接收
CAN_ReceiveMessage、CAN_ReleaseFIFO、CAN_PendingMessage
错误管理
CAN_GetLastErrCode、CAN_GetReceiveErrCounter、CAN_GetLSBTransmitErrCounter
状态查询
CAN_GetTransmitFailStatus、CAN_GetArbitrationLostStatus、CAN_GetFlagLowestPriority、CAN_GetTransmitMailboxEmptyFlag、CAN_GetReceiveSignal、CAN_GetLastSamplePoint、CAN_GetReceiveMode、CAN_GetTransmitMode、CAN_GetMailboxCode
中断与标志管理
CAN_INTConfig、CAN_GetFlagSTS、CAN_ClearFlag、CAN_GetIntStatus、CAN_ClearINTPendingBit
void CAN_DeInit(const CAN_Module *CANx)将 CAN 外设寄存器反初始化为默认复位值。
name CAN_DeInit
fun Deinitializes the CAN peripheral registers to their default reset values.
param CANx:
- CAN
return none
uint8_t CAN_Init(CAN_Module *CANx, const CAN_InitType *CAN_InitParam)根据 CAN_InitType 结构体中的指定参数初始化 CAN 外设。
name CAN_Init
fun Initializes the CAN peripheral according to the specified
parameters in the CAN_InitType structure.
param CANx:
- CAN
param CAN_InitParam (The input parameters must be the following values) :
- BaudRatePrescaler
- It ranges from 1 to 1024.
- OperatingMode
- CAN_Normal_Mode
- CAN_LoopBack_Mode
- CAN_Silent_Mode
- CAN_Silent_LoopBack_Mode
- RSJW
- CAN_RSJW_1tq
- CAN_RSJW_2tq
- CAN_RSJW_3tq
- CAN_RSJW_4tq
- TBS1
- CAN_TBS1_1tq
- CAN_TBS1_2tq
- CAN_TBS1_3tq
- CAN_TBS1_4tq
- CAN_TBS1_5tq
- CAN_TBS1_6tq
- CAN_TBS1_7tq
- CAN_TBS1_8tq
- CAN_TBS1_9tq
- CAN_TBS1_10tq
- CAN_TBS1_11tq
- CAN_TBS1_12tq
- CAN_TBS1_13tq
- CAN_TBS1_14tq
- CAN_TBS1_15tq
- CAN_TBS1_16tq
- TBS2
- CAN_TBS2_1tq
- CAN_TBS2_2tq
- CAN_TBS2_3tq
- CAN_TBS2_4tq
- CAN_TBS2_5tq
- CAN_TBS2_6tq
- CAN_TBS2_7tq
- CAN_TBS2_8tq
- TTCM
- DISABLE
- ENABLE
- ABOM
- DISABLE
- ENABLE
- AWKUM
- DISABLE
- ENABLE
- NART
- DISABLE
- ENABLE
- RFLM
- DISABLE
- ENABLE
- TXFP
- DISABLE
- ENABLE
return InitStatus :
- CAN_InitSTS_Failed
- CAN_InitSTS_Success
void CAN_InitStruct(CAN_InitType *CAN_InitParam)将 CAN_InitType 结构体的每个成员填入默认值。
name CAN_InitStruct
fun Fills each CAN_InitType member with its default value.
param CAN_InitParam (The input parameters must be the following values) :
- BaudRatePrescaler
- It ranges from 1 to 1024.
- OperatingMode
- CAN_Normal_Mode
- CAN_LoopBack_Mode
- CAN_Silent_Mode
- CAN_Silent_LoopBack_Mode
- RSJW
- CAN_RSJW_1tq
- CAN_RSJW_2tq
- CAN_RSJW_3tq
- CAN_RSJW_4tq
- TBS1
- CAN_TBS1_1tq
- CAN_TBS1_2tq
- CAN_TBS1_3tq
- CAN_TBS1_4tq
- CAN_TBS1_5tq
- CAN_TBS1_6tq
- CAN_TBS1_7tq
- CAN_TBS1_8tq
- CAN_TBS1_9tq
- CAN_TBS1_10tq
- CAN_TBS1_11tq
- CAN_TBS1_12tq
- CAN_TBS1_13tq
- CAN_TBS1_14tq
- CAN_TBS1_15tq
- CAN_TBS1_16tq
- TBS2
- CAN_TBS2_1tq
- CAN_TBS2_2tq
- CAN_TBS2_3tq
- CAN_TBS2_4tq
- CAN_TBS2_5tq
- CAN_TBS2_6tq
- CAN_TBS2_7tq
- CAN_TBS2_8tq
- TTCM
- DISABLE
- ENABLE
- ABOM
- DISABLE
- ENABLE
- AWKUM
- DISABLE
- ENABLE
- NART
- DISABLE
- ENABLE
- RFLM
- DISABLE
- ENABLE
- TXFP
- DISABLE
- ENABLE
return none
void CAN_InitFilter(const CAN_FilterInitType *CAN_InitFilterStruct)根据 CAN_FilterInitType 结构体中的指定参数初始化 CAN 的接收过滤器。
name CAN_InitFilter
fun Initializes the CAN peripheral according to the specified
parameters in the CAN_FilterInitType structure.
param CAN_InitFilterStruct (The input parameters must be the following values) :
- Filter_HighId
- It ranges from 0x0000 to 0xFFFF
- Filter_LowId
- It ranges from 0x0000 to 0xFFFF
- FilterMask_HighId
- It ranges from 0x0000 to 0xFFFF
- FilterMask_LowId
- It ranges from 0x0000 to 0xFFFF
- Filter_FIFOAssignment
- CAN_Filter_FIFO0
- CAN_Filter_FIFO1
- Filter_Num
- It ranges from 0 to 13
- Filter_Mode
- CAN_Filter_IdMaskMode
- CAN_Filter_IdListMode
- Filter_Scale
- CAN_Filter_16bitScale
- CAN_Filter_32bitScale
- Filter_Act
- ENABLE
- DISABLE
return none
void CAN_SoftwareReset(CAN_Module *CANx)请求 CAN 软件复位。
name CAN_SoftwareReset
fun Enable software reset.
param CANx:
- CAN
return none
void CAN_DebugFreeze(CAN_Module *CANx, FunctionalState Cmd)使能或禁用 CAN 的调试冻结。
name CAN_DebugFreeze
fun Enables the DBG Freeze for CAN.
param CANx:
- CAN
param Cmd (The input parameters must be the following values):
- DISABLE
- ENABLE
return none
void CAN_EnTTComMode(CAN_Module *CANx, FunctionalState Cmd)使能或禁用 CAN 的时间触发通信模式。
name CAN_EnTTComMode
fun Enables the CAN Time stamp sent.
param CANx:
- CAN
param Cmd (The input parameters must be the following values):
- DISABLE
- ENABLE
note when enabled, Time stamp (MTIM[15:0]) value is sent in the last
two data bytes of the 8-byte message: MTIM[7:0] in data byte 6
and MTIM[15:8] in data byte 7
note DLC must be programmed as 8 in order Time Stamp (2 bytes) to be
sent over the CAN bus.
return none
uint8_t CAN_OperatingModeReq(CAN_Module *CANx, uint8_t CAN_OperatingMode)请求 CAN 进入指定的运行模式。
name CAN_OperatingModeReq
fun Select the CAN Operation mode.
param CANx:
- CAN
param CAN_OperatingMode (The input parameters must be the following values) :
- CAN_Operating_InitMode
- CAN_Operating_NormalMode
- CAN_Operating_SleepMode
return status :
- CAN_ModeSTS_Failed CAN failed entering the specific mode
- CAN_ModeSTS_Success CAN Succeed entering the specific mode
uint8_t CAN_EnterSleep(CAN_Module *CANx)进入睡眠模式。
name CAN_EnterSleep
fun Enters sleep mode.
param CANx:
- CAN
return sleepstatus:
- CAN_SLEEP_Ok
- CAN_SLEEP_Failed
uint8_t CAN_WakeUp(CAN_Module *CANx)唤醒 CAN。
name CAN_WakeUp
fun Wakes the CAN up.
param CANx:
- CAN
return CAN_Status:
- CAN_WKU_Ok
- CAN_WKU_Failed
uint8_t CAN_TransmitMessage(CAN_Module *CANx, CanTxMessage *TxMessage)启动一帧报文的发送。
name CAN_TransmitMessage
fun initialize the transmission of a message.
param CANx:
- CAN
param TxMessage (The input parameters must be the following values):
- StdId
- It ranges from 0 to 0x7FF
- ExtId
- It ranges from 0 to 0x1FFFFFFF
- IDE
- CAN_Standard_Id
- CAN_Extended_Id
- RTR
- CAN_RTRQ_Data
- CAN_RTRQ_Remote
- DLC
- It ranges from 0 to 8
- Data[0-7]
- It ranges from 0 to 0xFF
return transmit_mailbox (The input parameters must be the following values) :
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
- CAN_TxSTS_NoMailBox
uint8_t CAN_TransmitSTS(const CAN_Module *CANx, uint8_t TransmitMailbox)返回指定发送邮箱的发送状态。
name CAN_TransmitSTS
fun Checks the transmission of a message.
param CANx:
- CAN
param TransmitMailbox (The input parameters must be the following values) :
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
return state :
- CAN_TxSTS_Failed
- CAN_TxSTS_Ok
- CAN_TxSTS_Pending
void CAN_CancelTransmitMessage(CAN_Module *CANx, uint8_t Mailbox)取消发送请求。
name CAN_CancelTransmitMessage
brief Cancels a transmit request.
param CANx:
- CAN
param Mailbox (The input parameters must be the following values) :
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
return none
使用提示: 源码注释未提供 fun 字段,只有 brief,本条摘要取自 brief;实现按 Mailbox 把 CAN_TSTS_ABRQM0、CAN_TSTS_ABRQM1 或 CAN_TSTS_ABRQM2 写入 CANx->TSTS,即对选定的发送邮箱置中止请求位,Mailbox 为其它值时不做任何处理。
void CAN_ReceiveMessage(CAN_Module *CANx, uint8_t FIFONum, CanRxMessage *RxMessage)接收一帧报文。
name CAN_ReceiveMessage
fun Receives a message.
param CANx:
- CAN
param FIFONum (The input parameters must be the following values) :
- CAN_FIFO0
- CAN_FIFO1
param RxMessage (The input parameters must be the following values) :
- StdId
- It ranges from 0 to 0x7FF
- ExtId
- It ranges from 0 to 0x1FFFFFFF
- IDE
- CAN_Standard_Id
- CAN_Extended_Id
- RTR
- CAN_RTRQ_Data
- CAN_RTRQ_Remote
- DLC
- It ranges from 0 to 8
- Data[0-7]
- It ranges from 0 to 0xFF
- FMI
- It ranges from 0 to 0xFF
return none
void CAN_ReleaseFIFO(CAN_Module *CANx, uint8_t FIFONum)释放指定的接收 FIFO。
name CAN_ReleaseFIFO
fun Releases the specified DATAFIFO.
param CANx:
- CAN
param FIFONum (The input parameters must be the following values) :
- CAN_FIFO0
- CAN_FIFO1
return none
uint8_t CAN_PendingMessage(const CAN_Module *CANx, uint8_t FIFONum)返回指定接收 FIFO 中挂起的报文数量。
name CAN_PendingMessage
fun Returns the number of pending messages.
param CANx :
- CAN
param FIFONum (The input parameters must be the following values) :
- CAN_FIFO0
- CAN_FIFO1
return message_pending :
- CAN_FIFOX_PENDING_0
- CAN_FIFOX_PENDING_1
- CAN_FIFOX_PENDING_2
- CAN_FIFOX_PENDING_3
uint8_t CAN_GetLastErrCode(const CAN_Module *CANx)返回 CANx 的上次错误代码 (LEC)。
name CAN_GetLastErrCode
fun Returns the CANx's last error code (LEC).
param CANx:
- CAN
return errorcode :
- CAN_ERRORCODE_NoErr No Error
- CAN_ERRORCODE_StuffErr Stuff Error
- CAN_ERRORCODE_FormErr Form Error
- CAN_ERRORCODE_ACKErr Acknowledgment Error
- CAN_ERRORCODE_BitRecessiveErr Bit Recessive Error
- CAN_ERRORCODE_BitDominantErr Bit Dominant Error
- CAN_ERRORCODE_CRCErr CRC Error
- CAN_ERRORCODE_SoftwareSetErr Software Set Error
uint8_t CAN_GetReceiveErrCounter(const CAN_Module *CANx)返回 CANx 的接收错误计数器 (REC)。
name CAN_GetReceiveErrCounter
fun Returns the CANx Receive Error Counter (REC).
param CANx:
- CAN
return counter_value:
- It ranges from 0 to 255
note In case of an error during reception, this counter is incremented
by 1 or by 8 depending on the error condition as defined by the CAN
standard. After every successful reception, the counter is
decremented by 1 or reset to 120 if its value was higher than 127.
When the counter value exceeds 127, the CAN controller enters the
error passive state.
uint8_t CAN_GetLSBTransmitErrCounter(const CAN_Module *CANx)返回 9 位 CANx 发送错误计数器 (TEC) 的低字节。
name CAN_GetLSBTransmitErrCounter
fun Returns the LSB of the 9-bit CANx Transmit Error Counter(TEC).
param CANx:
- CAN
return counter_value:
- It ranges from 0 to 255
FlagStatus CAN_GetTransmitFailStatus(const CAN_Module *CANx, uint8_t mailbox_queue)获取指定发送邮箱的发送失败状态。
name CAN_GetTransmitFailStatus
fun Get the transmit failure status of the given transmit mailbox.
param CANx:
- CAN
param mailbox_queue:
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
return FlagStatus:
- SET
- RESET
FlagStatus CAN_GetArbitrationLostStatus(const CAN_Module *CANx, uint8_t mailbox_queue)获取仲裁丢失状态。
name CAN_GetArbitrationLostStatus
fun Get the status of arbitration lost.
param CANx:
- CAN
param mailbox_queue:
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
return FlagStatus:
- SET
- RESET
FlagStatus CAN_GetFlagLowestPriority(const CAN_Module *CANx, uint8_t mailbox_queue)获取最低优先级标志。
name CAN_GetFlagLowestPriority
fun Get the flag of lowest priority.
param CANx:
- CAN
param mailbox_queue:
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
return FlagStatus:
- SET
- RESET
FlagStatus CAN_GetTransmitMailboxEmptyFlag(const CAN_Module *CANx, uint8_t mailbox_queue)获取发送邮箱空标志。
name CAN_GetTransmitMailboxEmptyFlag
fun Get the flag of Transmit mailbox empty.
param CANx:
- CAN
param mailbox_queue:
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
return FlagStatus:
- SET
- RESET
FlagStatus CAN_GetReceiveSignal(const CAN_Module *CANx)返回 CANx 的接收电平值 (RXS)。
name CAN_GetReceiveSignal
fun Returns the CANx's receive signal value (RXS).
param CANx:
- CAN
return FlagStatus:
- SET
- RESET
FlagStatus CAN_GetLastSamplePoint(const CAN_Module *CANx)返回 CANx 的上次采样值 (LSMP)。
name CAN_GetLastSamplePoint
fun Returns the CANx's Last sample point (LSMP).
param CANx:
- CAN
return FlagStatus:
- SET
- RESET
FlagStatus CAN_GetReceiveMode(const CAN_Module *CANx)返回 CANx 的接收模式 (RXMD)。
name CAN_GetReceiveMode
fun Returns the CANx's receive mode (RXMD).
param CANx:
- CAN
return FlagStatus:
- SET
- RESET
FlagStatus CAN_GetTransmitMode(const CAN_Module *CANx)返回 CANx 的发送模式 (TXMD)。
name CAN_GetTransmitMode
fun Returns the CANx's transmit mode (TXMD).
param CANx:
- CAN
return FlagStatus:
- SET
- RESET
uint8_t CAN_GetMailboxCode(const CAN_Module *CANx)返回 CANx 的邮箱号 (CODE[1:0])。
name CAN_GetMailboxCode
fun Returns the CANx's mailbox code (CODE[1:0]).
param CANx:
- CAN
return mailbox_queue :
- CAN_TXMAILBOX_0
- CAN_TXMAILBOX_1
- CAN_TXMAILBOX_2
- CAN_TxSTS_NoMailBox
void CAN_INTConfig(CAN_Module *CANx, uint32_t CAN_INT, FunctionalState Cmd)根据 Cmd 使能或禁用指定的 CANx 中断。
name CAN_INTConfig
fun Enables or disables the specified CANx interrupts according
to Cmd.
param CANx:
- CAN
param CAN_INT (The input parameters must be the following values) :
- CAN_INT_TME,
- CAN_INT_FMP0,
- CAN_INT_FF0,
- CAN_INT_FOV0,
- CAN_INT_FMP1,
- CAN_INT_FF1,
- CAN_INT_FOV1,
- CAN_INT_EWG,
- CAN_INT_EPV,
- CAN_INT_BOF,
- CAN_INT_LEC,
- CAN_INT_ERR,
- CAN_INT_WKU,
- CAN_INT_SLK.
param Cmd :
- DISABLE
- ENABLE
return none
FlagStatus CAN_GetFlagSTS(const CAN_Module *CANx, uint32_t CAN_FLAG)检查指定的 CAN 标志是否置位。
name CAN_GetFlagSTS
fun Checks whether the specified CAN flag is set or not.
param CANx:
- CAN
param CAN_FLAG (The input parameters must be the following values) :
- CAN_FLAG_EWGFL
- CAN_FLAG_EPVFL
- CAN_FLAG_BOFFL
- CAN_FLAG_LEC
- CAN_FLAG_RQCPM0
- CAN_FLAG_RQCPM1
- CAN_FLAG_RQCPM2
- CAN_FLAG_FFMP1
- CAN_FLAG_FFULL1
- CAN_FLAG_FFOVR1
- CAN_FLAG_FFMP0
- CAN_FLAG_FFULL0
- CAN_FLAG_FFOVR0
- CAN_FLAG_WKU
- CAN_FLAG_SLAK
return FlagStatus:
- SET
- RESET
void CAN_ClearFlag(CAN_Module *CANx, uint32_t CAN_FLAG)清除 CAN 的标志状态。
name CAN_ClearFlag
fun Clears the CAN's flag status.
param CANx:
- CAN
param CAN_FLAG (The input parameters must be the following values) :
- CAN_FLAG_RQCPM0
- CAN_FLAG_RQCPM1
- CAN_FLAG_RQCPM2
- CAN_FLAG_FFULL1
- CAN_FLAG_FFOVR1
- CAN_FLAG_FFULL0
- CAN_FLAG_FFOVR0
- CAN_FLAG_WKU
- CAN_FLAG_SLAK
- CAN_FLAG_LEC
return none
INTStatus CAN_GetIntStatus(const CAN_Module *CANx, uint32_t CAN_INT)检查指定的 CANx 中断是否发生。
name CAN_GetIntStatus
fun Checks whether the specified CANx interrupt has occurred or not.
param CANx:
- CAN
param CAN_INT (The input parameters must be the following values) :
- CAN_INT_TME
- CAN_INT_FMP0
- CAN_INT_FF0
- CAN_INT_FOV0
- CAN_INT_FMP1
- CAN_INT_FF1
- CAN_INT_FOV1
- CAN_INT_WKU
- CAN_INT_SLK
- CAN_INT_EWG
- CAN_INT_EPV
- CAN_INT_BOF
- CAN_INT_LEC
- CAN_INT_ERR
return INTStatus :
- SET
- RESET
void CAN_ClearINTPendingBit(CAN_Module *CANx, uint32_t CAN_INT)清除 CANx 的中断状态。
name CAN_ClearINTPendingBit
fun Clears the CANx's interrupt status.
param CANx:
- CAN
param CAN_INT (The input parameters must be the following values) :
- CAN_INT_TME
- CAN_INT_FF0
- CAN_INT_FOV0
- CAN_INT_FF1
- CAN_INT_FOV1
- CAN_INT_WKU
- CAN_INT_SLK
- CAN_INT_EWG
- CAN_INT_EPV
- CAN_INT_BOF
- CAN_INT_LEC
- CAN_INT_ERR
return none
5.2.3 Demo 示例说明
本节说明 bxCAN 的 2 个示例:CAN_LoopBack 在环回模式下把发送的报文直接回环接收,CAN_Tx_Rx 在正常模式下经外部收发器与总线收发报文。
5.2.3.1 CAN_LoopBack 回环收发
工程目录: projects/n32g41x_EVAL/examples/bxCAN/CAN_LoopBack/
使能 CAN 与 GPIO 时钟→配置 PA11、PA12 为 CAN 复用功能→回环模式下初始化 CAN 与接收过滤器→发送一帧报文并等待回环接收→校验收到的报文后延时并循环发送
| 项目 | 源码解读 |
|---|---|
| 功能 | 在环回测试模式下发送一帧标准数据帧,报文在 CAN 内部回环到接收 FIFO,收到后比对标识符与 8 字节数据,比对通过再发送下一帧,如此循环。 |
| 源码组成 | src/main.c:main 与报文赋值;src/can_config.c:CAN_CONFIG、CAN_NVIC_Configuration、CAN_GPIO_Configuration、Check_CanRecData;inc/can_config.h:引脚与过滤器宏、Check_CanRecData 声明、外部变量;inc/main.h:包含驱动与配置文件;src/n32g41x_it.c、inc/n32g41x_it.h:CAN_IRQHandler 等中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/、EWARM/:Keil 与 IAR 工程。 |
| 关键配置 | 引脚:RX 为 PA11、TX 为 PA12,均复用 GPIO_AF1,由 N32G412、N32G415 宏切换;RX 配为 GPIO_MODE_INPUT、GPIO_PULL_UP、GPIO_DS_HIGH,TX 配为 GPIO_MODE_AF_PP、GPIO_DS_HIGH;模式: OperatingMode 为 CAN_LoopBack_Mode、TXFP 为 ENABLE,TTCM、ABOM、AWKUM、NART、RFLM 为 DISABLE;波特率:500 Kbps, N32G415 下 APB1 48 MHz、分频 6,其余 40 MHz、分频 5;过滤器:0 号 32 位掩码模式、关联 CAN_FIFO0、只放行标识符 0x400;中断:FIFO0 挂起,抢占与子优先级 0x0; 时钟:HSI+PLL, N32G412 80 MHz、N32G415 96 MHz。 |
| 程序与数据路径 | main 先调用 CAN_CONFIG 完成时钟、GPIO、NVIC、CAN 与过滤器初始化,再填充 CAN_TxMessage;while 循环中先 CAN_TransmitMessage 请求发送,再在 Rx_Flag 为 DISABLE 的循环里反复调用 Check_CanRecData 比对报文;FIFO0 挂起中断触发 CAN_IRQHandler,其中 CAN_ReceiveMessage 读出报文;校验通过后延时一段并清零 Rx_Flag,进入下一轮。 |
| 主要 API | CAN_InitStruct、CAN_Init、CAN_InitFilter、CAN_TransmitMessage、CAN_ReceiveMessage、CAN_INTConfig |
| 验证方法 | 下载并复位运行后,用 CAN 分析设备可看到标识符 0x400、数据 0x00~0x07 的报文循环发送; 回环模式下无需外部收发器,也可观察 Check_CanRecData 的返回是否始终为非零。 |
| 使用提示 | 环回模式下 TX 在内部反馈到 RX,无需外部 CAN 收发器与总线; 开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1,基于评估板 N32G41x_STB V1.0。 |
核心代码解读与移植
示例先完成时钟、引脚与 CAN 的初始化,再由主循环发送报文并在中断配合下校验回环收到的报文。
数据路径: main -> CAN_CONFIG 使能时钟并配置 GPIO、NVIC、CAN 与过滤器 -> CAN_TransmitMessage 请求发送 -> 回环接收触发 CAN_IRQHandler -> CAN_ReceiveMessage 读 FIFO0 -> Check_CanRecData 比对 -> 延时后清零 Rx_Flag
1. 从默认值起步并复位 CAN。 CAN_CONFIG 先打开 CAN 时钟,再配置中断与引脚,随后 CAN_DeInit 复位寄存器并用 CAN_InitStruct 填入默认值。
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN, ENABLE);
CAN_NVIC_Configuration();
CAN_GPIO_Configuration();
CAN_DeInit(CAN);
CAN_InitStruct(&CAN_InitStructure);
移植到其它板卡时,只需改 CAN_GPIO_Configuration 与 can_config.h 中的引脚宏。
2. 位时序按型号分档给出 500 Kbps。 N32G415 的 APB1 为 48 MHz、分频取 6,其余型号 APB1 为 40 MHz、分频取 5,两者时间段参数相同。
#ifdef N32G415
/* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
APB1CLK = 48MHz, 48000000 / (6 * (11 + 4 + 1)) = 500000 = 500Kbps */
CAN_InitStructure.RSJW = CAN_RSJW_4tq;
CAN_InitStructure.TBS1 = CAN_TBS1_11tq;
CAN_InitStructure.TBS2 = CAN_TBS2_4tq;
CAN_InitStructure.BaudRatePrescaler = 6;
#else
/* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
APB1CLK = 40MHz, 40000000 / (5 * (11 + 4 + 1)) = 500000 = 500Kbps */
CAN_InitStructure.RSJW = CAN_RSJW_4tq;
CAN_InitStructure.TBS1 = CAN_TBS1_11tq;
CAN_InitStructure.TBS2 = CAN_TBS2_4tq;
CAN_InitStructure.BaudRatePrescaler = 5;
#endif
切换型号或换算其它波特率时,同步改 BaudRatePrescaler、TBS1、TBS2 与 RSJW 四项。
3. 过滤器 0 只放行标识符 0x400。 过滤器配置为 32 位掩码模式并关联 FIFO0,匹配值与掩码都由 inc/can_config.h 中的宏生成,只比较需要匹配的位。
CAN_FilterInitStructure.Filter_Num = 0;
CAN_FilterInitStructure.Filter_Mode = CAN_Filter_IdMaskMode;
CAN_FilterInitStructure.Filter_Scale = CAN_Filter_32bitScale;
CAN_FilterInitStructure.Filter_HighId = CAN_STD_ID_LIST_32BIT_H(0x00000400);
CAN_FilterInitStructure.Filter_LowId = CAN_STD_ID_LIST_32BIT_L(0x00000400);
CAN_FilterInitStructure.FilterMask_HighId = CAN_STD_ID_LIST_32BIT_H(0x00000200);
CAN_FilterInitStructure.FilterMask_LowId = CAN_STD_ID_LIST_32BIT_L(0x00000200);
CAN_FilterInitStructure.Filter_FIFOAssignment = CAN_FIFO0;
CAN_FilterInitStructure.Filter_Act = ENABLE;
CAN_InitFilter(&CAN_FilterInitStructure);
改收其它标识符时,同步改 Filter_HighId、Filter_LowId 与对应的掩码值。
4. 中断取报文,主循环校验后循环发送。 FIFO0 挂起中断把报文读入 CAN_RxMessage,主循环发送后在标志上等待,并用 Check_CanRecData 比对报文。
void CAN_IRQHandler(void)
{
/* Receives a message */
CAN_ReceiveMessage(CAN, CAN_FIFO0, &CAN_RxMessage);
}
while(1)
{
/* Transmit */
CAN_TransmitMessage(CAN, &CAN_TxMessage);
while(Rx_Flag == DISABLE)
{
Rx_Flag = Check_CanRecData(&CAN_RxMessage, 0x0400, 0x00, CAN_Standard_Id, CAN_RTRQ_Data, 8,
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07, 0);
}
/* Delay */
wait_slak = 0xFFFF;
while(wait_slak > 0)
{
wait_slak--;
}
Rx_Flag = DISABLE;
}
修改期望报文时,同步改 main 中 Check_CanRecData 的期望参数与 CAN_TxMessage 的赋值。
对应源码: src/main.c、src/can_config.c、src/n32g41x_it.c、inc/can_config.h
5.2.3.2 CAN_Tx_Rx 正常模式收发
工程目录: projects/n32g41x_EVAL/examples/bxCAN/CAN_Tx_Rx/
使能 CAN 与 GPIO 时钟→配置 PA11、PA12 为 CAN 复用功能→正常模式下初始化 CAN 与接收过滤器→上电发送一帧报文→收到外部报文后由中断置位标志并再发送一帧
| 项目 | 源码解读 |
|---|---|
| 功能 | 在正常模式下上电对外发送一帧标准数据帧,随后等待总线上的报文; 收到一帧后由中断置位标志,主循环再发送一帧,如此循环。 |
| 源码组成 | src/main.c:main 与报文赋值;src/can_config.c:CAN_CONFIG、CAN_NVIC_Configuration、CAN_GPIO_Configuration、Check_CanRecData;inc/can_config.h:引脚与过滤器宏、Check_CanRecData 声明、外部变量;inc/main.h:包含驱动与配置文件;src/n32g41x_it.c、inc/n32g41x_it.h:CAN_IRQHandler 等中断服务函数;readme.txt:功能、环境与使用说明;MDK-ARM/、EWARM/:Keil 与 IAR 工程。 |
| 关键配置 | 引脚:RX 为 PA11、TX 为 PA12,均复用 GPIO_AF1,由 N32G412、N32G415 宏切换;RX 配为 GPIO_MODE_INPUT、GPIO_PULL_UP、GPIO_DS_HIGH,TX 配为 GPIO_MODE_AF_PP、GPIO_DS_HIGH;模式: OperatingMode 为 CAN_Normal_Mode、TXFP 为 ENABLE,TTCM、ABOM、AWKUM、NART、RFLM 为 DISABLE;波特率:500 Kbps, N32G415 下 APB1 48 MHz、分频 6,其余 40 MHz、分频 5;过滤器:0 号 32 位掩码模式、关联 CAN_FIFO0、只放行标识符 0x400;中断:FIFO0 挂起,抢占与子优先级 0x0; 时钟:HSI+PLL, N32G412 80 MHz、N32G415 96 MHz。 |
| 程序与数据路径 | main 先调用 CAN_CONFIG 完成初始化,再填充 CAN_TxMessage;while 循环中先 CAN_TransmitMessage 请求发送,随后轮询 Rx_Flag;FIFO0 挂起中断触发 CAN_IRQHandler,其中 CAN_ReceiveMessage 读出报文并把 Rx_Flag 置 ENABLE;主循环清零 Rx_Flag 后再次发送。 |
| 主要 API | CAN_InitStruct、CAN_Init、CAN_InitFilter、CAN_TransmitMessage、CAN_ReceiveMessage、CAN_INTConfig |
| 验证方法 | 需要外部 CAN 收发器与 CAN 总线; 总线上的其它节点可看到标识符 0x400、数据 0x00~0x07 的报文,本节点每收到一帧外部报文后再发送一帧。 |
| 使用提示 | 正常模式需要外部 CAN 收发器并接入 CAN 总线; 开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1,基于评估板 N32G41x_STB V1.0。 |
核心代码解读与移植
示例先完成时钟、引脚与 CAN 的初始化,再由主循环按收到的报文触发下一次发送。
数据路径: main -> CAN_CONFIG 使能时钟并配置 GPIO、NVIC、CAN 与过滤器 -> CAN_TransmitMessage 首次发送 -> 总线接收触发 CAN_IRQHandler -> CAN_ReceiveMessage 读 FIFO0 并置位 Rx_Flag -> 主循环清零标志后再次发送
1. 从默认值起步并复位 CAN。 CAN_CONFIG 先打开 CAN 时钟,再配置中断与引脚,随后 CAN_DeInit 复位寄存器并用 CAN_InitStruct 填入默认值。
RCC_EnableAPB1PeriphClk(RCC_APB1_PERIPH_CAN, ENABLE);
CAN_NVIC_Configuration();
CAN_GPIO_Configuration();
CAN_DeInit(CAN);
CAN_InitStruct(&CAN_InitStructure);
移植到其它板卡时,只需改 CAN_GPIO_Configuration 与 can_config.h 中的引脚宏。
2. 工作模式设为正常收发并给出 500 Kbps。 OperatingMode 取 CAN_Normal_Mode,位时序仍按型号分档。
/* CAN cell init */
CAN_InitStructure.TTCM = DISABLE;
CAN_InitStructure.ABOM = DISABLE;
CAN_InitStructure.AWKUM = DISABLE;
CAN_InitStructure.NART = DISABLE;
CAN_InitStructure.RFLM = DISABLE;
CAN_InitStructure.TXFP = ENABLE;
CAN_InitStructure.OperatingMode = CAN_Normal_Mode;
#ifdef N32G415
/* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
APB1CLK = 48MHz, 48000000 / (6 * (11 + 4 + 1)) = 500000 = 500Kbps */
CAN_InitStructure.RSJW = CAN_RSJW_4tq;
CAN_InitStructure.TBS1 = CAN_TBS1_11tq;
CAN_InitStructure.TBS2 = CAN_TBS2_4tq;
CAN_InitStructure.BaudRatePrescaler = 6;
#else
/* Baud rate = APB1CLK / (BaudRatePrescaler * (TBS1 + TBS2 + 1))
APB1CLK = 40MHz, 40000000 / (5 * (11 + 4 + 1)) = 500000 = 500Kbps */
CAN_InitStructure.RSJW = CAN_RSJW_4tq;
CAN_InitStructure.TBS1 = CAN_TBS1_11tq;
CAN_InitStructure.TBS2 = CAN_TBS2_4tq;
CAN_InitStructure.BaudRatePrescaler = 5;
#endif
切到其它模式时改 OperatingMode,换算波特率时同步改 BaudRatePrescaler、TBS1、TBS2 与 RSJW。
3. 主循环发送后在标志上等待。 每轮先发送一帧,随后阻塞在 Rx_Flag 为 DISABLE 的空循环里,由中断置位该标志后清零并进入下一轮。
while(1)
{
CAN_TransmitMessage(CAN, &CAN_TxMessage);
while(Rx_Flag == DISABLE)
{
}
Rx_Flag = DISABLE;
}
去掉轮询改为事件驱动时,可在 CAN_IRQHandler 里直接组织下一帧发送。
4. 中断收到报文后置位软件标志。 CAN_IRQHandler 读走 FIFO0 的报文并把 Rx_Flag 置 ENABLE,作为主循环继续发送的触发条件。
void CAN_IRQHandler(void)
{
/* Receives a message */
CAN_ReceiveMessage(CAN, CAN_FIFO0, &CAN_RxMessage);
/* flag set */
Rx_Flag = ENABLE;
}
对应源码: src/main.c、src/can_config.c、src/n32g41x_it.c、inc/can_config.h
5.2.4 注意与排障
| 场景 | 检查与建议 | 来源 |
|---|---|---|
| CAN 寄存器的一次访问宽度 | CAN 外设寄存器必须以字(32 位)方式访问,不允许按半字或字节访问; 直接操作寄存器时按其字宽度读写。 |
用户手册 |
| 在非初始化模式下改位时序 | CAN_BTIM 只能在 CAN 内核处于初始化模式时修改,退出初始化模式后位时间特性不可再改;波特率与采样点参数应在初始化阶段一次设定。 |
用户手册 |
| 配置或修改接收过滤器 | 修改过滤器值和过滤器设置前,需先清除对应的 CAN_FMC.FAC 位或将 CAN_FMC.FINITM 置 1;CAN_FMC.FINITM 为 1 时禁止接收报文,未使用的过滤器组应保持非激活。 |
用户手册 |
| 写发送邮箱数据 | 只有当 CAN_TSTS.TMEM 为 1(邮箱为空)时软件才能修改发送邮箱的寄存器;置位发送邮箱的 TXRQ 后邮箱进入等待发送状态,其寄存器被写保护。 |
用户手册 |
| 中止一帧发送请求 | 置位 CAN_TSTS.ABRQM 可中止发送请求:邮箱处于就绪或挂起状态时立即中止;邮箱处于发送状态时,发送失败则变为就绪后中止并清除发送成功标志,发送成功则邮箱变空并由硬件置位发送成功标志。 |
用户手册 |
| 进入初始化模式或从复位启动 | 复位后 CAN 处于睡眠模式; 从睡眠进入初始化模式需同时置位 CAN_MCTRL.INIRQ 并清零 CAN_MCTRL.SLPRQ,再等 CAN_MSTS.INIAK 置位确认。 |
用户手册 |
| 总线关闭后的恢复 | 发送错误计数器大于 255 时置位总线关闭标志; 恢复需在 CANRX 引脚上检测到 128 个连续的 11 位隐性位,且初始化模式下不监视 CANRX,无法完成恢复,需先退出初始化模式。 |
用户手册 |
N32G412、N32G415 系列勘误手册 V1.0.0(2026.6.30)的勘误列表只列出一行 A 版芯片条目,勘误链接列为空,未列出 CAN 相关条目。以上结论均取自用户手册的“控制器局域网(CAN)”章节。