STM32的HAL库开发系列 - CAN通信实例

这篇具有很好参考价值的文章主要介绍了STM32的HAL库开发系列 - CAN通信实例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

CAN通信是一种高效、可靠、灵活的数据传输方式,适用于各种应用场景,在工业自动化、汽车电子、医疗设备等领域有着广泛的应用。

但理解CAN通信的实际应用,也不能全部只看软件方面,还需要对硬件上也有了解。

在硬件上,CAN通信使用两条线路:一条是数据线(CAN_H),另一条是地线(CAN_L)。数据线和地线之间的电压差表示了数据的“1”或“0”。数据传输采用非连续总线唤醒(Non-Continuous Dominant State)的方式,这意味着,当有节点需要发送数据时,它会把总线电压拉高,表示“1”,其他节点就会停止发送,并等待数据传输完成。这种方式能够有效地避免数据冲突,保证了数据的可靠性。

使用CAN通信的设备需要实现CAN控制器,它负责控制总线的电压,并检测和处理总线上的数据。在软件层面,需要使用CAN驱动程序来实现对CAN控制器的控制。

以下这段代码就是实际应用的举例。

/**
  * @brief			HAL库CAN FIFO0接受邮箱中断(Rx0)回调函数
  * @param			hcan : CAN句柄指针
  */
void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
	static BaseType_t xHigherPriorityTaskWoken = pdFALSE;	// 不请求上下文切换
	CAN_RxHeaderTypeDef RxHeader;							// CAN通信协议头
	uint8_t rx_data[8] = {0};								// 暂存CAN接收数据
	motor_measure_t motorDataTmp;							// 电机数据
	uint8_t i = 0;
	
//	if (hcan == &hcan1)
	if (hcan->Instance == CAN1)
	{
		if (HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, rx_data) == HAL_OK)	// 接收CAN总线上发送来的数据
		{
			// 对应电机向总线上发送的反馈的标识符和程序电机序号
			switch (RxHeader.StdId) {
				case CAN_2006_M_ID : i = MotorID_ShootM; break;
				case CAN_PITCH_MOTOR_ID : i = MotorID_GimbalPitch; break;
				case CAN_YAW_MOTOR_ID : i = MotorID_GimbalYaw; break;
				#if DEBUGMODE
				default : i = RxHeader.StdId - CAN_3508_M1_ID; break;
				#else
				default : break;
				#endif
			}

			// 电机返回数据协议解析
			get_motor_measure(&motorDataTmp, rx_data);
			#if DEBUGMODE
				get_motor_measure(&motorData[i], rx_data);
			#endif

			// 向消息队列中填充数据
			if (messageQueueCreateFlag) {
				xQueueOverwriteFromISR(messageQueue[i], (void *)&motorDataTmp, &xHigherPriorityTaskWoken);
				portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
			}
		}
	}
}

对于CAN发送,相应的实例如下:

/**
  * @brief          发送C620电调控制电流
  * @param[in]		motorID对应的电机控制电流, 范围 [-16384, 16384],对应电调输出的转矩电流范围 [-20A, 20A]
  * @param[in]      etcID: 控制报文标识符(电调ID)为1-4还是5-8
  */
