STM32-HAL库09-CAN通讯(loopback模式)

一、所用材料:

STM32F103C6T6最小系统板
STM32CUBEMX(HAL库软件)
MDK5
串口调试助手

二、所学内容:

初步学习如何使用STM32的CAN通讯功能,在本章节主要达到板内CAN通讯的效果,即32发送CAN信息再在CAN接收中断中用串口打印出来。

三、CUBEMX配置:

第一步:老三件套-RCC,SYS,时钟树配置

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

第二步:串口配置

在这里插入图片描述

第三步:CAN配置

关键步骤:

  • 波特率设置:1M bit/s,具体配置如下图
  • TEST MODE - Loopback
  • 打开接收中断RX0
    在这里插入图片描述
    在这里插入图片描述

四、MDK5配置:

一、can.h头文件配置

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __CAN_H__
#define __CAN_H__#ifdef __cplusplus
extern "C" {
#endif/* Includes ------------------------------------------------------------------*/
#include "main.h"/* USER CODE BEGIN Includes *//* USER CODE END Includes */extern CAN_HandleTypeDef hcan;/* USER CODE BEGIN Private defines *//* USER CODE END Private defines */void MX_CAN_Init(void);/* USER CODE BEGIN Prototypes */
void CANFilter_Config(void);
void CAN1_Send_Test(void);
void CAN_Start_Init(void);
void CAN1_Send(uint8_t* cdata);
/* USER CODE END Prototypes */#ifdef __cplusplus
}
#endif#endif /* __CAN_H__ */

二、can.c源文件配置

