完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32H743两路can的配置
FDCAN_HandleTypeDef FDCAN1_Handler; FDCAN_RxHeaderTypeDef FDCAN1_RxHeader; FDCAN_TxHeaderTypeDef FDCAN1_TxHeader; FDCAN_HandleTypeDef FDCAN2_Handler; FDCAN_RxHeaderTypeDef FDCAN2_RxHeader; FDCAN_TxHeaderTypeDef FDCAN2_TxHeader; FDCAN_RxHeaderTypeDef RxHeader; //初始化FDCAN1,波特率为500Kbit/S //配置FDCAN1的时钟源为PLL1Q=200Mhz //presc:分频值,取值范围1~512 //ntsjw:重新同步跳跃时间单元。范围:1~128 //ntsg1: 取值范围2~256 //ntsg2: 取值范围2~128 //mode:FDCAN_MODE_NORMAL,普通模式;FDCAN_MODE_EXTERNAL_LOOPBACK,回环模式; //返回值:0,初始化OK; // 其他,初始化失败; u8 FDCAN1_Mode_Init(u16 presc,u8 ntsjw,u16 ntsg1,u8 ntsg2,u32 mode) { FDCAN_FilterTypeDef FDCAN1_RXFilter; //初始化FDCAN1 HAL_FDCAN_DeInit(&FDCAN1_Handler); //先清除以前的设置 FDCAN1_Handler.Instance=FDCAN1; FDCAN1_Handler.Init.FrameFormat=FDCAN_FRAME_CLASSIC; //传统模式 FDCAN1_Handler.Init.Mode=mode; //回环测试 FDCAN1_Handler.Init.AutoRetransmission=DISABLE; //关闭自动重传!传统模式下一定要关闭!!! FDCAN1_Handler.Init.TransmitPause=DISABLE; //关闭传输暂停 FDCAN1_Handler.Init.ProtocolException=DISABLE; //关闭协议异常处理 FDCAN1_Handler.Init.NominalPrescaler=presc; //分频系数 FDCAN1_Handler.Init.NominalSyncJumpWidth=ntsjw; //重新同步跳跃宽度 FDCAN1_Handler.Init.NominalTimeSeg1=ntsg1; //tsg1范围:2~256 FDCAN1_Handler.Init.NominalTimeSeg2=ntsg2; //tsg2范围:2~128 FDCAN1_Handler.Init.MessageRAMOffset=0; //信息RAM偏移 FDCAN1_Handler.Init.StdFiltersNbr=0; //标准信息ID滤波器编号 FDCAN1_Handler.Init.ExtFiltersNbr=0; //扩展信息ID滤波器编号 FDCAN1_Handler.Init.RxFifo0ElmtsNbr=1; //接收FIFO0元素编号 FDCAN1_Handler.Init.RxFifo0ElmtSize=FDCAN_DATA_BYTES_8; //接收FIFO0元素大小:8字节 FDCAN1_Handler.Init.RxBuffersNbr=0; //接收缓冲编号 FDCAN1_Handler.Init.TxEventsNbr=0; //发送事件编号 FDCAN1_Handler.Init.TxBuffersNbr=0; //发送缓冲编号 FDCAN1_Handler.Init.TxFifoQueueElmtsNbr=1; //发送FIFO序列元素编号 FDCAN1_Handler.Init.TxFifoQueueMode=FDCAN_TX_FIFO_OPERATION; //发送FIFO序列模式 |
|
|
|
FDCAN1_Handler.Init.TxElmtSize=FDCAN_DATA_BYTES_8; //发送大小:8字节
if(HAL_FDCAN_Init(&FDCAN1_Handler)!=HAL_OK) return 1; //初始化FDCAN //FDCAN1_Handler.Init.MessageRAMOffset = FDCAN1_Handler.msgRam.EndAddress-SRAMCAN_BASE; //配置RX滤波器 FDCAN1_RXFilter.IdType=FDCAN_STANDARD_ID; //标准ID FDCAN1_RXFilter.FilterIndex=14; //滤波器索引 FDCAN1_RXFilter.FilterType=FDCAN_FILTER_MASK; //滤波器类型 FDCAN1_RXFilter.FilterConfig=FDCAN_FILTER_TO_RXFIFO0; //过滤器0关联到FIFO0 FDCAN1_RXFilter.FilterID1=0x0000; //32位ID FDCAN1_RXFilter.FilterID2=0x0000; //如果FDCAN配置为传统模式的话,这里是32位掩码 if(HAL_FDCAN_ConfigFilter(&FDCAN1_Handler,&FDCAN1_RXFilter)!=HAL_OK) return 2;//滤波器初始化 HAL_FDCAN_Start(&FDCAN1_Handler); //开启FDCAN HAL_FDCAN_ActivateNotification(&FDCAN1_Handler,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0); return 0; } u8 FDCAN2_Mode_Init(u16 presc,u8 ntsjw,u16 ntsg1,u8 ntsg2,u32 mode) { FDCAN_FilterTypeDef FDCAN2_RXFilter; //初始化FDCAN1 // HAL_FDCAN_DeInit(&FDCAN2_Handler); //先清除以前的设置 FDCAN2_Handler.Instance=FDCAN2; FDCAN2_Handler.Init.FrameFormat=FDCAN_FRAME_CLASSIC; //传统模式 FDCAN2_Handler.Init.Mode=mode; //回环测试 FDCAN2_Handler.Init.AutoRetransmission=DISABLE; //关闭自动重传!传统模式下一定要关闭!!! FDCAN2_Handler.Init.TransmitPause=DISABLE; //关闭传输暂停 FDCAN2_Handler.Init.ProtocolException=DISABLE; //关闭协议异常处理 FDCAN2_Handler.Init.NominalPrescaler=presc; //分频系数 FDCAN2_Handler.Init.NominalSyncJumpWidth=ntsjw; //重新同步跳跃宽度 FDCAN2_Handler.Init.NominalTimeSeg1=ntsg1; //tsg1范围:2~256 FDCAN2_Handler.Init.NominalTimeSeg2=ntsg2; //tsg2范围:2~128 FDCAN2_Handler.Init.MessageRAMOffset=FDCAN1_Handler.msgRam.EndAddress-SRAMCAN_BASE; //信息RAM偏移 FDCAN2_Handler.Init.StdFiltersNbr=0; //标准信息ID滤波器编号 FDCAN2_Handler.Init.ExtFiltersNbr=0; //扩展信息ID滤波器编号 FDCAN2_Handler.Init.RxFifo0ElmtsNbr=1; //接收FIFO0元素编号 FDCAN2_Handler.Init.RxFifo0ElmtSize=FDCAN_DATA_BYTES_8; //接收FIFO0元素大小:8字节 FDCAN2_Handler.Init.RxBuffersNbr=0; //接收缓冲编号 FDCAN2_Handler.Init.TxEventsNbr=0; //发送事件编号 FDCAN2_Handler.Init.TxBuffersNbr=0; //发送缓冲编号 FDCAN2_Handler.Init.TxFifoQueueElmtsNbr=2; //发送FIFO序列元素编号 FDCAN2_Handler.Init.TxFifoQueueMode=FDCAN_TX_FIFO_OPERATION; //发送FIFO序列模式 FDCAN2_Handler.Init.TxElmtSize=FDCAN_DATA_BYTES_8; //发送大小:8字节 if(HAL_FDCAN_Init(&FDCAN2_Handler)!=HAL_OK) return 1; //初始化FDCAN //FDCAN1_Handler.Init.MessageRAMOffset = FDCAN1_Handler.msgRam.EndAddress-SRAMCAN_BASE; //配置RX滤波器 FDCAN2_RXFilter.IdType=FDCAN_STANDARD_ID; //标准ID FDCAN2_RXFilter.FilterIndex=0; //滤波器索引 FDCAN2_RXFilter.FilterType=FDCAN_FILTER_MASK; //滤波器类型 FDCAN2_RXFilter.FilterConfig=FDCAN_FILTER_TO_RXFIFO0; //过滤器0关联到FIFO0 FDCAN2_RXFilter.FilterID1=0x0000; //32位ID FDCAN2_RXFilter.FilterID2=0x0000; //如果FDCAN配置为传统模式的话,这里是32位掩码 if(HAL_FDCAN_ConfigFilter(&FDCAN2_Handler,&FDCAN2_RXFilter)!=HAL_OK) return 2;//滤波器初始化 HAL_FDCAN_Start(&FDCAN2_Handler); //开启FDCAN HAL_FDCAN_ActivateNotification(&FDCAN2_Handler,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0); return 0; } //FDCAN1底层驱动,引脚配置,时钟使能 //HAL_FDCAN_Init()调用 //hsdram:FDCAN1句柄 void HAL_FDCAN_MspInit(FDCAN_HandleTypeDef* hfdcan) { /* GPIO_InitTypeDef GPIO_Initure; RCC_PeriphCLKInitTypeDef FDCAN_PeriphClk; __HAL_RCC_FDCAN_CLK_ENABLE(); //使能FDCAN1时钟 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 //FDCAN1时钟源配置为PLL1Q FDCAN_PeriphClk.PeriphClockSelection=RCC_PERIPHCLK_FDCAN; FDCAN_PeriphClk.FdcanClockSelection=RCC_FDCANCLKSOURCE_PLL; HAL_RCCEx_PeriphCLKConfig(&FDCAN_PeriphClk); GPIO_Initure.Pin=GPIO_PIN_11|GPIO_PIN_12; //PA11,12 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_MEDIUM; //超高速 GPIO_Initure.Alternate=GPIO_AF9_FDCAN1; //复用为CAN1 HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化 */ GPIO_InitTypeDef GPIO_Initure; RCC_PeriphCLKInitTypeDef FDCAN_PeriphClk; __HAL_RCC_FDCAN_CLK_ENABLE(); //使能FDCAN1时钟 __HAL_RCC_GPIOA_CLK_ENABLE(); //开启GPIOA时钟 __HAL_RCC_GPIOI_CLK_ENABLE(); //开启GPIOI时钟 __HAL_RCC_GPIOB_CLK_ENABLE(); //开启GPIOB时钟 //FDCAN1时钟源配置为PLL1Q FDCAN_PeriphClk.PeriphClockSelection=RCC_PERIPHCLK_FDCAN; FDCAN_PeriphClk.FdcanClockSelection=RCC_FDCANCLKSOURCE_PLL; HAL_RCCEx_PeriphCLKConfig(&FDCAN_PeriphClk); GPIO_Initure.Pin=GPIO_PIN_12; //PA12 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_MEDIUM; //超高速 GPIO_Initure.Alternate=GPIO_AF9_FDCAN1; //复用为CAN1 HAL_GPIO_Init(GPIOA,&GPIO_Initure); //初始化 GPIO_Initure.Pin=GPIO_PIN_9; //PI9 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_MEDIUM; //超高速 GPIO_Initure.Alternate=GPIO_AF9_FDCAN1; //复用为CAN1 HAL_GPIO_Init(GPIOI,&GPIO_Initure); //初始化 GPIO_Initure.Pin=GPIO_PIN_5|GPIO_PIN_13; //PB5 GPIO_Initure.Mode=GPIO_MODE_AF_PP; //推挽复用 GPIO_Initure.Pull=GPIO_PULLUP; //上拉 GPIO_Initure.Speed=GPIO_SPEED_FREQ_MEDIUM; //超高速 GPIO_Initure.Alternate=GPIO_AF9_FDCAN2; //复用为CAN2 HAL_GPIO_Init(GPIOB,&GPIO_Initure); //初始化 #if FDCAN1_RX0_INT_ENABLE HAL_NVIC_SetPriority(FDCAN1_IT0_IRQn,1,2); HAL_NVIC_EnableIRQ(FDCAN1_IT0_IRQn); #endif #if FDCAN2_RX1_INT_ENABLE HAL_NVIC_SetPriority(FDCAN2_IT0_IRQn,1,3); HAL_NVIC_EnableIRQ(FDCAN2_IT0_IRQn); #endif } //此函数会被HAL_FDCAN_DeInit调用 //hfdcan:fdcan句柄 void HAL_FDCAN_MspDeInit(FDCAN_HandleTypeDef* hfdcan) { __HAL_RCC_FDCAN_FORCE_RESET(); //复位FDCAN1 __HAL_RCC_FDCAN_RELEASE_RESET(); //停止复位 #if FDCAN1_RX0_INT_ENABLE HAL_NVIC_DisableIRQ(FDCAN1_IT0_IRQn); #endif #if FDCAN2_RX1_INT_ENABLE HAL_NVIC_DisableIRQ(FDCAN2_IT0_IRQn); #endif } //can发送一组数据(固定格式:ID为0X12,标准帧,数据帧) //len:数据长度(最大为8),可设置为FDCAN_DLC_BYTES_2~FDCAN_DLC_BYTES_8 //msg:数据指针,最大为8个字节。 //返回值:0,成功; // 其他,失败; u8 FDCAN1_Send_Msg(u8* msg,u32 len) { FDCAN1_TxHeader.Identifier=0x13; //32位ID FDCAN1_TxHeader.IdType=FDCAN_STANDARD_ID; //标准ID FDCAN1_TxHeader.TxFrameType=FDCAN_DATA_FRAME; //数据帧 FDCAN1_TxHeader.DataLength=len; //数据长度 FDCAN1_TxHeader.ErrorStateIndicator=FDCAN_ESI_ACTIVE; FDCAN1_TxHeader.BitRateSwitch=FDCAN_BRS_OFF; //关闭速率切换 FDCAN1_TxHeader.FDFormat=FDCAN_CLASSIC_CAN; //传统的CAN模式 FDCAN1_TxHeader.TxEventFifoControl=FDCAN_NO_TX_EVENTS; //无发送事件 FDCAN1_TxHeader.MessageMarker=0; if(HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN1_Handler,&FDCAN1_TxHeader,msg)!=HAL_OK) return 1;//发送 return 0; } u8 FDCAN2_Send_Msg(u8* msg,u32 len) { FDCAN2_TxHeader.Identifier=0x12; //32位ID FDCAN2_TxHeader.IdType=FDCAN_STANDARD_ID; //标准ID FDCAN2_TxHeader.TxFrameType=FDCAN_DATA_FRAME; //数据帧 FDCAN2_TxHeader.DataLength=len; //数据长度 FDCAN2_TxHeader.ErrorStateIndicator=FDCAN_ESI_ACTIVE; FDCAN2_TxHeader.BitRateSwitch=FDCAN_BRS_OFF; //关闭速率切换 FDCAN2_TxHeader.FDFormat=FDCAN_CLASSIC_CAN; //传统的CAN模式 FDCAN2_TxHeader.TxEventFifoControl=FDCAN_NO_TX_EVENTS; //无发送事件 FDCAN2_TxHeader.MessageMarker=0; if(HAL_FDCAN_AddMessageToTxFifoQ(&FDCAN2_Handler,&FDCAN2_TxHeader,msg)!=HAL_OK) return 1;//发送 return 0; } //can口接收数据查询 //buf:数据缓存区; //返回值:0,无数据被收到; // 其他,接收的数据长度; u8 FDCAN1_Receive_Msg(u8 *buf) { if(HAL_FDCAN_GetRxMessage(&FDCAN1_Handler,FDCAN_RX_FIFO0,&FDCAN1_RxHeader,buf)!=HAL_OK)return 0;//接收数据 return FDCAN1_RxHeader.DataLength》》16; } u8 FDCAN2_Receive_Msg(u8 *buf) { if(HAL_FDCAN_GetRxMessage(&FDCAN2_Handler,FDCAN_RX_FIFO0,&FDCAN2_RxHeader,buf)!=HAL_OK)return 0;//接收数据 return FDCAN2_RxHeader.DataLength》》16; } #if FDCAN1_RX0_INT_ENABLE //FDCAN1中断服务函数 void FDCAN1_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&FDCAN1_Handler); } #endif #if FDCAN2_RX1_INT_ENABLE //FDCAN1中断服务函数 void FDCAN2_IT0_IRQHandler(void) { HAL_FDCAN_IRQHandler(&FDCAN2_Handler); } #endif //FIFO0回调函数 void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs) { u8 i=0; u8 rxdata[8]; u8 rxdata_can1[8]; u8 rxdata_can2[8]; if((RxFifo0ITs&FDCAN_IT_RX_FIFO0_NEW_MESSAGE)!=RESET) //FIFO1新数据中断 { //提取FIFO0中接收到的数据 HAL_FDCAN_GetRxMessage(hfdcan,FDCAN_RX_FIFO0,&RxHeader,rxdata); //printf(“id:%#xrn”,FDCAN1_RxHeader.Identifier); // printf(“len:%drn”,FDCAN1_RxHeader.DataLength》》16); // for(i=0;i《8;i++) //printf(“rxdata[%d]:%drn”,i,rxdata[i]); HAL_FDCAN_ActivateNotification(hfdcan,FDCAN_IT_RX_FIFO0_NEW_MESSAGE,0); } } can.h文件 //FDCAN1接收RX0中断使能 #define FDCAN1_RX0_INT_ENABLE 0 //0,不使能;1,使能。 #define FDCAN2_RX1_INT_ENABLE 1 u8 FDCAN1_Mode_Init(u16 presc,u8 ntsjw,u16 ntsg1,u8 ntsg2,u32 mode); u8 FDCAN1_Send_Msg(u8* msg,u32 len); u8 FDCAN1_Receive_Msg(u8 *buf); u8 FDCAN2_Mode_Init(u16 presc,u8 ntsjw,u16 ntsg1,u8 ntsg2,u32 mode); u8 FDCAN2_Send_Msg(u8* msg,u32 len); u8 FDCAN2_Receive_Msg(u8 *buf); main函数 FDCAN1_Mode_Init(10,8,31,8,FDCAN_MODE_INTERNAL_LOOPBACK); //回环测试 FDCAN2_Mode_Init(10,8,31,8,FDCAN_MODE_INTERNAL_LOOPBACK); //回环测试 canbuf_can1_tx[0]=0;//填充发送缓冲区 canbuf_can1_tx[1]=1; canbuf_can1_tx[2]=2; canbuf_can1_tx[3]=3; canbuf_can1_tx[4]=4; canbuf_can1_tx[5]=5; canbuf_can1_tx[6]=6; canbuf_can1_tx[7]=7+t; canbuf_can2_tx[0]=10;//填充发送缓冲区 canbuf_can2_tx[1]=11; canbuf_can2_tx[2]=12; canbuf_can2_tx[3]=13; canbuf_can2_tx[4]=14; canbuf_can2_tx[5]=15; canbuf_can2_tx[6]=0x10; canbuf_can2_tx[7]=0x11+t; res=FDCAN1_Send_Msg(canbuf_can1_tx,FDCAN_DLC_BYTES_8);//发送8个字节 res=FDCAN2_Send_Msg(canbuf_can2_tx,FDCAN_DLC_BYTES_8);//发送8个字节 /*如果要用轮询方式打开下列两个函数,将中断关掉 //key=FDCAN1_Receive_Msg(canbuf_can1_rx); // key=FDCAN2_Receive_Msg(canbuf_can2_rx); 在调试的时候遇到不进中断的问题,当时以为can1 fifo0对应的中断是中断0那么can2 的中断则对应的是中断1所以调试老半天也不进中断,个人理解不知道对不对如果想要can2对应中断1那么应该设置对应fifo1 ,在配置can2的时候偏移地址应该设置fifo1的地址才可以,这个没有研究以后有时间在研究,而我的设置是围绕fifo0的配置来的所以应该遵循fifo0的配置,(fifo0对应中断0)还有在设置fifo0的中断时can1和can2共用回掉fifo0的函数而且他们也共用一条中断线0。在回调函数中可以设置想要的id和数据。 第一次写帖子可能有些不足的地方还请见谅,本人也第一次用stm32h743的芯片在can配置的时候会有理解不对的地方还请大家指出不胜感激。大神不喜勿喷! |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1771 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1070 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
728浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
568浏览 3评论
593浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-22 15:40 , Processed in 0.859572 second(s), Total 81, Slave 64 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号