本帖最后由 tagntangtangtan 于 2025-1-17 09:20 编辑
之前双路Can不同是引脚复用错了
先配置时钟
stc_clock_xtal_init_t stcXtalInit;
stc_clock_pll_init_t stcPLLHInit;
CLK_SetClockDiv(CLK_BUS_CLK_ALL,
(CLK_PCLK0_DIV1 | //200MHz Timer6_n(n=1~2)、Timer4_n(n=1~3)、TimerA_n(n=1~4)、I2Cn(n=1~2)、CMPn(n=1~4)
CLK_PCLK1_DIV2 | //100MHz USARTn(n=1~6)、SPIn(n=1~3)、Timer0_n(n=1~2)、TimerA_5、EMB、CRC、HASH、AES、MCANn(n=1~2)
CLK_PCLK2_DIV4 | //50MHz ADC 转换时钟
CLK_PCLK3_DIV4 | //50MHz RTC(控制逻辑)、WDT、SWDT(控制逻辑)、WKTM、FCM、CTC
CLK_PCLK4_DIV2 | //100MHz ADCn(n=1~3)(控制逻辑)、DAC(控制逻辑)
CLK_EXCLK_DIV4 | //50MHz SMC
CLK_HCLK_DIV1)); //200MHz GPIO,EFM
GPIO_AnalogCmd(GPIO_PORT_H, GPIO_PIN_00 | GPIO_PIN_01, ENABLE);
CLK_XtalStructInit(&stcXtalInit);
/* Config Xtal and enable Xtal */
stcXtalInit.u8Mode = CLK_XTAL_MD_OSC;// 外部晶振时钟
stcXtalInit.u8Drv = CLK_XTAL_DRV_LOW;// 外部低速晶震 8~16M
stcXtalInit.u8State = CLK_XTAL_ON;
stcXtalInit.u8StableTime = CLK_XTAL_STB_2MS;// XTAL稳定时间
CLK_XtalInit(&stcXtalInit);
CLK_XtalCmd(ENABLE);
CLK_Xtal32Cmd(DISABLE);
//PLLH 时钟
CLK_PLLStructInit(&stcPLLHInit);
/* VCO = (8/1)*100 = 800MHz*/
stcPLLHInit.u8PLLState = CLK_PLL_ON;
stcPLLHInit.PLLCFGR = 0UL;
stcPLLHInit.PLLCFGR_f.PLLM = 1UL - 1UL;/* XTAL 8M / 1 */
stcPLLHInit.PLLCFGR_f.PLLN = 100UL - 1UL;/* 8M*100 = 800M */
stcPLLHInit.PLLCFGR_f.PLLP = 4UL - 1UL;/* MLLP = 800M/4 = 200M */
stcPLLHInit.PLLCFGR_f.PLLQ = 4UL - 1UL;/* MLLQ = 800M/4 = 200M */
stcPLLHInit.PLLCFGR_f.PLLR = 4UL - 1UL;/* MLLR = 800M/4 = 200M */
stcPLLHInit.PLLCFGR_f.PLLSRC = CLK_PLL_SRC_XTAL;
CLK_SetPLLSrc(CLK_PLL_SRC_XTAL); //PLL时钟源为外部晶振
CLK_PLLInit(&stcPLLHInit);
/* 3 cycles for 150 ~ 200MHz */
EFM_SetWaitCycle(EFM_WAIT_CYCLE3);
/* 3 cycles for 150 ~ 200MHz */
GPIO_SetReadWaitCycle(GPIO_RD_WAIT3);
/* Enable MPLL. */
CLK_PLLCmd(ENABLE);
/* Wait MPLL ready. */
while(SET != CLK_GetStableStatus(CLK_STB_FLAG_PLL))
{
;
}
CLK_SetSysClockSrc(CLK_SYSCLK_SRC_PLL); //设置系统时钟源
之后使能时钟和初始化引脚
FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_MCAN1, ENABLE);
#if CAN2_EN
FCG_Fcg1PeriphClockCmd(FCG1_PERIPH_MCAN2, ENABLE);
#endif
#if CAN1_EN
GPIO_SetFunc(GPIO_PORT_A, GPIO_PIN_09, GPIO_FUNC_56);//MCAN1_TX
GPIO_SetFunc(GPIO_PORT_A, GPIO_PIN_08, GPIO_FUNC_57);//MCAN1_RX
#endif
#if CAN2_EN
GPIO_SetFunc(GPIO_PORT_B, GPIO_PIN_13, GPIO_FUNC_56);//MCAN2_TX
GPIO_SetFunc(GPIO_PORT_B, GPIO_PIN_12, GPIO_FUNC_57);//MCAN2_RX
#endif
#if CAN1_EN
NVIC_ClearPendingIRQ(MCAN1_INT0_IRQn); //CAN1接收中断
NVIC_SetPriority(MCAN1_INT0_IRQn, DDL_IRQ_PRIO_00);
NVIC_EnableIRQ(MCAN1_INT0_IRQn);
#endif
#if CAN2_EN
NVIC_ClearPendingIRQ(MCAN2_INT0_IRQn); //CAN2接收中断
NVIC_SetPriority(MCAN2_INT0_IRQn, DDL_IRQ_PRIO_00);
NVIC_EnableIRQ(MCAN2_INT0_IRQn);
#endif
之后进行CAN配置
//标准帧筛选配置
#define MCAN_STD_FILTER0 {.u32IdType = MCAN_STD_ID, .u32FilterType = MCAN_FILTER_MASK, \
.u32FilterConfig = MCAN_FILTER_TO_RX_FIFO0, .u32FilterId1 = 0x00000000, \
.u32FilterId2 = 0x00000000,}
//扩展帧筛选配置
#define MCAN_EXT_FILTER0 {.u32IdType = MCAN_EXT_ID, .u32FilterType = MCAN_FILTER_MASK, \
.u32FilterConfig = MCAN_FILTER_TO_RX_FIFO0, .u32FilterId1 = 0x00000000, \
.u32FilterId2 = 0x00000000,}
//CAN接收中断
#define MCAN_RX_INT_SEL (MCAN_INT_RX_FIFO0_NEW_MSG | \
MCAN_INT_RX_FIFO0_WATERMARK | \
MCAN_INT_RX_FIFO0_FULL)
stc_mcan_tx_msg_t stcTx1Msg;
stc_mcan_rx_msg_t stcRx1Msg;
stc_mcan_tx_msg_t stcTx2Msg;
stc_mcan_rx_msg_t stcRx2Msg;
stc_mcan_tx_msg_t Tx1Message;
stc_mcan_tx_msg_t Tx2Message;
uint32_t Can1AllocatedSize,Can2AllocatedSize;
void Can1InitConfig(void)
{
#if CAN1_EN
stc_mcan_init_t stcMcanInit;
stc_mcan_filter_t stcStdFilterList = MCAN_STD_FILTER0;
stc_mcan_filter_t stcExtFilterList = MCAN_EXT_FILTER0;
CLK_SetCANClockSrc(CLK_MCAN1, CLK_MCANCLK_SYSCLK_DIV5);//200M/5 = 40MHZ
MCAN_StructInit(&stcMcanInit);
stcMcanInit.u32Mode = MCAN_MD_NORMAL;
stcMcanInit.u32FrameFormat = MCAN_FRAME_CLASSIC;
/* Classic CAN. Baudrate 1Mbps, sample point 80% */
//CAN 波特率 = CANClock / PRESC / (SEG_1 + SEG_2)
#if CAN1_BAUDRATE == 1000 //1MBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 2U;
#elif CAN1_BAUDRATE == 500 // 500KBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 4U;
#elif CAN1_BAUDRATE == 250 // 250KBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 8U;
#elif CAN1_BAUDRATE == 125 // 125KBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 16U;
#endif
//stcMcanInit.stcBitTime.u32NominalPrescaler = 2U;
stcMcanInit.stcBitTime.u32NominalTimeSeg1 = 16U;
stcMcanInit.stcBitTime.u32NominalTimeSeg2 = 4U;
stcMcanInit.stcBitTime.u32NominalSyncJumpWidth = 4U;
/* Message RAM 最多分配512个字,共2KB */
stcMcanInit.stcMsgRam.u32AddrOffset = 0u;//消息起始地址
stcMcanInit.stcMsgRam.u32StdFilterNum = 1u;//指定标准帧ID筛选器的数量
stcMcanInit.stcMsgRam.u32ExtFilterNum = 1u;//指定扩展帧ID筛选器的数量
/* 接收RAM配置 */
stcMcanInit.stcMsgRam.u32RxFifo0Num = MCAN_RX_FIFO0_NUM;
stcMcanInit.stcMsgRam.u32RxFifo0DataSize = MCAN_DATA_SIZE_8BYTE;
stcMcanInit.stcMsgRam.u32RxFifo1Num = 0u;
stcMcanInit.stcMsgRam.u32RxFifo1DataSize = MCAN_DATA_SIZE_8BYTE;
stcMcanInit.stcMsgRam.u32RxBufferNum = 0u;//指定专用Rx缓冲区元素的数量
stcMcanInit.stcMsgRam.u32RxBufferDataSize = MCAN_DATA_SIZE_8BYTE;
/* 发送RAM配置 */
stcMcanInit.stcMsgRam.u32TxBufferNum = MCAN_TX_BUF_NUM;//指定专用Tx缓冲区的数量
stcMcanInit.stcMsgRam.u32TxFifoQueueNum = MCAN_TX_FIFO_NUM;//Tx的FIFO(先进先出)数量
stcMcanInit.stcMsgRam.u32TxFifoQueueMode = MCAN_TX_FIFO_MD;//FIFO模式 (或者队列)
stcMcanInit.stcMsgRam.u32TxDataSize = MCAN_DATA_SIZE_8BYTE;
stcMcanInit.stcMsgRam.u32TxEventNum = 12u;
/* 接收滤波器 */
stcMcanInit.stcFilter.pstcStdFilterList = &stcStdFilterList;
stcMcanInit.stcFilter.pstcExtFilterList = &stcExtFilterList;
stcMcanInit.stcFilter.u32StdFilterConfigNum = stcMcanInit.stcMsgRam.u32StdFilterNum;
stcMcanInit.stcFilter.u32ExtFilterConfigNum = stcMcanInit.stcMsgRam.u32ExtFilterNum;
MCAN_Init(CM_MCAN1, &stcMcanInit);
//can1 Message RAM所占空间
Can1AllocatedSize = stcMcanInit.stcMsgRam.u32AllocatedSize;
/* 水位设置 */
MCAN_SetFifoWatermark(CM_MCAN1, MCAN_WATERMARK_RX_FIFO0, MCAN_RX_FIFO0_WATERMARK);
/* 设置 RXFIFO 在接收满的情况下使用覆盖模式 */
MCAN_RxFifoOperationModeConfig(CM_MCAN1, MCAN_RX_FIFO0, MCAN_RX_FIFO_OVERWRITE);
MCAN_IntCmd(CM_MCAN1, MCAN_RX_INT_SEL, MCAN_INT_LINE0, ENABLE);
/* Start the MCAN module */
//MCAN_Start(CM_MCAN1);
#endif
}
void Can2InitConfig(void)
{
#if CAN2_EN
stc_mcan_init_t stcMcanInit;
stc_mcan_filter_t stcStdFilterList = MCAN_STD_FILTER0;
stc_mcan_filter_t stcExtFilterList = MCAN_EXT_FILTER0;
CLK_SetCANClockSrc(CLK_MCAN2, CLK_MCANCLK_SYSCLK_DIV5);
MCAN_StructInit(&stcMcanInit);
stcMcanInit.u32Mode = MCAN_MD_NORMAL;
stcMcanInit.u32FrameFormat = MCAN_FRAME_CLASSIC;
/* Classic CAN. Baudrate 1Mbps, sample point 80% */
#if CAN2_BAUDRATE == 1000 //1MBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 2U;
#elif CAN2_BAUDRATE == 500 // 500KBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 4U;
#elif CAN2_BAUDRATE == 250 // 250KBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 8U;
#elif CAN2_BAUDRATE == 125 // 125KBps
stcMcanInit.stcBitTime.u32NominalPrescaler = 16U;
#endif
//stcMcanInit.stcBitTime.u32NominalPrescaler = 2U;
stcMcanInit.stcBitTime.u32NominalTimeSeg1 = 16U;
stcMcanInit.stcBitTime.u32NominalTimeSeg2 = 4U;
stcMcanInit.stcBitTime.u32NominalSyncJumpWidth = 4U;
/* Message RAM 最多分配512个字,共2KB */
stcMcanInit.stcMsgRam.u32AddrOffset = Can1AllocatedSize;//消息起始地址
stcMcanInit.stcMsgRam.u32StdFilterNum = 1u;//指定标准帧ID筛选器的数量
stcMcanInit.stcMsgRam.u32ExtFilterNum = 1u;//指定扩展帧ID筛选器的数量
/* 接收RAM配置 */
stcMcanInit.stcMsgRam.u32RxFifo0Num = MCAN_RX_FIFO0_NUM;
stcMcanInit.stcMsgRam.u32RxFifo0DataSize = MCAN_DATA_SIZE_8BYTE;
stcMcanInit.stcMsgRam.u32RxFifo1Num = 0u;
stcMcanInit.stcMsgRam.u32RxFifo1DataSize = MCAN_DATA_SIZE_8BYTE;
stcMcanInit.stcMsgRam.u32RxBufferNum = 0u;//指定专用Rx缓冲区元素的数量
stcMcanInit.stcMsgRam.u32RxBufferDataSize = MCAN_DATA_SIZE_8BYTE;
/* 发送RAM配置 */
stcMcanInit.stcMsgRam.u32TxBufferNum = MCAN_TX_BUF_NUM;//指定专用Tx缓冲区的数量
stcMcanInit.stcMsgRam.u32TxFifoQueueNum = MCAN_TX_FIFO_NUM;//Tx的FIFO数量
stcMcanInit.stcMsgRam.u32TxFifoQueueMode = MCAN_TX_FIFO_MD;//FIFO模式 (或者队列)
stcMcanInit.stcMsgRam.u32TxDataSize = MCAN_DATA_SIZE_8BYTE;
stcMcanInit.stcMsgRam.u32TxEventNum = 12u;
/* 接收滤波器 */
stcMcanInit.stcFilter.pstcStdFilterList = &stcStdFilterList;
stcMcanInit.stcFilter.pstcExtFilterList = &stcExtFilterList;
stcMcanInit.stcFilter.u32StdFilterConfigNum = stcMcanInit.stcMsgRam.u32StdFilterNum;
stcMcanInit.stcFilter.u32ExtFilterConfigNum = stcMcanInit.stcMsgRam.u32ExtFilterNum;
MCAN_Init(CM_MCAN2, &stcMcanInit);
//can2 Message RAM所占空间
Can2AllocatedSize = stcMcanInit.stcMsgRam.u32AllocatedSize;
/* 水位设置 */
MCAN_SetFifoWatermark(CM_MCAN2, MCAN_WATERMARK_RX_FIFO0, MCAN_RX_FIFO0_WATERMARK);
/* 设置 RXFIFO 在接收满的情况下使用覆盖模式 */
MCAN_RxFifoOperationModeConfig(CM_MCAN2, MCAN_RX_FIFO0, MCAN_RX_FIFO_OVERWRITE);
MCAN_IntCmd(CM_MCAN2, MCAN_RX_INT_SEL, MCAN_INT_LINE0, ENABLE);
/* Start the MCAN module */
//MCAN_Start(CM_MCAN2);
#endif
}
/**
* @brief MCAN interrupt line 0 IRQ handler.
* @param None
* @retval None
*/
void MCAN1_INT0_Handler(void)
{
uint32_t u32RxBuffer;
uint32_t u32TxBuffer = 0U;
/* FIFO0接收到新数据 */
if (MCAN_GetStatus(CM_MCAN1, MCAN_FLAG_RX_FIFO0_NEW_MSG) == SET)
{
MCAN_ClearStatus(CM_MCAN1, MCAN_FLAG_RX_FIFO0_NEW_MSG);
//读取新数据
if(MCAN_GetRxMsg(CM_MCAN1, MCAN_RX_FIFO0, &stcRx1Msg) == LL_OK)
{
}
}
//触发水位(watermark)中断
if (MCAN_GetStatus(CM_MCAN1, MCAN_FLAG_RX_FIFO0_WATERMARK) == SET)
{
MCAN_ClearStatus(CM_MCAN1, MCAN_FLAG_RX_FIFO0_WATERMARK);
u32RxBuffer = 0;u32TxBuffer = 0U;
while(MCAN_GetRxMsg(CM_MCAN1, MCAN_RX_FIFO0, &stcRx1Msg) == LL_OK)
{
McanLoadTxMsg(&stcTx2Msg, &stcRx1Msg);
stcTx2Msg.u32TxBuffer = 1UL << u32RxBuffer;
if (MCAN_AddMsgToTxBuffer(CM_MCAN2, &stcTx2Msg) == LL_OK)
{
u32TxBuffer |= stcTx2Msg.u32TxBuffer;
}
u32RxBuffer++;
}
MCAN_EnableTxBufferRequest(CM_MCAN2, u32TxBuffer);
}
//消息 FIFO 满中断
if (MCAN_GetStatus(CM_MCAN1, MCAN_FLAG_RX_FIFO0_FULL) == SET)
{
MCAN_ClearStatus(CM_MCAN1, MCAN_FLAG_RX_FIFO0_FULL);
u32RxBuffer = 0;u32TxBuffer = 0U;
while(MCAN_GetRxMsg(CM_MCAN1, MCAN_RX_FIFO0, &stcRx1Msg) == LL_OK)
{
McanLoadTxMsg(&stcTx2Msg, &stcRx1Msg);
stcTx2Msg.u32TxBuffer = 1UL << u32RxBuffer;
if (MCAN_AddMsgToTxBuffer(CM_MCAN2, &stcTx2Msg) == LL_OK)
{
u32TxBuffer |= stcTx2Msg.u32TxBuffer;
}
u32RxBuffer++;
}
MCAN_EnableTxBufferRequest(CM_MCAN2, u32TxBuffer);
}
}
/**
* @brief MCAN interrupt line 0 IRQ handler.
* @param None
* @retval None
*/
void MCAN2_INT0_Handler(void)
{
uint32_t u32RxBuffer;
uint32_t u32TxBuffer = 0U;
/* FIFO0接收到新数据 */
if (MCAN_GetStatus(CM_MCAN2, MCAN_FLAG_RX_FIFO0_NEW_MSG) == SET)
{
MCAN_ClearStatus(CM_MCAN2, MCAN_FLAG_RX_FIFO0_NEW_MSG);
//读取新数据
if(MCAN_GetRxMsg(CM_MCAN2, MCAN_RX_FIFO0, &stcRx2Msg) == LL_OK)
{
}
}
//触发水位(watermark)中断
if (MCAN_GetStatus(CM_MCAN2, MCAN_FLAG_RX_FIFO0_WATERMARK) == SET)
{
MCAN_ClearStatus(CM_MCAN2, MCAN_FLAG_RX_FIFO0_WATERMARK);
u32RxBuffer = 0;u32TxBuffer = 0U;//读取所有未读取的数据
while(MCAN_GetRxMsg(CM_MCAN2, MCAN_RX_FIFO0, &stcRx2Msg) == LL_OK)
{
McanLoadTxMsg(&stcTx1Msg, &stcRx2Msg);
stcTx1Msg.u32TxBuffer = 1UL << u32RxBuffer;
if (MCAN_AddMsgToTxBuffer(CM_MCAN1, &stcTx1Msg) == LL_OK)
{
u32TxBuffer |= stcTx1Msg.u32TxBuffer;
}
u32RxBuffer++;
}
MCAN_EnableTxBufferRequest(CM_MCAN1, u32TxBuffer);
}
//消息 FIFO 满中断
if (MCAN_GetStatus(CM_MCAN2, MCAN_FLAG_RX_FIFO0_FULL) == SET)
{
MCAN_ClearStatus(CM_MCAN2, MCAN_FLAG_RX_FIFO0_FULL);
u32RxBuffer = 0;u32TxBuffer = 0U;//读取所有未读取的数据
while(MCAN_GetRxMsg(CM_MCAN2, MCAN_RX_FIFO0, &stcRx2Msg) == LL_OK)
{
McanLoadTxMsg(&stcTx1Msg, &stcRx2Msg);
stcTx1Msg.u32TxBuffer = 1UL << u32RxBuffer;
if (MCAN_AddMsgToTxBuffer(CM_MCAN1, &stcTx1Msg) == LL_OK)
{
u32TxBuffer |= stcTx1Msg.u32TxBuffer;
}
u32RxBuffer++;
}
MCAN_EnableTxBufferRequest(CM_MCAN1, u32TxBuffer);
}
}
void McanLoadTxMsg(stc_mcan_tx_msg_t *pstcTxMsg, stc_mcan_rx_msg_t *pstcRxMsg)
{
*pstcTxMsg = *((stc_mcan_tx_msg_t *)pstcRxMsg);
}
void Can1SendBuff(stc_mcan_tx_msg_t *pstcTxMsg)
{
uint16_t tx_num = 0;
pstcTxMsg->u32TxBuffer = MCAN_TX_BUF0;
while((MCAN_AddMsgToTxFifoQueue(CM_MCAN1, pstcTxMsg) != LL_OK) && (tx_num < 0x1ff)) tx_num++;
}
void Can2SendBuff(stc_mcan_tx_msg_t *pstcTxMsg)
{
uint16_t tx_num = 0;
pstcTxMsg->u32TxBuffer = MCAN_TX_BUF0;
while((MCAN_AddMsgToTxFifoQueue(CM_MCAN2, pstcTxMsg) != LL_OK) && (tx_num < 0x1ff)) tx_num++;
}
void Can1SendData(u32 ID, u32 IDE, u32 DLC, u8 data0,u8 data1,u8 data2,u8 data3,u8 data4,u8 data5,u8 data6,u8 data7)
{
uint16_t tx_num = 0;
Tx1Message.ID = ID; //can id
Tx1Message.IDE = IDE; //0:标准帧 1:扩展帧
Tx1Message.RTR = 0; //0:数据帧 1:远程帧
Tx1Message.DLC = DLC; //数据长度
Tx1Message.u32TxBuffer = MCAN_TX_BUF10;
Tx1Message.au8Data[0] = data0;
Tx1Message.au8Data[1] = data1;
Tx1Message.au8Data[2] = data2;
Tx1Message.au8Data[3] = data3;
Tx1Message.au8Data[4] = data4;
Tx1Message.au8Data[5] = data5;
Tx1Message.au8Data[6] = data6;
Tx1Message.au8Data[7] = data7;
while((MCAN_AddMsgToTxFifoQueue(CM_MCAN1, &Tx1Message) != LL_OK) && (tx_num < 0x1ff)) tx_num++;
}
void Can2SendData(u32 ID, u32 IDE, u32 DLC, u8 data0,u8 data1,u8 data2,u8 data3,u8 data4,u8 data5,u8 data6,u8 data7)
{
uint16_t tx_num = 0;
Tx2Message.ID = ID; //can id
Tx2Message.IDE = IDE; //0:标准帧 1:扩展帧
Tx2Message.RTR = 0; //0:数据帧 1:远程帧
Tx2Message.DLC = DLC; //数据长度
Tx2Message.u32TxBuffer = MCAN_TX_BUF10;
Tx2Message.au8Data[0] = data0;
Tx2Message.au8Data[1] = data1;
Tx2Message.au8Data[2] = data2;
Tx2Message.au8Data[3] = data3;
Tx2Message.au8Data[4] = data4;
Tx2Message.au8Data[5] = data5;
Tx2Message.au8Data[6] = data6;
Tx2Message.au8Data[7] = data7;
while((MCAN_AddMsgToTxFifoQueue(CM_MCAN2, &Tx2Message) != LL_OK) && (tx_num < 0x1ff)) tx_num++;
}
|
|