stm32实现CAN通讯测试

1.3CAN通讯案例1:环回静默模式测试

1.3.1需求描述

我们使用环回静默模式测试CAN能否正常工作。把接收到的报文数据发送到串口输出,看是否可以正常工作。

电路原理图---stm32需要can连接的引脚

这个是stm32f103的数据手册说明 PB8和PB9需要重定义才能使用can功能 stm32f103的默认can引脚不是 PB8和PB9

我们没有用CAN的默认引脚,而是用的重定向的引脚PB8和PB9。

1.4 stm32cubemx 配置

选择好芯片配置后进行配置

1.4.1 单线调试模式和时钟



1.4.2 配置usart 做串口输出

1.4.3 配置CAN引脚 并修改引脚 并配置参数





参数说明

导出项目

1.5 打开keil配置支持c库 设置目录和代码


配置烧录自动重启


路径配置和文件配置

配置Common_debug.c文件和Drivers_can.c文件

编写 common_debug.c 和 Dervers_can.c 和main.c

c 复制代码
#include "Common_Debug.h"


void Common_Debug_Init(void)
{
    //MX_USART1_UART_Init();
}

int fputc(int c, FILE *file)
{
    HAL_UART_Transmit(&huart1, (uint8_t *)&c, 1, 1000);
    return c;
}
c 复制代码
#include "Driver_CAN.h"
#include "string.h"

static void Driver_CAN_ConfigFilter(void);

void Driver_CAN_Init(void)
{
    MX_CAN_Init();

    Driver_CAN_ConfigFilter();

    HAL_CAN_Start(&hcan);
}

static void Driver_CAN_ConfigFilter(void)
{
    CAN_FilterTypeDef filter;
    filter.FilterBank = 0;  /* 过滤器0 */
    filter.FilterFIFOAssignment = CAN_FILTER_FIFO0;  /* 把过滤器0与fifo0绑定 */
    filter.FilterMode = CAN_FILTERMODE_IDMASK; /* 掩码模式 */
    filter.FilterScale = CAN_FILTERSCALE_32BIT;
    filter.FilterIdHigh =0x0;
    filter.FilterIdLow =0x0;

    filter.FilterMaskIdHigh = 0x0;
    filter.FilterMaskIdLow = 0x0;

    filter.FilterActivation = CAN_FILTER_ENABLE;
    HAL_CAN_ConfigFilter(&hcan, &filter);
}

/**
 * @description: 发送信息
 * @param {uint16_t} id 信息的id
 * @param {uint8_t} *data 数据
 * @param {uint8_t} len 数据的长度(字节个数)
 */
void Driver_CAN_SendMsg(uint16_t id, uint8_t *data, uint8_t len)
{
    if(len > 8) return;
    uint32_t mailBox = 0;
    CAN_TxHeaderTypeDef header;
    header.DLC = len;
    header.StdId = id;
    header.IDE = CAN_ID_STD;
    header.RTR = CAN_RTR_DATA;

    HAL_CAN_AddTxMessage(&hcan, &header, data, &mailBox);
}

/* 一次性把接收到的所有报文全部读取 */
void Driver_CAN_RecevieMsgs(RxMsgStruct msgs[], uint8_t *count)
{
    /* 获取目前报文数 */
    *count = HAL_CAN_GetRxFifoFillLevel(&hcan, CAN_RX_FIFO0);
    CAN_RxHeaderTypeDef header;
    for (uint8_t i = 0; i < *count; i++)
    {
        memset(msgs[i].data, 0, 8);


        HAL_CAN_GetRxMessage(&hcan, CAN_RX_FIFO0, &header, msgs[i].data);
        msgs[i].id = header.StdId;
        msgs[i].len = header.DLC;
    }
}

main.c

c 复制代码
/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file           : main.c
 * @brief          : Main program body
 ******************************************************************************
 * @attention
 *
 * Copyright (c) 2024 STMicroelectronics.
 * All rights reserved.
 *
 * This software is licensed under terms that can be found in the LICENSE file
 * in the root directory of this software component.
 * If no LICENSE file comes with this software, it is provided AS-IS.
 *
 ******************************************************************************
 */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "can.h"
