STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

这篇具有很好参考价值的文章主要介绍了STM32CubeIDE开发(二十六), STM32的CAN总线开发要点。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、CAN总线简介

        1.1 CAN概述

        1.2 CAN总线较其他串行通信优势

        1.3 CAN总线通信

         1.4 报文种类及格式

         1.5 CAN应用

二、CAN工程创建及配置

        2.1 工程设计及原理框图

         2.2 工程创建接配置

三、代码设计

        3.1 修改输出源文件can.c

        3.2 自定义can应用驱动

 3.3 CAN调用实现

四、编译及测试

        4.1 编译及测试

         4.2 测试


一、CAN总线简介

        1.1 CAN概述

        CAN是Controller Area Network(控制区域网络) 的缩写,是ISO国际标准化的串行通信协议。由德国电气商博世公司在1986年率先提出。此后,CAN通过ISO11898及ISO11519进行了标准化。现在在欧洲已是汽车网络的标准协议。

        CAN协议经过ISO标准化后有两个标准:ISO11898标准和ISO11519-2标准。其中ISO11898是针对通信速率为125Kbps~1Mbps的高速通信标准,总线最大长度达到40m/1Mbps,连接单元数最大支持到30;而ISO11519-2是针对通信速率为125Kbps以下的低速通信标准,总线最大长度达到1km/40kbps,连接单元数最大支持到20。

        CAN 控制器根据两根线上的电位差来判断总线电平。总线电平分为显性电平和隐性电平,二者必居其一。发 送方通过使总线电平发生变化,将消息发送给接收方。只有2个设备简单通信时,当成USART串口使用,多个设备同时通信时,遵循CAN协议,使用邮箱、识别符、过滤器功能:总线空闲时,所有单元都可发送消息,而两个以上的单元同时开始发送消息时,根据标识符(ID,非地址)决定优先级。两个以上的单元同时开始发送消息时,对各消息ID 的每个位进行逐个仲裁比较。仲裁获胜(优先级最高)的单元可继续发送消息,仲裁失利的单元则立刻停止发送而进行接收工作。

        1.2 CAN总线较其他串行通信优势

        CAN总线相比起其他串行通信协议,具有以下优势:

        【1】由于连接总线的单元,没有类似“地址”的信息,因此,在总线上添加单元时,已连接的其他单元的软硬件和应用层都不需要做改变。      

        【2】具有错误检测、错误通知和错误恢复功能:所有单元都可以检测错误(错误检测功能),检测出错误的单元会立即同时通知其他所有单元(错误通知功能),正在发送消息的单元一旦检测出错误,会强制结束当前的发送。强制结束发送的单元会不断反复地重新发送此消息直到成功发送为止(错误恢复功能)。

        【3】故障封闭功能:CAN可以判断出错误的类型是总线上暂时的数据错误(如外部噪声等)还是持续的数据错误(如单元内部故障、驱动器故障、断线等)。由此功能,当总线上发生持续数据错误时,可将引起此故障的单元从总线上隔离出去。

        【4】连接节点多。CAN 总线是可同时连接多个单元的总线。可连接的单元总数理论上是没有限制的。但实际上可连接的单元数受总线上的时间延迟及电气负载的限制。降低通信速度,可连接的单元数增加;提高通信速度,则可连接的单元数减少。

        1.3 CAN总线通信

        CAN总线是基于相同波特率通信的,所以设备接入前要知道总线上的波特率是多少。在STM32CubeMX上,其波特率计算如下图所示:波特率=(pclk1/((1+8+7)*9)) = 36Mhz/16/9 = 250Kbits。

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         在数据传输方面,一次最多只能发送8个字节的数据,这是由CAN协议规定的。多于8个的需要第二次再发送,需要开发者自己实现连续多数据发送的函数来实现大于8字节数据量的应用。

        同一条 CAN 总线的不同主机,不能同时发送相同 ID 的报文:如果使用 2 个及以上驱动器,连接在同一条 CAN 线上,必须设置为不同的编号,比如 0 组 1 号和 0 组 2 号,如果不设置为不同的编号,一旦让驱动器回传报文,报文 ID 则会相同,就会造成总线致命冲突,此时驱动器会进入硬件错误状态。

        CAN接口兼容规范2.0A和2.0B(主动式),可以接收和发送11位标识符的标准帧,也可以接收和发送29位标识符的扩展帧。具有3个发送邮箱和2个接收FIFO(邮箱及FIFO可以看做是缓存区域),3级14个可调节滤波器。

        “发送邮箱”是用于CAN总线数据发送的,总共有3个,每个邮箱只装一个报文,并且存在优先级关系。优先级越高表示其里面的数据会被优先发送。数据在发送前都会被送到优先级最高且空闲的发送邮箱,然后依次发送。如果所有邮箱都满了,会溢出标记为1,需要等待空邮箱。满邮箱按先后次序排队发送报文,发送完成后变成空邮箱。

        FIFO:表面的意思是“先入先出”,是指有层级深度的接收邮箱。一般CAN有2个FIFO邮箱(FIFO0和FIFO1),每个FIFO有3层深度,3层深度是指每个邮箱可以接收3个报文,但读取时只能读到最先收到的报文报文处理完成后,再读取时则是下一个报文。

        过滤器:可由硬件判断报文中的标识符,过滤掉标识符不匹配的报文(过滤掉不想要的ID,接收想要的ID)。CAN总线控制器通常提供了14个或28个过滤器组,每组2个32为寄存器。过滤器是由硬件实现的,只有与过滤器匹配的报文才需要软件处理。在接收报文时,数据先进入过滤器,与过滤器匹配的报文会被放入FIFO邮箱。过滤器根据下列优先级规则来确定:
        1,位宽为32位的过滤器,优先级高于位宽为16位的过滤器
        2,对于位宽相同的过滤器,标识符列表模式的优先级高于屏蔽位模式
        3,位宽和模式都相同的过滤器,优先级由过滤器号决定,过滤器号小的优先级高

        最终CAN总线通信如下图示意:

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         1.4 报文种类及格式

        CAN报文包含以下几种,其中数据帧及遥控帧是重点常用格式:

        【1】数据帧,用于发送单元向接收单元传送数据的帧。

        【2】遥控帧或远程帧,用于接收单元向具有相同ID的发送单元请求数据的帧。    

        【3】错误帧,用于当检测出错误时向其它单元通知错误的帧。

        【4】过载帧,用于接收单元通知其尚未做好接收准备的帧。

        【5】帧间隔,用于将数据帧及遥控帧与前面的帧分离开来的帧。

        每种类型的报文格式都不相同,数据帧和遥控帧格式如下:

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点        数据帧和遥控帧有标准格式和扩展格式两种格式,类似于I2C协议里的7位和10位地址。CAN的数据帧和遥控帧的标识符(ID)的标准格式有11个位标识符,扩展格式有29个位标识符。设备可以用标识符(ID)判断数据是不是发给自己的。

        CAN总线收发数据报文,根据标示符(也就是 ID)来决定优先级的。必须注意的是,在同一CAN网络中,所有单元必须设定成统一的通信速度,CAN设备可通过发送“遥控帧” 请求其他单元发送数据。CAN支持Normal 正常模式、Silent 静默模式、Loopback 环回模式测试、Silent_loopback 静默换回模式测试共四种模式,在CubeMX对应如下:

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         1.5 CAN应用

        CAN具有很高的可靠性,广泛应用于:汽车电子、工业自动化、船舶、医疗设备、工业设备等方面。