void CAN_Cmd_C620(CAN_HandleTypeDef *hcan, int16_t motor1, int16_t motor2, int16_t motor3, int16_t motor4, bool_t etcID)
{
	CAN_TxHeaderTypeDef TxHeader;						// CAN通信协议头
	uint8_t TxData[8] = {0};							// 发送电机指令缓存
	uint32_t TxMailboxX = CAN_TX_MAILBOX0;				// CAN发送邮箱

	if (etcID == false) {
		TxHeader.StdId = CAN_3508_ALL_ID;				// 标准格式标识符ID
	} else {
		TxHeader.StdId = CAN_3508_ETC_ID;
	}
	TxHeader.ExtId = 0;
	TxHeader.IDE = CAN_ID_STD;							// 标准帧
	TxHeader.RTR = CAN_RTR_DATA;						// 传送帧类型为数据帧
	TxHeader.DLC = 0x08;								// 数据长度码
	TxData[0] = (uint8_t)(motor1 >> 8);
	TxData[1] = (uint8_t)motor1;
	TxData[2] = (uint8_t)(motor2 >> 8);
	TxData[3] = (uint8_t)motor2;
	TxData[4] = (uint8_t)(motor3 >> 8);
	TxData[5] = (uint8_t)motor3;
	TxData[6] = (uint8_t)(motor4 >> 8);
	TxData[7] = (uint8_t)motor4;

	//找到空的发送邮箱
	while (HAL_CAN_GetTxMailboxesFreeLevel(hcan) == 0);	// 如果三个发送邮箱都阻塞了就等待直到其中某个邮箱空闲
	if ((hcan->Instance->TSR & CAN_TSR_TME0) != RESET) {
		// 检查发送邮箱0状态 如果邮箱0空闲就将待发送数据放入FIFO0
		TxMailboxX = CAN_TX_MAILBOX0;
	} else if ((hcan->Instance->TSR & CAN_TSR_TME1) != RESET) {
		TxMailboxX = CAN_TX_MAILBOX1;
	} else if ((hcan->Instance->TSR & CAN_TSR_TME2) != RESET) {
		TxMailboxX = CAN_TX_MAILBOX2;
	}
	// 将数据通过CAN总线发送
	#if DEBUGMODE
		if (HAL_CAN_AddTxMessage(hcan, &TxHeader, TxData, (uint32_t *)TxMailboxX) != HAL_OK) {
			Error_Handler();							// 如果CAN信息发送失败则进入死循环
		}
	#else
		HAL_CAN_AddTxMessage(hcan, &TxHeader, TxData, (uint32_t *)TxMailboxX);
	#endif
}

另外,CAN通信还具有较高的安全性。例如,它使用了校验和机制来检测数据传输中的错误,并使用了访问控制机制来限制对总线的访问。

在实际应用中,CAN通信还有许多标准,如:

CAN 2.0A: 这是最早的标准,支持11位帧ID和8字节数据。
CAN 2.0B: 与2.0A相比,它增加了29位帧ID和支持高速模式。
CAN FD (Flexible Data-rate) : 这是最新的标准,支持高达64字节的数据帧和更高的通信速率。

同时,由于其在工业、汽车等领域的广泛应用,也有许多标准化组织和协会为其制定了专门的应用标准,如:

J1939: 这是专门为汽车应用设计的标准,它定义了许多特定的应用层协议。
DeviceNet: 这是专门为工业自动化应用设计的标准,它定义了许多特定的应用层协议。

总之,CAN通信是一种高效、可靠、灵活的数据传输方式,适用于各种应用场景,并有许多标准和协议来支持其在不同领域的应用,是一种非常重要的通信技术。文章来源地址https://www.toymoban.com/news/detail-660733.html