/* Includes ------------------------------------------------------------------*/
#include "can.h"/* USER CODE BEGIN 0 */
#include "stdio.h"
#include "usart.h"
#include "main.h"
static CAN_TxHeaderTypeDef TxMessage; //CAN发送的消息的消息头
static CAN_RxHeaderTypeDef RxMessage; //CAN接收的消息的消息头
/* USER CODE END 0 */CAN_HandleTypeDef hcan;/* CAN init function */
void MX_CAN_Init(void)
{hcan.Instance = CAN1;hcan.Init.Prescaler = 4;hcan.Init.Mode = CAN_MODE_LOOPBACK;hcan.Init.SyncJumpWidth = CAN_SJW_1TQ;hcan.Init.TimeSeg1 = CAN_BS1_5TQ;hcan.Init.TimeSeg2 = CAN_BS2_3TQ;hcan.Init.TimeTriggeredMode = DISABLE;hcan.Init.AutoBusOff = DISABLE;hcan.Init.AutoWakeUp = DISABLE;hcan.Init.AutoRetransmission = DISABLE;hcan.Init.ReceiveFifoLocked = DISABLE;hcan.Init.TransmitFifoPriority = DISABLE;if (HAL_CAN_Init(&hcan) != HAL_OK){Error_Handler();}/* USER CODE BEGIN CAN_Init 2 *//* USER CODE END CAN_Init 2 */}void HAL_CAN_MspInit(CAN_HandleTypeDef* canHandle)
{GPIO_InitTypeDef GPIO_InitStruct = {0};if(canHandle->Instance==CAN1){/* USER CODE BEGIN CAN1_MspInit 0 *//* USER CODE END CAN1_MspInit 0 *//* CAN1 clock enable */__HAL_RCC_CAN1_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/**CAN GPIO ConfigurationPA11     ------> CAN_RXPA12     ------> CAN_TX*/GPIO_InitStruct.Pin = GPIO_PIN_11;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);GPIO_InitStruct.Pin = GPIO_PIN_12;GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);/* CAN1 interrupt Init */HAL_NVIC_SetPriority(USB_LP_CAN1_RX0_IRQn, 0, 0);HAL_NVIC_EnableIRQ(USB_LP_CAN1_RX0_IRQn);/* USER CODE BEGIN CAN1_MspInit 1 *//* USER CODE END CAN1_MspInit 1 */}
}void HAL_CAN_MspDeInit(CAN_HandleTypeDef* canHandle)
{if(canHandle->Instance==CAN1){/* USER CODE BEGIN CAN1_MspDeInit 0 *//* USER CODE END CAN1_MspDeInit 0 *//* Peripheral clock disable */__HAL_RCC_CAN1_CLK_DISABLE();/**CAN GPIO ConfigurationPA11     ------> CAN_RXPA12     ------> CAN_TX*/HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);/* CAN1 interrupt Deinit */HAL_NVIC_DisableIRQ(USB_LP_CAN1_RX0_IRQn);/* USER CODE BEGIN CAN1_MspDeInit 1 *//* USER CODE END CAN1_MspDeInit 1 */}
}/* USER CODE BEGIN 1 */
/*******************
接受信息过滤器
*******************/void CANFilter_Config(void)
{CAN_FilterTypeDef  sFilterConfig;sFilterConfig.FilterBank = 0;                       //CAN过滤器编号,范围0-27sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;   //CAN过滤器模式,掩码模式或列表模式sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;  //CAN过滤器尺度,16位或32位sFilterConfig.FilterIdHigh = 0x000 << 5;			//32位下,存储要过滤ID的高16位sFilterConfig.FilterIdLow = 0x0000;					//32位下,存储要过滤ID的低16位sFilterConfig.FilterMaskIdHigh = 0x0000;			//掩码模式下,存储的是掩码sFilterConfig.FilterMaskIdLow = 0x0000;sFilterConfig.FilterFIFOAssignment = 0;				//报文通过过滤器的匹配后,存储到哪个FIFOsFilterConfig.FilterActivation = ENABLE;    		//激活过滤器sFilterConfig.SlaveStartFilterBank = 0;if (HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) != HAL_OK) {Error_Handler();}else{ printf("HAL_CAN_ConfigFilter(&hcan, &sFilterConfig) is HAL_OK\r\n"); }
}
/*******************
中断接受
*******************/
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{uint8_t  data[8];HAL_StatusTypeDef	status;status = HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxMessage, data);if (HAL_OK == status){    printf("--->Data Receieve!\r\n");printf("RxMessage.StdId is %#x\r\n",  RxMessage.StdId);printf("data[0] is 0x%02x\r\n", data[0]);printf("data[1] is 0x%02x\r\n", data[1]);printf("data[2] is 0x%02x\r\n", data[2]);printf("data[3] is 0x%02x\r\n", data[3]);printf("data[4] is 0x%02x\r\n", data[4]);printf("data[5] is 0x%02x\r\n", data[5]);printf("data[6] is 0x%02x\r\n", data[6]);printf("data[7] is 0x%02x\r\n", data[7]);		printf("<---\r\n");   HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);		}
}/*******************
发送函数
*******************/
void CAN1_Send_Test(void)
{uint32_t TxMailbox;uint8_t data[4] = {0x01, 0x02, 0x03, 0x04};TxMessage.IDE = CAN_ID_STD;     //设置ID类型TxMessage.StdId = 0x111;        //设置ID号TxMessage.RTR = CAN_RTR_DATA;   //设置传送数据帧TxMessage.DLC = 4;              //设置数据长度if (HAL_CAN_AddTxMessage(&hcan, &TxMessage, data, &TxMailbox) != HAL_OK){Error_Handler();}	// else{ printf("HAL_CAN_AddTxMessage(&hcan, &TxMessage, data, &TxMailbox) is HAL_OK\r\n"); }
}void CAN1_Send(uint8_t* cdata)
{uint32_t TxMailbox;TxMessage.IDE = CAN_ID_STD;     //设置ID类型TxMessage.StdId = 0x111;        //设置ID号TxMessage.RTR = CAN_RTR_DATA;   //设置传送数据帧TxMessage.DLC = 8;              //设置数据长度	if (HAL_CAN_AddTxMessage(&hcan, &TxMessage, cdata, &TxMailbox) != HAL_OK){Error_Handler();}		
}
/*******************
CAN启动函数
*******************/
void CAN_Start_Init(void)
{if (HAL_CAN_Start(&hcan) != HAL_OK) {Error_Handler();}else{ printf("HAL_CAN_Start(&hcan) is HAL_OK\r\n"); }/* 3. Enable CAN RX Interrupt */if (HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) !=  HAL_OK) {Error_Handler();}else{ printf("HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING) is HAL_OK\r\n"); }	
}
/* USER CODE END 1 */

