STM32F105RCT6使用CubeMX初始化工程——2:初始化CAN通信

目录

1:Cube初始化设置

2:配置过滤器

3:添加接收中断函数

4:通信测试


1:Cube初始化设置

配置对应引脚:配置CAN1的波特率为500kbps。CAN2配置同CAN1。

勾选接收中断函数。

2:配置过滤器

过滤器配置为不过滤。在CAN.c中的

/* USER CODE BEGIN 0 */

/* USER CODE END 0 */

中间添加过滤器初始函数。

void CAN1_Filter_Init(CAN_HandleTypeDef* canHandle)
{
   
 CAN_FilterTypeDef sFilterConfig;

 sFilterConfig.FilterActivation = ENABLE;//打开过滤器
 sFilterConfig.FilterBank = 1;//过滤器0 这里可设0-13
 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
 sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//采用FIFO0
 sFilterConfig.FilterIdHigh = 0x0000;//设置过滤器掩码高16位
 sFilterConfig.FilterIdLow = 0x0000;//设置过滤器掩码低16位
 sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
 sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位

 if(HAL_CAN_ConfigFilter(canHandle,&sFilterConfig) != HAL_OK)//初始化过滤器
 {
  Error_Handler();
 }
 if(HAL_CAN_Start(canHandle) != HAL_OK)//打开can
 {
  Error_Handler();
 }
 if(HAL_CAN_ActivateNotification(canHandle,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//开启接收中断
 {
  Error_Handler();
 }
}
void CAN2_Filter_Init(CAN_HandleTypeDef* canHandle)
{
  
 CAN_FilterTypeDef sFilterConfig;
 
 sFilterConfig.FilterActivation = ENABLE;//打开过滤器
 sFilterConfig.FilterBank = 13; //过滤器13 这里可设0-13
 sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//采用掩码模式
 sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//采用32位掩码模式
 sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO1;//采用FIFO1
 sFilterConfig.FilterIdHigh = 0x0000;//设置过滤器掩码高16位
 sFilterConfig.FilterIdLow = 0x0000;//设置过滤器掩码低16位
 sFilterConfig.FilterMaskIdHigh = 0x0000;//设置过滤器掩码高16位
 sFilterConfig.FilterMaskIdLow = 0x0000;//设置过滤器掩码低16位
 if(HAL_CAN_ConfigFilter(canHandle,&sFilterConfig) != HAL_OK)//初始化过滤器
 {
  Error_Handler();
 }
 if(HAL_CAN_Start(canHandle) != HAL_OK)//打开can
 {
  Error_Handler();
 }
 if(HAL_CAN_ActivateNotification(canHandle,CAN_IT_RX_FIFO1_MSG_PENDING) != HAL_OK)//开启接收中断
 {
  Error_Handler();
 }
}

STM32F105芯片复位后默认的0-13号过滤寄存器可以定向到CAN1的 FIFO1或者FIFO0,14-17号定向到CAN2的FIFO1或者FIFO0

过滤器配置时CAN1和CAN2的过滤器序号需要注意,我不太懂。下面这个是我当时看的一个博客。

STM32F105双CAN双FIFO通讯心得体会_xiaoyaofriend的专栏-CSDN博客

3:重写接收接收中断函数

main.c中 添加接收中断函数,只为了验证,随便抄了点(忘了出处),后续修改。

/* USER CODE BEGIN 4 */

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	uint8_t aRxData[8], i;
	//(STID+EXTID+IDE+RTR
	Can_Rx.StdId = 0x0Ff;
	Can_Rx.ExtId = 0x0Ff;
	Can_Rx.IDE = CAN_ID_EXT;//CAN_ID_STD 标准帧  CAN_ID_EXT 扩展帧
	Can_Rx.RTR = CAN_RTR_DATA;
	Can_Rx.DLC = 8;
	    if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &Can_Rx, aRxData) == HAL_OK)
	    {
				 printf("1Get Rx Message Success");
	        HAL_CAN_AddTxMessage(&hcan1,&Can_Tx,tdata,&pTxMailbox);
					//HAL_CAN_AddTxMessage(&hcan2,&Can_Tx,tdata,&pTxMailbox);

	    }
}

void HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	uint8_t aRxData[8], i;
	//(STID+EXTID+IDE+RTR
	Can_Rx.StdId = 0x0Ff;
	Can_Rx.ExtId = 0x0Ff;
	Can_Rx.IDE = CAN_ID_EXT;//CAN_ID_STD 标准帧  CAN_ID_EXT 扩展帧
	Can_Rx.RTR = CAN_RTR_DATA;
	Can_Rx.DLC = 8;
	    if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO1, &Can_Rx, aRxData) == HAL_OK)
	    {
	        printf("2Get Rx Message Success");
	        HAL_CAN_AddTxMessage(&hcan2,&Can_Tx,tdata,&pTxMailbox);
	    }
  
}

