当前位置: 首页 > article >正文

STM32MX 配置CANFD收发通讯

一、环境

MCU:STM32G0B1CEU6
CAN收发器:JIA1042

二、MX配置

配置SYS
在这里插入图片描述在这里插入图片描述在这里插入图片描述

配置canfd并开启中断,我开了两个FDCAN,配置是一样的,这里贴一下波特率的计算公式:
在这里插入图片描述
也就是:CAN时钟频率/预分频器/(1+TS1+TS2)
按照我这里的时钟就是:
CAN时钟频率为40MHZ,预分频器为1,TS1=5,TS2=4
所以数据段的频率为40/8/(1+5+4)=500MHZ
在这里插入图片描述

在这里插入图片描述

同时我这里开了个uart用作调试,配置完成后生成
在这里插入图片描述

三、滤波器配置

这里设置了ID为0x000,使用CANFD,数据长度64,滤波器在系统初始化完成后就可以进行配置了

void FDCAN1_config(void){

  FDCAN_FilterTypeDef sFilterConfig;

  /* Configure Rx filter */
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1 = 0x000;
  sFilterConfig.FilterID2 = 0x000;
  if (HAL_FDCAN_ConfigFilter(&hfdcan1, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /* Configure global filter:
     Filter all remote frames with STD and EXT ID
     Reject non matching frames with STD ID and EXT ID */
  if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan1, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
  {
    Error_Handler();
  }

  /* Start the FDCAN module */
  if (HAL_FDCAN_Start(&hfdcan1) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_FDCAN_ActivateNotification(&hfdcan1, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  {
    Error_Handler();
  }
	

	TxHeader.Identifier = 0x000;                 // CAN ID
	TxHeader.IdType = FDCAN_STANDARD_ID;        // 标准ID
	TxHeader.TxFrameType = FDCAN_DATA_FRAME;           
	TxHeader.DataLength = FDCAN_DLC_BYTES_64;
	TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
	TxHeader.BitRateSwitch = FDCAN_BRS_ON;
	TxHeader.FDFormat = FDCAN_FD_CAN;                  // CANFD
	TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
	TxHeader.MessageMarker = 0;
}
void FDCAN2_config(void){

  FDCAN_FilterTypeDef sFilterConfig;

  /* Configure Rx filter */
  sFilterConfig.IdType = FDCAN_STANDARD_ID;
  sFilterConfig.FilterIndex = 0;
  sFilterConfig.FilterType = FDCAN_FILTER_MASK;
  sFilterConfig.FilterConfig = FDCAN_FILTER_TO_RXFIFO0;
  sFilterConfig.FilterID1 = 0x000;
  sFilterConfig.FilterID2 = 0x000;
  if (HAL_FDCAN_ConfigFilter(&hfdcan2, &sFilterConfig) != HAL_OK)
  {
    Error_Handler();
  }

  /* Configure global filter:
     Filter all remote frames with STD and EXT ID
     Reject non matching frames with STD ID and EXT ID */
  if (HAL_FDCAN_ConfigGlobalFilter(&hfdcan2, FDCAN_REJECT, FDCAN_REJECT, FDCAN_FILTER_REMOTE, FDCAN_FILTER_REMOTE) != HAL_OK)
  {
    Error_Handler();
  }

  /* Start the FDCAN module */
  if (HAL_FDCAN_Start(&hfdcan2) != HAL_OK)
  {
    Error_Handler();
  }

  if (HAL_FDCAN_ActivateNotification(&hfdcan2, FDCAN_IT_RX_FIFO0_NEW_MESSAGE, 0) != HAL_OK)
  {
    Error_Handler();
  }
	
	TxHeader.Identifier = 0x000;                 // CAN ID
	TxHeader.IdType = FDCAN_STANDARD_ID;        // 标准ID
	TxHeader.TxFrameType = FDCAN_DATA_FRAME;           
	TxHeader.DataLength = FDCAN_DLC_BYTES_64;
	TxHeader.ErrorStateIndicator = FDCAN_ESI_ACTIVE;
	TxHeader.BitRateSwitch = FDCAN_BRS_ON;
	TxHeader.FDFormat = FDCAN_FD_CAN;                  // CANFD
	TxHeader.TxEventFifoControl = FDCAN_NO_TX_EVENTS;
	TxHeader.MessageMarker = 0;
}


四、发送和接收函数
这里我的发送是写在while里面的,实现的功能flag标志位1时,是一个canfd1发送数据,canfd2接收后flag值为2;flag为2时,canfd2发送数据,canfd1接收将flag值等于1
HAL库发送函数为:

HAL_FDCAN_AddMessageToTxFifoQ(FDCAN_HandleTypeDef *hfdcan, const FDCAN_TxHeaderTypeDef *pTxHeader,const uint8_t *pTxData)

接收函数为:

HAL_FDCAN_GetRxMessage(FDCAN_HandleTypeDef *hfdcan, uint32_t RxLocation,FDCAN_RxHeaderTypeDef *pRxHeader, uint8_t *pRxData)

下面时我的main(发送)和中断回调函数(接收)函数:

FDCAN_RxHeaderTypeDef RxHeader;
FDCAN_TxHeaderTypeDef TxHeader;
uint8_t TXData[64]={0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
												0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
												0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,
												0x00};
uint8_t RxData[64]={0};
uint8_t flag=1;
int main(void)
{

  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_FDCAN1_Init();
  MX_FDCAN2_Init();
  MX_USART3_UART_Init();
  /* USER CODE BEGIN 2 */
	FDCAN1_config();
	FDCAN2_config();
	HAL_Delay(2000);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		if(flag==0x01){
			if(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan1, &TxHeader, TXData)!=HAL_OK){
				Error_Handler();
			}
			HAL_Delay(1000);
		}else{
			if(HAL_FDCAN_AddMessageToTxFifoQ(&hfdcan2, &TxHeader, TXData)!=HAL_OK){
					Error_Handler();
			}
			HAL_Delay(1000);
		}
		HAL_Delay(1000);

    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
void HAL_FDCAN_RxFifo0Callback(FDCAN_HandleTypeDef *hfdcan, uint32_t RxFifo0ITs)
{
	if((RxFifo0ITs & FDCAN_IT_RX_FIFO0_NEW_MESSAGE) != RESET)
	{
	 if(hfdcan->Instance == FDCAN1)
		{
		 if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
		 {
			Error_Handler();
		 }
		 flag=0x01;
		 HAL_UART_Transmit(&huart3,&flag,1,1000);
		}
		if(hfdcan->Instance == FDCAN2)
		{
		 if (HAL_FDCAN_GetRxMessage(hfdcan, FDCAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
		 {
			Error_Handler();
		 }
		 flag=0x02;
		 HAL_UART_Transmit(&huart3,&flag,1,1000);
		}
	}
}


五、实际使用

实际使用过程中,需要将两个CANFD建立在一个CAN网络中才能进行通讯

六、源码工程

https://download.csdn.net/download/weixin_46516921/90080900


http://www.kler.cn/a/428582.html

相关文章:

  • linux-FTP服务配置与应用
  • QT 占位符的用法
  • 为什么你的 Qt 应用程序会出现 xcb 插件错误
  • 04JavaWeb——Maven-SpringBootWeb入门
  • ABP - 缓存模块(1)
  • 数据结构-ArrayList和顺序表
  • Java 并发舞台:多线程小精灵的奇幻冒险之旅
  • 第二十二天 TensorFlow基础
  • Android 常用倒计时技术和实现方式
  • element UI的Cascader 级联选择器在树形列表中编辑使用
  • 使用Excel的COUNTIFS和SUMIFS函数进行高级数据分析
  • 面向对象系统的分析和设计
  • QNX的安全文件策略:SECPOL
  • Linux学习——4_DNS域名解析服务器
  • Leetcode Hot 100【堆】215. 数组中的第K个最大元素
  • 探索HTML5与CSS3的流式布局:构建响应式网页设计的新纪元
  • go返回多个errors
  • Linux驱动开发(11):SPI子系统–OLED屏实验
  • YOLO系列发展历程:从YOLOv1到YOLO11,目标检测技术的革新与突破
  • Java Web 7 请求响应(Postman)
  • pyside6学习专栏(一)常用控件的使用(非QML方式)
  • dockerfile部署前后端(vue+springboot)
  • 16asm -指令
  • 2024/12/8 Windows安装Oracle19c
  • 锁相关的问题(死锁、互斥锁、自旋锁、读写锁、悲观锁、乐观锁)
  • Mac 录制电脑系统内的声音的具体方法?