三、main.c文件配置

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 */CANFilter_Config();CAN_Start_Init();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){CAN1_Send_Test();HAL_Delay(1000);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

四、串口打印结果:

在这里插入图片描述

五、本文对应代码分享:

https://download.csdn.net/download/qq_45854134/88522530

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/169411.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个java文件的JVM之旅

准备 我是小C同学编写得一个java文件&#xff0c;如何实现我的功能呢&#xff1f;需要去JVM(Java Virtual Machine)这个地方旅行。 变身 我高高兴兴的来到JVM&#xff0c;想要开始JVM之旅&#xff0c;它确说&#xff1a;“现在的我还不能进去&#xff0c;需要做一次转换&#x…

2023年11月在线IDE流行度最新排名

点击查看最新在线IDE流行度最新排名&#xff08;每月更新&#xff09; 2023年11月在线IDE流行度最新排名 TOP 在线IDE排名是通过分析在线ide名称在谷歌上被搜索的频率而创建的 在线IDE被搜索的次数越多&#xff0c;人们就会认为它越受欢迎。原始数据来自谷歌Trends 如果您相…

jQuery HTML/CSS 参考文档

jQuery HTML/CSS 参考文档 文章目录 应用样式 示例属性方法示例 jQuery HTML/CSS 参考文档 应用样式 addClass( classes ) 方法可用于将定义好的样式表应用于所有匹配的元素上。可以通过空格分隔指定多个类。 示例 以下是一个简单示例&#xff0c;设置了para标签 <p&g…

恒源云之oss上传数据、云台下载数据

目录 一、本地cmd上传数据二、使用云平台下载数据 一、本地cmd上传数据 需要下载恒源云客户端oss需要先将数据&#xff08;代码、数据集&#xff09;压缩成zip文件。 本地cmd打开oss&#xff0c;测试是否安成功 oss输入oss命令&#xff0c;并正确输入账号密码 oss login在个人…

按键编程 pal库和标准库

按钮的电路设计 电路的搭建 原理与编程 创建了两个变量 用来捕捉按键的状态 先让两个变量都为1 previous和current都为1 &#xff08;按键没按下&#xff09; 然后让current去捕捉按键的状态通过读gpioA的pin0 如果为0就是按键按下 如果为1就是按键没按下 然后赋值给current …

将 Ordinals 与比特币智能合约集成:第 4 部分

控制 BSV-20 代币的分配 在上一篇文章中&#xff0c;我们展示了智能合约可以在铸造后控制 BSV-20 代币的转移。 今天&#xff0c;我们演示如何控制此类代币的分发/发行。 无Tick模式 BSV-20 在 V2 中引入了无Tick模式&#xff0c;并采用了与 V1 不同的方法。 部署 (Deploy) …

ENVI IDL:如何将txt文本文件转化为GeoTIFF文件?

01 前言 此处的文本文件形式如下&#xff1a; 里面包含了众多点位信息&#xff08;不是站点数据&#xff09;&#xff0c;我们需要依据上述点的经纬度信息放到对应位置的像素点位置&#xff0c;放置完后如下&#xff1a; 可以发现&#xff0c;还存在部分缺失值&#xff0c;我们…

【强化学习】18 —— SAC( Soft Actor-Critic)

文章目录 前言最大熵强化学习不同动作空间下的最大熵强化学习基于能量的模型软价值函数最大熵策略 Soft Q-learningSoft Q-IterationSoft Q-Learning近似采样与SVGD伪代码 Soft Actor-Critic伪代码代码实践连续动作空间离散动作空间 参考与推荐 前言 之前的章节提到过在线策略…

基于STC12C5A60S2系列1T 8051单片机串口通信信应用

基于STC12C5A60S2系列1T 8051单片机串口通信应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机串口通信介绍STC12C5A60S2系列1T 8051单片机串口通信的结构基于STC12C5A60S2系列1T 8051单片机串口通信的特殊功能寄存器列表基于STC12C5A60S2系列1T 8051单片…

冯·诺依曼结构

一、约翰冯诺依曼---计算机之父 约翰冯诺依曼&#xff08;John von Neumann&#xff0c;1903年12月28日—1957年2月8日&#xff09;&#xff0c;出生于匈牙利布达佩斯&#xff0c;匈牙利裔美籍数学家、计算机科学家、物理学家和化学家&#xff0c;美国国家科学院院士&#xff…

C/C++轻量级并发TCP服务器框架Zinx-游戏服务器开发004:游戏核心消息处理 - 玩家类的实现

文章目录 0 代码仓库1 需求2 AOI设计2.1 AOI算法简介2.2 AOI数据结构及实现2.2.1 玩家2.2.2 网格对象2.2.3 游戏世界矩形2.2.4 获取周围玩家的实现2.2.5 代码测试 2.3 GameRole结合AOI创建玩家2.3.1 创建游戏世界全局对象-GameRole继承AOIWorld的Player2.3.2 把玩家到游戏世界的…

C#中基于.NET6的动态编译技术

前几天要解决动态计算问题&#xff0c;尝试着使用了不同的方法。问题是给定一个包含计算的字符串&#xff0c;在程序运行中得到计算结果&#xff0c;当时考虑了动态编译&#xff0c;在网上查了一些资料完成了这项功能&#xff0c;可是基于不同的.NET平台使用的编程代码相差比较…