/* USER CODE END 4 */

4:通信测试

发送测试

主函数前添加变量定义。

/* USER CODE BEGIN PV */
    CAN_TxHeaderTypeDef Can_Tx;
	CAN_RxHeaderTypeDef Can_Rx;

	uint8_t tdata[8] = {0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77};
	uint32_t pTxMailbox = 0;

/* USER CODE END PV */

初始化

  /* USER CODE BEGIN 2 */
	CAN1_Filter_Init(&hcan1);
	CAN2_Filter_Init(&hcan2);

    Can_Tx.StdId = 0x123;
	Can_Tx.ExtId = 0x123;
	Can_Tx.IDE = CAN_ID_EXT;
	Can_Tx.RTR = 0;
	Can_Tx.DLC = 8;
  /* USER CODE END 2 */

在主函数while中添加发送函数。

/* USER CODE BEGIN 3 */
HAL_Delay(1000);
HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
HAL_CAN_AddTxMessage(&hcan1,&Can_Tx,tdata,&pTxMailbox);
HAL_CAN_AddTxMessage(&hcan2,&Can_Tx,tdata,&pTxMailbox);

接收测试

过滤器配置是个技术活。看了好几个博客才看明白点。索性不配了。

CAN通信不能使用问题

发现一个天坑,我用的这个芯片是GB32F105RC的芯片,今天想重新写个程序发现CAN通信不能用了,检查了所有配置代码都没有问题。然后使用以前的程序CAN通信正常。

检查无数遍后,在一个小伙伴的协助下和以前的程序进行了对比。查了一下cubeMx的库,发现版本有点小差别。改回去后就正常了。之前人们说GB32的芯片和STM32的一样,现在想来还是有点区别的,手头没有STM32的同款芯片,没办法测试,但我想Cube库版本发行的时候应该是都进行过测试,大概率还是芯片差异的问题。

STM32Cube FW_F1 V1.8.3(可用)

  • Patch release to fix GPIO/I2C issues.

STM32Cube FW_F1 V1.8.4(不可用)

  • Patch release to fix know defects and enhacements implementation.

  • 11
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
下面是一个简单的stm32f103rct6系统时钟初始化代码的示例,使用的是PLL时钟源,SYSCLK频率为72MHz: ``` #include "stm32f10x.h" void RCC_Configuration(void) { /* Enable HSE */ RCC->CR |= ((uint32_t)RCC_CR_HSEON); /* Wait till HSE is ready and if Time out is reached exit */ uint32_t StartUpCounter = 0; uint32_t HSEStatus = 0; do { HSEStatus = RCC->CR & RCC_CR_HSERDY; StartUpCounter++; } while((HSEStatus == 0) && (StartUpCounter != 0x5000)); if ((RCC->CR & RCC_CR_HSERDY) != RESET) { HSEStatus = (uint32_t)0x01; } else { HSEStatus = (uint32_t)0x00; } if (HSEStatus == (uint32_t)0x01) { /* Flash 2 wait state */ FLASH->ACR |= FLASH_ACR_LATENCY_2; /* HCLK = SYSCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_HPRE_DIV1; /* PCLK2 = HCLK */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE2_DIV1; /* PCLK1 = HCLK/2 */ RCC->CFGR |= (uint32_t)RCC_CFGR_PPRE1_DIV2; /* PLLCLK = 8MHz * 9 = 72 MHz */ RCC->CFGR |= (uint32_t)(RCC_CFGR_PLLSRC_HSE | RCC_CFGR_PLLMULL9); /* Enable PLL */ RCC->CR |= RCC_CR_PLLON; /* Wait till PLL is ready */ while((RCC->CR & RCC_CR_PLLRDY) == 0); /* Select PLL as system clock source */ RCC->CFGR &= (uint32_t)((uint32_t)~(RCC_CFGR_SW)); RCC->CFGR |= (uint32_t)RCC_CFGR_SW_PLL; /* Wait till PLL is used as system clock source */ while ((RCC->CFGR & (uint32_t)RCC_CFGR_SWS) != (uint32_t)0x08); } else { /* If HSE fails to start-up, the application will have wrong clock configuration. User can add here some code to deal with this error */ } } ``` 在这个代码中,我们首先使能了HSE(高速外部时钟),然后等待HSE就绪。接下来,我们设置了FLASH等待状态为2,以确保在72MHz时钟下运行时Flash操作正确。 然后,我们设置了AHB总线(HCLK)的分频系数为1,APB2总线(PCLK2)的分频系数为1,APB1总线(PCLK1)的分频系数为2。 然后,我们将PLL时钟源设置为HSE,并将倍频系数设置为9,以获得72MHz的SYSCLK。然后我们使能PLL,并等待它就绪。 最后,我们将SYSCLK时钟源设置为PLL,并等待它稳定。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值