到了这里,关于STM32的HAL库开发系列 - CAN通信实例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 CAN/CANFD软件快速配置(HAL库版本)

    控制器局域网总线(CAN,Controller Area Network)是一种用于实时应用的串行通讯协议总线,它可以使用双绞线来传输信号,是世界上应用最广泛的现场总线之一。CAN协议用于汽车中各种不同元件之间的通信,以此取代昂贵而笨重的配电线束。该协议的健壮性使其用途延伸到其他

    2024年02月09日
    浏览(38)
  • STM32的CAN通信的收发库函数解读

    STM32的CAN通信的收发函数: CAN发送消息结构体定义:        当需要使用CAN发送报文时,先定义一个上面发送类型的结构体,然后把报文的内容按成员赋值到该结构体中,最后调用库函数CAN_Transmit把这些内容写入到发送邮箱即可把报文发送出去。  CAN接收消息结构体定义:

    2024年02月07日
    浏览(37)
  • GD32F30x系列---CAN通信收发配置

    GD32F30x系列CAN通信配置: 先找到CAN模块时钟时挂载在APB1总线上的,如下图所示: APB1总线的最大频率为60MHz,如下图所示: 根据总线频率可以计算出对应波特率的配置BS1,BS2等; 如果不会计算的话也可以直接使用工具,如下图所示: 这里工具会直接帮你你计算好BS1、BS2、P

    2024年01月19日
    浏览(96)
  • 【STM32】标准库与HAL库对照学习教程十四--CAN总线

    STM32全部教程 :【STM32】标准库与HAL库对照学习系列教程大全 本篇介绍如何使用STM32的标准库与HAL库对CAN总线的使用,由于我那块普中的STM32F103ZET6开发板送人了,因此我这边用STM32F103C8最小系统板,进行简单的演示一下功能,最主要的还是需要理解CAN总线的原理,在本篇中,

    2024年02月15日
    浏览(41)
  • STM32F407单片机HAL库CAN2不能接收数据解决方法

      最近在使用stm32F407的片子调试can通信,直接在正点原子的代码上修改调试,调试can1的时候,基本没啥问题,收发都正常,使用查询模式和中断模式都可以。但是当修改到can2的时候,可以正常发送数据,但是中断函数始终进不去。折腾了一两个小时终于搞定了。下面将解

    2024年02月16日
    浏览(43)
  • 入门stm32:STM32hal库实现ESP8266与手机通信(不定长数据收发和ESP8266使用的一些问题)

    目录 前言 一、stm32cubeMX的串口配置 二、空闲中断+dma接收 三、ESP8266.c和ESP8266.h ESP8266.h ESP8266.c 注意事项 四、与手机通信例程 步骤:  例程代码main.c 运行结果 五、相关问题 总结 相关的app和源码         前提: 1.掌握串口通信和ESP8266的使用方法 串口通信:单片机串口通信

    2024年02月04日
    浏览(84)
  • 入门小白:STM32hal库实现ESP8266与手机通信(不定长数据收发和ESP8266使用的一些问题)

    目录 前言 一、stm32cubeMX的串口配置 二、空闲中断+dma接收 三、ESP8266.c和ESP8266.h ESP8266.h ESP8266.c 注意事项 四、与手机通信例程 步骤:  例程代码main.c 运行结果 五、相关问题 总结 相关的app和源码         前提: 1.掌握串口通信和ESP8266的使用方法 串口通信:单片机串口通信

    2024年02月07日
    浏览(60)
  • 野火STM32电机系列(三)Cubemx配置CAN通信

    CAN接口: PI9 PB9 1.配置CAN 通信参数 由于F4的 CAN外设挂载在APB1上,时钟配置后APB1的时钟速率为42MHz,目标通信速率为1000KHz,由公式: BaudRate = 1/NominalBitTime NominalBitTime = 1tq + tBS1 +tBS2 设置参数如下: CAN时钟分频参数为7,BS1为4,BS2为1,CAN模式为Nomal模式。 生成工程 在can.c中添加

    2024年02月11日
    浏览(44)
  • 【STM32通讯系列--串口通讯】使用标准库、HAL库实现任意长度数据的收发(包含帧头、帧尾校验,配套完整开源程序)

    【数据组成】串口的通讯协议由开始位,数据位,校验位,结束位构成。 【数据结构】一般以一个低电平作为一帧数据的起始,接着跟随 8 位或者 9 位数据位,之后为校验位,分为奇校验,偶校验和无校验,最后以一个先高后低的脉冲表示结束位,长度可以设置为 0.5,1,

    2024年02月14日
    浏览(42)
  • HAL库STM32的串口收发教程

            首先配置STM32CubeMX 第一步在系统SYS里的Debug(调试)选项选择Serial Wire(这里使用ST-LINK-V2仿真下载器所以选择该项)。  第二打开使用外部晶振  在芯片引脚上点击PC13选择GPIO_Output(即设置GPIO为输出模式) 点击GPIO,点击PC13 在其下方配置引脚: GPIO out  level 设置成

    2024年02月14日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包