#include "usart.h"
#include "gpio.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "Driver_CAN.h"
#include "Common_Debug.h"
/* 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 */
RxMsgStruct msgs[3];
uint8_t     msgCount;
/* 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_CAN_Init();
    MX_USART1_UART_Init();
    /* USER CODE BEGIN 2 */

    /* USER CODE END 2 */

    /* Infinite loop */
    /* USER CODE BEGIN WHILE */
    debug_init();
    debug_printfln("hal库CAN");
    Driver_CAN_Init();
    /* 先发送 */
    Driver_CAN_SendMsg(0x1, "abcdef", 6);
    Driver_CAN_SendMsg(0x2, "abc", 3);
    Driver_CAN_SendMsg(0x3, "1234", 4);
    Driver_CAN_SendMsg(0x4, "12345", 5);
    debug_printfln("发送完成...");
    while(1)
    {
        msgCount = 0;
        Driver_CAN_RecevieMsgs(msgs, &msgCount);
        for(uint8_t i = 0; i < msgCount; i++)
        {
            debug_printfln("id = %#x, len = %d, msg = %.*s",
                           msgs[i].id,
                           msgs[i].len,
                           msgs[i].len,
                           msgs[i].data);
        }
        /* USER CODE END WHILE */

        /* USER CODE BEGIN 3 */
    }
    /* USER CODE END 3 */
}

/**
 * @brief System Clock Configuration
 * @retval None
 */
void SystemClock_Config(void)
{
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    /** Initializes the RCC Oscillators according to the specified parameters
     * in the RCC_OscInitTypeDef structure.
     */
    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState       = RCC_HSE_ON;
    RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
    RCC_OscInitStruct.HSIState       = RCC_HSI_ON;
    RCC_OscInitStruct.PLL.PLLState   = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource  = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLMUL     = RCC_PLL_MUL9;
    if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
    {
        Error_Handler();
    }

    /** Initializes the CPU, AHB and APB buses clocks
     */
    RCC_ClkInitStruct.ClockType      = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
    RCC_ClkInitStruct.SYSCLKSource   = RCC_SYSCLKSOURCE_PLLCLK;
    RCC_ClkInitStruct.AHBCLKDivider  = RCC_SYSCLK_DIV1;
    RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

    if(HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
    {
        Error_Handler();
    }
}

/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
 * @brief  This function is executed in case of error occurrence.
 * @retval None
 */
void Error_Handler(void)
{
    /* USER CODE BEGIN Error_Handler_Debug */
    /* User can add his own implementation to report the HAL error return state */
    __disable_irq();
    while(1)
    {
    }
    /* USER CODE END Error_Handler_Debug */
}

#ifdef USE_FULL_ASSERT
/**
 * @brief  Reports the name of the source file and the source line number
 *         where the assert_param error has occurred.
 * @param  file: pointer to the source file name
 * @param  line: assert_param error line source number
 * @retval None
 */
void assert_failed(uint8_t *file, uint32_t line)
{
    /* USER CODE BEGIN 6 */
    /* User can add his own implementation to report the file name and line number,
       ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
    /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */
相关推荐
Silicore_Emma8 小时前
芯谷科技—D2010:高效电机控制与保护的卓越之选
单片机·电机控制·工业自动化·电动工具调速·智能家电设备·绍兴芯谷·d2010
xiaohai@Linux8 小时前
基于 TCP 的IOT物联网云端服务端和设备客户端通信架构设计与实现
嵌入式硬件·物联网·网络协议·tcp/ip
创界工坊工作室8 小时前
DPJ-137 基于单片机的公交车自动报站系统设计(源代码+proteus仿真)
stm32·单片机·嵌入式硬件·51单片机·proteus
疯狂的豆包9 小时前
ESP32与MAX98357:打造智能收音机的奇妙之旅
单片机
啃硬骨头9 小时前
Aurix TC387 Ethernet代码解析之六_MAC的LwIP初始化3
单片机·嵌入式硬件
啃硬骨头9 小时前
Aurix TC387 Ethernet代码解析之四_MAC的LwIP初始化1
单片机·嵌入式硬件
xingzhemengyou19 小时前
STM32简介
stm32·单片机·嵌入式硬件
zore_c9 小时前
【C语言】贪吃蛇游戏超详解(包含音效、颜色、封装成应用等)
c语言·数据结构·笔记·stm32·游戏·链表
意法半导体STM3210 小时前
【官方原创】使用STM32N6测试Helium指令 LAT1567
stm32·单片机·嵌入式硬件·mcu·stm32开发