二、CAN工程创建及配置

        2.1 工程设计及原理框图

        本文采用STM32L496VGTX+独立CAN 收发器(TJA1050)和STM32F103C8Tx开发板(已经集成了CAN 收发器-TJA1050)进行CAN通信。

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

        STM32L496VGTX预留了扩展引脚PD0、PD1支持CAN1,然后通过扩展引脚接入TJA1050:

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         TJA1050原理框图,STM32L496VGTX扩展口PD0、PD1接下图的PA11、PA12。

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         STM32F103C8Tx开发板的CAN组件原理框图如下,PB8、PB9接MCU:

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         2.2 工程创建接配置

        现以STM32L496VGTX为例创建CAN工程stm32L496VGT6_can,创建完成后,移植以前已经实现过的lpuart1通信功能、按键功能及LED灯功能,请参考:

cubeIDE开发, stm32调试信息串口通信输出显示_py_free的博客-CSDN博客_stm32串口显示

        假设已经移植了串口调试功能并能在电脑上通过串口通信实现调试信息输出。

        进入CAN配置阶段,双击.ioc打开CubeMX配置界面,设置CAN1功能开启,先在图形配置界面选择PD0、PD1为CAN_RX/TX模式,将自动开启CAN1功能,然后进入CAN页面配置参数,波特率设置为250Kbits,及本次CAN网络的统一波特率。

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         开启接收中断功能

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         完成后点击保存输出生成代码

