目的
通过stm32CubeMx配置CAN,实现回环测试
cubemx配置
时钟配置
开启外部时钟
打开sw调试
配置串口,默认配置
配置CAN
clk=APB1=36M;
波特率=clk/Prescaler /(1 + Segment1 + Segment2);
= 36M/4/(1+5+3)=1M;最高波特率1M
传输优先级禁止时取决于报文
Receive Fifo Locked Mode禁止时,FIFO满了不会覆盖原有数据
中断配置
代码编写:
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.c
* @brief : Main program body
******************************************************************************
* @attention
*
* <h2><center>© Copyright (c) 2021 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#define CAN_ID ((uint32_t)0x1314)
CAN_RxHeaderTypeDef CanRx;//接收消息报文信息
CAN_TxHeaderTypeDef CanTx;//发送消息报文信息
uint8_t RxData[8]; //接收数据区
uint8_t TxData[8] = {0,10,2,3,4,5,6,7};//发送数据区
uint8_t Flag_Rx = 0; //接收到数据的标志
uint32_t pTxMailbox = 0; //发送邮箱盒子
/********************************************
@function:Can_Config,对于Can的CubeMx外的基础配置
@param:void
@return:HAL_StatusTypeDef
@date:2021.5.31
@note:
********************************************/
HAL_StatusTypeDef Can_Config(void)
{
CAN_FilterTypeDef sFilterConfig;
CanTx.DLC = 8; //数据长度
CanTx.ExtId = CAN_ID;
CanTx.IDE = CAN_ID_EXT; //扩展帧模式
CanTx.RTR = CAN_RTR_DATA; //数据帧
CanTx.StdId = 0x00; //使用扩展帧时需置零
CanTx.TransmitGlobalTime = DISABLE;//时间戳
sFilterConfig.FilterActivation = CAN_FILTER_ENABLE; //筛选器使能
sFilterConfig.FilterBank = 0; //筛选器0
sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0;//指定将分配给过滤器的FIFO(0或1U)。
sFilterConfig.FilterIdHigh = (((CAN_ID<<3) | CAN_ID_EXT | CAN_RTR_DATA)&0xFFFF0000)>>16; //ID的高16位
sFilterConfig.FilterIdLow = ((CAN_ID<<3) | CAN_ID_EXT | CAN_RTR_DATA) & 0xFFFF; //ID的低16位,只接收扩展帧模式、数据帧
sFilterConfig.FilterMaskIdHigh = 0;//FilterMask高低字节数据中位为1时代表必须与ID该位一致,0xFFFFFFFF代表接收筛选必须与ID一致才通过
sFilterConfig.FilterMaskIdLow = 0;
sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//掩码模式
sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//32位
sFilterConfig.SlaveStartFilterBank = 0;
if(HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK)
{
return HAL_ERROR;
}
if(HAL_CAN_Start(&hcan) != HAL_OK) //启动CAN
{
return HAL_ERROR;
}
if(HAL_CAN_ActivateNotification(&hcan,CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)//激活CAN_IT_RX_FIFO0_MSG_PENDING中断
{
return HAL_ERROR;
}
return HAL_OK;
}
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)//报文接收中断
{
if(HAL_CAN_GetRxMessage(hcan, CAN_FILTER_FIFO0, &CanRx, RxData) == HAL_OK)
{
Flag_Rx = 1;
}
}
void HAL_CAN_RxFifo0FullCallback(CAN_HandleTypeDef *hcan)//当接收的Fifo0满了的时候产生该中断
{
}
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
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_USART1_UART_Init();
MX_CAN_Init();
/* USER CODE BEGIN 2 */
Can_Config();
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
if(Flag_Rx)
{
Flag_Rx = 0;
printf("Rx:%d %d %d\r\n",RxData[0],RxData[1],RxData[2]);
printf("ID=0x%0x\r\n",CanRx.ExtId);
TxData[0]++;
}
if(HAL_CAN_AddTxMessage(&hcan, &CanTx, TxData, &pTxMailbox) != HAL_OK)//发送数据
{
printf("Tx Fail\r\n");
}
CanTx.ExtId++;
HAL_Delay(500);
if(Flag_Rx)
{
Flag_Rx = 0;
printf("Rx:%d %d %d\r\n",RxData[0],RxData[1],RxData[2]);
printf("ID=0x%0x\r\n",CanRx.ExtId);
TxData[0]++;
}
if(HAL_CAN_AddTxMessage(&hcan, &CanTx, TxData, &pTxMailbox) != HAL_OK)//发送数据
{
printf("Tx Fail\r\n");
}
CanTx.ExtId--;
printf("System Run\r\n");
HAL_Delay(500);
}
/* USER CODE END 3 */
}
效果
注意1
当此处代码为0时代表,只要是报文就接收:
sFilterConfig.FilterMaskIdHigh = 0;//FilterMask高低字节数据中位为1时代表必须与ID该位一致,0xFFFFFFFF代表接收筛选必须与ID一致才通过
sFilterConfig.FilterMaskIdLow = 0;
注意2
当此处代码为oxFFFF时代表,只接收与ID位全匹配:
sFilterConfig.FilterMaskIdHigh = 0xFFFF;//FilterMask高低字节数据中位为1时代表必须与ID该位一致,0xFFFFFFFF代表接收筛选必须与ID一致才通过
sFilterConfig.FilterMaskIdLow = 0xFFFF;
代码链接
链接:https://pan.baidu.com/s/1A3GRqDl0Fl4Rm_jhH8RBAw
提取码:y9gq
复制这段内容后打开百度网盘手机App,操作更方便哦
备注
回环模式测试通过后通过控制器芯片使用正常模式即可收发数据
版权声明:本文为qq_36561846原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。