stm32H743can配置

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:%#x\r\n",FDCAN1_RxHeader.Identifier);
       // printf("len:%d\r\n",FDCAN1_RxHeader.DataLength>>16);
       // for(i=0;i<8;i++)
        //printf("rxdata[%d]:%d\r\n",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配置的时候会有理解不对的地方还请大家指出!转载时请贴出本文的地址

  • 4
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
对于STM32H743,CAN透传是通过配置CAN控制器的工作模式来实现的。下面是一个简单的示例代码,演示了如何设置CAN控制器为透传模式: ```c #include "stm32h7xx.h" // 定义CAN通信参数 #define CAN1_TX_GPIO_PORT GPIOB #define CAN1_RX_GPIO_PORT GPIOB #define CAN1_TX_PIN GPIO_PIN_9 #define CAN1_RX_PIN GPIO_PIN_8 // 定义CAN过滤器参数 #define CAN_FILTER_ID 0x123 #define CAN_FILTER_MASK 0x7FF void CAN1_Config(void) { CAN_FilterTypeDef can_filter; GPIO_InitTypeDef gpio_init; // 使能CAN1时钟 __HAL_RCC_CAN1_CLK_ENABLE(); // 配置CAN引脚为复用功能 gpio_init.Pin = CAN1_TX_PIN | CAN1_RX_PIN; gpio_init.Mode = GPIO_MODE_AF_PP; gpio_init.Pull = GPIO_NOPULL; gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; gpio_init.Alternate = GPIO_AF9_CAN1; HAL_GPIO_Init(CAN1_TX_GPIO_PORT, &gpio_init); // 配置CAN控制器 hcan1.Instance = CAN1; hcan1.Init.Prescaler = 10; hcan1.Init.Mode = CAN_MODE_NORMAL; hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ; hcan1.Init.TimeSeg1 = CAN_BS1_15TQ; hcan1.Init.TimeSeg2 = CAN_BS2_4TQ; hcan1.Init.TimeTriggeredMode = DISABLE; hcan1.Init.AutoBusOff = DISABLE; hcan1.Init.AutoWakeUp = DISABLE; hcan1.Init.AutoRetransmission = DISABLE; hcan1.Init.ReceiveFifoLocked = DISABLE; hcan1.Init.TransmitFifoPriority = DISABLE; // 初始化CAN控制器 HAL_CAN_Init(&hcan1); // 配置CAN过滤器 can_filter.FilterBank = 0; can_filter.FilterMode = CAN_FILTERMODE_IDMASK; can_filter.FilterScale = CAN_FILTERSCALE_32BIT; can_filter.FilterIdHigh = (CAN_FILTER_ID << 5) >> 16; can_filter.FilterIdLow = (CAN_FILTER_ID << 5) & 0xFFFF; can_filter.FilterMaskIdHigh = (CAN_FILTER_MASK << 5) >> 16; can_filter.FilterMaskIdLow = (CAN_FILTER_MASK << 5) & 0xFFFF; can_filter.FilterFIFOAssignment = CAN_RX_FIFO0; can_filter.FilterActivation = ENABLE; HAL_CAN_ConfigFilter(&hcan1, &can_filter); // 启动CAN通信 HAL_CAN_Start(&hcan1); } int main(void) { CAN1_Config(); while(1) { // 接收CAN数据 if(HAL_CAN_GetRxFifoFillLevel(&hcan1, CAN_RX_FIFO0) > 0) { CAN_RxHeaderTypeDef rx_header; uint8_t rx_data[8]; HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &rx_header, rx_data); // 处理接收到的数据 // 发送CAN数据 CAN_TxHeaderTypeDef tx_header; uint8_t tx_data[8] = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; tx_header.StdId = CAN_FILTER_ID; tx_header.ExtId = 0x00; tx_header.IDE = CAN_ID_STD; tx_header.RTR = CAN_RTR_DATA; tx_header.DLC = 8; HAL_CAN_AddTxMessage(&hcan1, &tx_header, tx_data, NULL); } } } ``` 以上代码配置了CAN1控制器为透传模式,并实现了简单的接收和发送CAN数据的功能。你可以根据自己的需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值