三、代码设计

        3.1 修改输出源文件can.c

        在Core/src目录下,双击打开can.c文件,修改MX_CAN1_Init函数,增加过滤设置、CAN开启、中断支持设置等功能。

/* USER CODE BEGIN 0 */
//新增
#define CAN1_ID_H      0x0000 //32位基础ID设置(高16位)
#define CAN1_ID_L      0x0000 //32位基础ID设置(低16位)
#define CAN1_MASK_H    0x0000 //32位屏蔽MASK设置(高16位)
#define CAN1_MASK_L    0x0000 //32位屏蔽MASK设置(低16位)
/* USER CODE END 0 */

CAN_HandleTypeDef hcan1;

/* CAN1 init function */
void MX_CAN1_Init(void)
{

  /* USER CODE BEGIN CAN1_Init 0 */
    //新增
	CAN_FilterTypeDef  CAN1_sFilterConfig;
	HAL_StatusTypeDef  HAL_Status;
  /* USER CODE END CAN1_Init 0 */

  /* USER CODE BEGIN CAN1_Init 1 */

  /* USER CODE END CAN1_Init 1 */
  hcan1.Instance = CAN1;
  hcan1.Init.Prescaler = 20;
  hcan1.Init.Mode = CAN_MODE_NORMAL;
  hcan1.Init.SyncJumpWidth = CAN_SJW_1TQ;
  hcan1.Init.TimeSeg1 = CAN_BS1_8TQ;
  hcan1.Init.TimeSeg2 = CAN_BS2_7TQ;
  hcan1.Init.TimeTriggeredMode = DISABLE;
  hcan1.Init.AutoBusOff = DISABLE;
  hcan1.Init.AutoWakeUp = DISABLE;
  hcan1.Init.AutoRetransmission = DISABLE;
  hcan1.Init.ReceiveFifoLocked = DISABLE;
  hcan1.Init.TransmitFifoPriority = DISABLE;
  if (HAL_CAN_Init(&hcan1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN CAN1_Init 2 */
    //新增
  CAN1_sFilterConfig.FilterIdHigh = CAN1_ID_H;//32位基础ID设置(高16位)
  CAN1_sFilterConfig.FilterIdLow = CAN1_ID_L;//32位基础ID设置(低16位)
  CAN1_sFilterConfig.FilterMaskIdHigh = CAN1_MASK_H;//32位屏蔽MASK设置(高16位)
  CAN1_sFilterConfig.FilterMaskIdLow = CAN1_MASK_L;//32位屏蔽MASK设置(低16位)
  CAN1_sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO1;//接收到的报文放入FIFO1位置
  CAN1_sFilterConfig.FilterBank = 0;//过滤器0
  CAN1_sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;//设为IDLIST列表模式/IDMASK屏蔽模式
  CAN1_sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;//过滤器位宽度
  CAN1_sFilterConfig.FilterActivation = ENABLE;//ENABLE激活过滤器,DISABLE禁止过滤器
  CAN1_sFilterConfig.SlaveStartFilterBank = 0;//过滤器组设置(单个CAN总线时无用)
  HAL_Status = HAL_CAN_ConfigFilter(&hcan1, &CAN1_sFilterConfig);
  if ( HAL_Status!= HAL_OK)//判断开启是否成功
   {
     /* Filter configuration Error */
     Error_Handler();//开启CAN总线失败的处理程序
   }

   /* Start the CAN peripheral */
  HAL_Status = HAL_CAN_Start(&hcan1);
   if ( HAL_Status!= HAL_OK)//这个函数和下面的函数是cubemx没有给出的,需要手动添加
   {
     /* Start Error */
     Error_Handler();//开启CAN总线失败的处理程序
   }

   /* Activate CAN RX notification */
   //若不使用CAN中断,以下不需要
   HAL_Status = HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO1_MSG_PENDING);
   if ( HAL_Status!= HAL_OK)//选择fifo1中断
   {
     /* Notification Error */
     Error_Handler();//开启CAN总线挂起中断失败的处理程序
   }

  /* USER CODE END CAN1_Init 2 */

}

        3.2 自定义can应用驱动

         在ICore目录创建文件夹can,并在该文件夹下创建can1.h和can1.c源文件。

        can1.h

#ifndef CAN_CAN1_H_
#define CAN_CAN1_H_

#include "stm32l4xx_hal.h" //HAL库文件声明

extern CAN_HandleTypeDef hcan;//声明的HAL库结构体

#define CAN1_REC_LEN  256//定义CAN1最大接收字节数

extern uint8_t  CAN1_RX_BUF[CAN1_REC_LEN];//接收缓冲,末字节为换行符
extern uint16_t CAN1_RX_STA;//接收状态标记

uint8_t  CAN1_SendNormalData(CAN_HandleTypeDef*  hcan,uint16_t ID,uint8_t *pData,uint16_t  Len);//CAN发送函数
void CAN1_printf (char *fmt, ...);//CAN总线通信,使用CAN1,这是CAN专用的printf函数

#endif /* CAN_CAN1_H_ */

        can1.c,该驱动通过CAN1_printf函数实现向CAN发送数据,通过重写stm32l4xx_hal_can.h/c文件中的HAL_CAN_RxFifo1MsgPendingCallback函数实现CAN数据接收。

#include "can1.h" //库文件声明
#include "main.h"
#include <string.h>//用于字符串处理的库
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>

CAN_HandleTypeDef hcan;//声明的HAL库结构体

CAN_TxHeaderTypeDef     TxMeg;//CAN发送设置相关结构体
CAN_RxHeaderTypeDef     RxMeg;//CAN接收设置相关结构体

uint8_t CAN1_RX_BUF[CAN1_REC_LEN];//接收缓冲,最大CAN1_REC_LEN个字节.末字节为换行符
uint16_t CAN1_RX_STA;//接收状态标记

void  HAL_CAN_RxFifo1MsgPendingCallback(CAN_HandleTypeDef *hcan)  //接收回调函数(函数名不可改)
{
    uint8_t  Data[8];//接收缓存数组
    HAL_StatusTypeDef HAL_RetVal;//判断状态的枚举
	HAL_RetVal=HAL_CAN_GetRxMessage(hcan,CAN_RX_FIFO1,&RxMeg,Data);//接收邮箱中的数据
	if (HAL_OK==HAL_RetVal){//判断接收是否成功
		//接收成功后的数据处理程序,写在此处。(数据在Data数组中)
		//以下2行是采用简单的寄存器查寻方式处理接收数据,每次只接收1位。在实际项目中的复杂接收程序可自行编写。
		CAN1_RX_BUF[0]=Data[0];//将接收到的数据放入缓存数组(因只用到1个数据,所以只存放在数据[0]位置)
		CAN1_RX_STA++;//数据接收标志位加1
	}
}
//CAN发送数据函数(参数:总线名,ID,数据数组,数量。返回值:0成功HAL_OK,1参数错误HAL_ERROR,2发送失败HAL_BUSY)
//示例:CAN1_SendNormalData(&hcan1,0,CAN_buffer,8);//CAN发送数据函数
uint8_t  CAN1_SendNormalData(CAN_HandleTypeDef* hcan,uint16_t ID,uint8_t *pData,uint16_t  Len)
{
    HAL_StatusTypeDef HAL_RetVal;//判断状态的枚举
    uint16_t SendTimes,SendCNT=0;
    uint8_t  FreeTxNum=0;
    uint8_t  FreeLevelCount=0;
    uint32_t CAN_TX_BOX0;
    TxMeg.StdId=ID;
    TxMeg.IDE = CAN_ID_STD;//扩展帧标识(STD标准帧/EXT扩展帧)
    TxMeg.RTR = CAN_RTR_DATA;//远程帧标识(DATA数据帧/REMOTE远程帧)
    if(!hcan||!pData||!Len){
    	printf("\n\rCAN发送失败!\n\r"); //串口发送
    	return  HAL_ERROR;//如果总线名、数据、数量任何一个为0则返回值为1
    }
    SendTimes=Len/8+(Len%8?1:0);
    FreeTxNum=HAL_CAN_GetTxMailboxesFreeLevel(hcan);//得出空闲邮箱的数量
    TxMeg.DLC=8;
    while(SendTimes--){//循环判断分批发送是否结束
       if(0==SendTimes){//如果分批发送结束
           if(Len%8)TxMeg.DLC=Len%8;//则加入最后不足8个的数据内容
       }
       FreeLevelCount = 0;//防止死循环
       while(0 == FreeTxNum&&FreeLevelCount<10){
    	   	FreeLevelCount++;
    	   	HAL_Delay(1);
            FreeTxNum = HAL_CAN_GetTxMailboxesFreeLevel(hcan);
        }
       HAL_Delay(1);//延时防止速度过快导致的发送失败
       //开始发送数据(参数:总线名,设置参数,数据,邮箱号)
       HAL_RetVal=HAL_CAN_AddTxMessage(hcan,&TxMeg,pData+SendCNT,&CAN_TX_BOX0);
       if(HAL_RetVal!=HAL_OK){
    		   printf("\n\rCAN总线忙碌!\n\r"); //串口发送
    		   return  HAL_BUSY;//如果发送失败,则返回值为2
       }
       SendCNT+=8;
    }
    return HAL_OK;//如果发送成功结束,返回值为0
}
//CAN总线通信,使用CAN1,这是CAN专用的printf函数
//调用方法:CAN1_printf("123"); //向UART8发送字符123
void CAN1_printf (char *fmt, ...)
{
    char buff[CAN1_REC_LEN+1];  //用于存放转换后的数据 [长度]
    uint16_t i=0;
    va_list arg_ptr;
    va_start(arg_ptr, fmt);
    vsnprintf(buff, CAN1_REC_LEN+1, fmt,  arg_ptr);//数据转换
    i=strlen(buff);//得出数据长度
    if(strlen(buff)>CAN1_REC_LEN)i=CAN1_REC_LEN;//如果长度大于最大值,则长度等于最大值(多出部分忽略)
    CAN1_SendNormalData(&hcan,0x11,(uint8_t *)buff,i);//CAN发送数据函数(ID为0x11)
    va_end(arg_ptr);
}

 3.3 CAN调用实现

        在main.c文件中,加入各驱动文件的头文件引用

/* USER CODE BEGIN Includes */
#include "../../ICore/key/key.h"
#include "../../ICore/led/led.h"
#include "../../ICore/print/print.h"
#include "../../ICore/usart/usart.h"
#include "../../ICore/can/can1.h"
/* USER CODE END Includes */

         在main函数中,加入各驱动的初始化化实现,CAN的初始化以及生产代码自动调用

  /* USER CODE BEGIN 2 */
  ResetPrintInit(&hlpuart1);
  HAL_UART_Receive_IT(&hlpuart1,(uint8_t *)&HLPUSART_NewData, 1); //再开启接收中断
  HLPUSART_RX_STA = 0;
  /* USER CODE END 2 */

        在main函数循环体中,实现CAN调用

  /* USER CODE BEGIN WHILE */
  while (1)
  {
	  if(HLPUSART_RX_STA&0xC000){//溢出或换行,重新开始
		  printf("%.*s\r\n",HLPUSART_RX_STA&0X0FFF, HLPUSART_RX_BUF);
		  HLPUSART_RX_STA=0;//接收错误,重新开始
		  HAL_Delay(100);//等待
	  }
	  if(CAN1_RX_STA!=0)//CAN判断中断接收标志位【处理从CAN外部设备接收的字符】
      {
    	  //CAN1_printf("%c",CAN1_RX_BUF[0]); //CAN总线发送
    	  printf("CAN1 Receive:%c",CAN1_RX_BUF[0]); //lpuart1总线发送
    	  CAN1_RX_STA=0;//清除标志位
      }
	  if(KEY_1())//按下KEY1判断
	  {
		  CAN1_printf("A");//向CAN1发送字符A
	  }
	  if(KEY_2())//按下KEY2判断
	  {
		  CAN1_printf("B");//向CAN1发送字符B
	  }
    /* USER CODE END WHILE */

四、编译及测试

        4.1 编译及测试

         编译工程,STM32L496VGx支持ST-Link,直接在CubeIDE配置运行及下载程序。

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         同样方法基于STM32F103C8Tx芯片创建工程、配置CAN及代码编译,其CAN配置如下

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         完成工程编译后,加载测试

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点

         4.2 测试

        打开串口工具,连接STM32L496芯片的工程lpuart1串口,在STM32F103C8Tx开发板上按键KEY1、KEY2,查看串口输出情况。

STM32CubeIDE开发(二十六), STM32的CAN总线开发要点文章来源地址https://www.toymoban.com/news/detail-414359.html

到了这里,关于STM32CubeIDE开发(二十六), STM32的CAN总线开发要点的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • STM32 基础知识(探索者开发板)--159讲 CAN总线

    CAN基础知识:ISO国际标准化的串行通信协议,为了减少线束的数量 a.多主控制  每个设备都可以主动发送数据 b.通信速度较快,通信距离远。最高1Mbps(距离小于40M),最远可达10KM(速率低于5Kbps) c.具有错误检测、错误通知和错误恢复功能 d.故障封闭功能  能发现故障,且可以把故

    2024年01月17日
    浏览(46)
  • CAN总线详解及STM32的CAN通信编程指南

    对于CAN通信而言,本人之前也未接触了解过,由于实习的技术要求,因此也花费了一段时间对CAN通信进行学习,并且实现了基于STM32的CAN环回静默模式通信,因此写一遍比较详细的文章对该内容进行总结。本文的参考资料有STM32的中文参考手册、协议手册等。话不多说开始吧!

    2024年02月11日
    浏览(40)
  • STM32 CAN总线过滤器设置

                                                                                                         CAN过滤器配置以及常见问题总结 过滤器组 在具有两个CAN的产品中,CAN1和CAN2分享28个过滤器组,只有一个CAN的系列产品中有14个过滤器组,用以对接收到的帧进行过

    2024年01月17日
    浏览(41)
  • STM32的CAN总线调试经验分享

    CAN总线简易入门教程 CAN总线显性电平和隐性电平详解 STM32的CAN总线调试经验分享 最近负责的一个项目用的主控芯片是 STM32F407IGT6 ,需要和几个电机控制器进行通讯,有很多参数需要进行监控。负责固件开发的同事一直搞不定一个问题。就是开启 CAN 的接收中断,接收不到数据

    2024年01月20日
    浏览(41)
  • CAN总线基础详解以及stm32的CAN控制器

    目录 CAN简介 CAN总线拓扑图 CAN总线特定 CAN应用场景 CAN的物理层 CAN的协议层 CAN数据帧介绍 CAN位时序介绍 数据同步过程 硬件同步 再同步 CAN总线仲裁 stm32的CAN控制器 CAN控制器介绍 CAN控制器模式 CAN控制器框图 接收过滤器 CAN控制器波特率计算 CAN相关寄存器 CAN主控制寄存器(

    2024年01月25日
    浏览(45)
  • CAN总线学习笔记 | STM32CubeMX配置CAN环回测试

    CAN基础知识介绍文中介绍了CAN协议的基础知识,以及STM32F4芯片的CAN控制器相关知识,下面将通过实例,利用STM32CubeMX图形化配置工具,来实现CAN通讯的环回测试 CAN是挂载在APB1总线上,设置PCLK1时钟频率到最大45MHz 激活CAN1,配置位时序参数,其他基本参数以及工作模式(此处

    2024年02月11日
    浏览(35)
  • STM32+收发器实现CAN和485总线

    RS485总线是一种常见的(Recommended Standard)串行总线标准(485是它的标识号),采用平衡发送与差分接收的方式,因此具有抑制共模干扰的能力。CAN是控制器局域网络(Controller Area Network, CAN)的简称,是一种能够实现分布式实时控制的串行通信网络,属于CSMA(多路载波侦听)/CD(冲突检测

    2024年02月05日
    浏览(49)
  • STM32基于CAN总线协议控制步进电机

    如上图所示,实现了以下功能: 1.两块stm32单片机通过CAN控制器与收发器进行半双工通信; 2.stm32主机通过检测按键,切换不同的模式,将不同模式的case值发送给stm32从机; 3.stm32从机根据收到的case值,控制步进电机进行不同的运动操作; 4.OLED用于显示收发内容与按键状态等

    2024年01月19日
    浏览(47)
  • CAN总线(五)STM32的CAN波特率设置方法(完整版)

     ①HSI是高速内部时钟,RC振荡器,频率为8MHz。   ②HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为4MHz~16MHz。 ③LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 ⑤PLL为锁相环倍频输出,其时钟输入

    2024年02月07日
    浏览(29)
  • stm32专题二十六:高级定时器介绍

    高级定时器 STM32F103有 2 个高级定时器 TIM1 和 TIM8,高级定时器的功能主要有定时、输入捕获、输出比较、互补输出等。 高级定时器简介: 计数器16bit,上 / 下 / 两边 计数,TIM1和TIM8,还有一个重复计数器RCR,独有; 有4个GPIO,其中通道1 ~ 3还有互补输出GPIO; 时钟来自PCLK2,为

    2024年02月20日
    浏览(74)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包