STM32基于CAN总线协议控制步进电机

这篇具有很好参考价值的文章主要介绍了STM32基于CAN总线协议控制步进电机。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、功能描述:

STM32基于CAN总线协议控制步进电机,stm32,嵌入式硬件,单片机

如上图所示,实现了以下功能:

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

二、CAN总线概述

1.CAN总线协议

        CAN总线(Controller Area Network)是一种串行通信协议,最初是由德国Bosch公司在1983年为汽车应用而开发的。然而,由于其高效、可靠的性能,CAN总线已经被广泛用于各种领域,包括工业控制、医疗设备、军事应用等。(来源:ChatGPT)

以下是CAN总线的一些关键特点和特性:

  1. 串行通信: CAN总线使用串行通信,通过两根导线进行数据传输,即CAN_H和CAN_L。这种方式有助于减小线缆数量,降低成本,同时提高系统的可靠性。

  2. 实时性: CAN总线的设计目标之一是提供高实时性,适用于需要及时响应和同步的应用。这使得它特别适用于汽车电子系统等需要高度协同工作的场景。

  3. 多主机网络: CAN总线支持多主机网络,允许多个节点同时发送和接收数据。这使得多个电子控制单元(ECU)能够并行工作,促进系统的分布式控制。

  4. 抗干扰性: CAN总线具有很强的抗干扰能力。它采用不同的电压水平来表示0和1,这使得CAN总线对电磁干扰具有一定的容忍性。

  5. 错误检测和冗余: CAN总线使用CRC(循环冗余校验)来检测传输中的错误,并能够在数据帧中添加冗余位,以提高错误检测和纠正的能力。

  6. 消息优先级: CAN总线使用标识符来给消息分配优先级。低标识符的消息拥有更高的优先级,这有助于确保紧急消息能够在较短的时间内被传输。

  7. 灵活性: CAN总线的协议允许节点通过标识符来识别和筛选消息,从而实现更灵活的通信结构。

        总体而言,CAN总线是一种可靠、高效的通信协议,特别适用于需要实时性和多节点通信的应用场景。在汽车领域,它被广泛用于车辆内部的电子控制系统,如发动机控制单元(ECU)、制动系统、空调系统等。

2.CAN总线网络

STM32基于CAN总线协议控制步进电机,stm32,嵌入式硬件,单片机

        CAN总线⽹络主要挂在CAN_HCAN_L,各个节点通过这两条线实现信号的串⾏差分传输,为了避免信号的反射和⼲扰,还需要在CAN_H和CAN_L之间接上120欧姆的终端电阻。为什么是120Ω,因为电缆的特性阻抗为120Ω,为了模拟⽆限远的传输线。

3.CAN总线信号

        CAN总线采⽤不归零码位填充技术,信号有两种不同状态,分别为隐形电平和显性电平。CAN的数据总线有两条CAN_H和CAN_L,当没有数据发送时,两条线的电平⼀样都为2.5V,称为静电平,也就是隐性电平。当有信号发送时,CAN_H的电平升⾼1V,即3.5V,CAN_L的电平降低1V即1.5V,此时为显性电平。信号每⼀次传输完后不需要返回到显性电平。

定义 总线电平 逻辑电平
CAN_H-CAN_L<0.5V 隐性电平 1
CAN_H-CAN_L>0.9V 显性电平 0

4.CAN总线工作原理

        ①CAN总线没有主从节点之分,所有CAN总线上的节点都是地位等价的。当CAN总线上的⼀个节点发送数据时,它以报⽂的形式⼴播给⽹络中的⽽所有节点;这样对于每个节点来说,⽆论数据是否发给⾃⼰,都对其进⾏接收。
        ②CAN总线每组报⽂开头的11位字符为标识符,定义了报⽂的优先级;在同⼀个总线中,标识符是唯⼀的,不可能有两个节点发送具有相同标识符的报⽂。当然接收节点也会根据标识符来判断是否接收这帧信息,⼀般称这项技术为报⽂滤波技术。
        ③CAN总线接收节点可以通过远程数据请求发送远程帧请求发送节点发送相应的数据,回应节点传送的数据帧与请求数据的远程帧具有相同的标识符。(接收校对标识符)
        ④CAN总线的优先权由发送数据报⽂中的标识符决定报⽂占⽤总线的优先权;标识符越⼩,优先权越⾼。
        ⑤CAN总线的仲裁机制:只要总线空闲,任何节点都可以向总线发送报⽂。如果有两个或两个以上的节点同时发送报⽂,就会引起总线访问碰撞。通过使⽤标识符逐位仲裁可以解决这个碰撞问题。⽽且当具有相同标识符的数据帧和远程帧同时发送时,数据帧优先于远程帧。
        ⑥⽬前CAN总线通信协议仅仅包括OSI七层互联参考模型中的数据链路层和物理层

三、代码实操

1.配置CAN总线:

        ①初始化GPIO两个收发引脚(stm32f103c8t6只有一个CAN1控制器,固定引脚

        ②初始化NVIC中断向量表优先级

        ③初始化CAN相关参数配置

        ④初始化CAN过滤器(筛选器)

void CAN_init() {
	
	GPIO_InitTypeDef GPIO_InitStructure;
	NVIC_InitTypeDef NVIC_InitStructure;
	CAN_InitTypeDef CAN_InitStructure;
	CAN_FilterInitTypeDef CAN_FilterInitStruct;
	 
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO|RCC_APB2Periph_GPIOB, ENABLE);	//使能时钟
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1, ENABLE); 
/**********************************GPIO****************************************************************/
	//CAN_TX   
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PB9
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	       //复用推挽输出,TX
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化PB9
  //CAN_RX	  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;//PB8
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;        //复用推挽输出,RX
  GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化PB8  
	

  GPIO_PinRemapConfig(GPIO_Remap1_CAN1, ENABLE);
	
/***********************************CAN工作模式初始化****************************************************/
	
	CAN_DeInit(CAN1);
	CAN_StructInit(&CAN_InitStructure);
	
	//时间触发模式
	CAN_InitStructure.CAN_TTCM = DISABLE;
	//自动离线管理
	CAN_InitStructure.CAN_ABOM = ENABLE;
	//自动唤醒模式
	CAN_InitStructure.CAN_AWUM = ENABLE;
	//报文自动重传 (0为启用)
	CAN_InitStructure.CAN_NART = DISABLE;
	//FIFO溢出时报文覆盖原文件
	CAN_InitStructure.CAN_RFLM = DISABLE;
	//报文发送优先级取决于邮箱先后
	CAN_InitStructure.CAN_TXFP = DISABLE;
	
	//工作模式:普通模式
	CAN_InitStructure.CAN_Mode = CAN_Mode_Normal;
	//设置CAN波特率  (1MHz)
	CAN_InitStructure.CAN_SJW = CAN_SJW_4tq;
	CAN_InitStructure.CAN_BS1 = CAN_BS1_5tq;
	CAN_InitStructure.CAN_BS2 = CAN_BS2_3tq;
	CAN_InitStructure.CAN_Prescaler = 5;
	
	//初始化CAN
	CAN_Init(CAN1,&CAN_InitStructure);
	//接受到一条报文即可产生中断
	CAN_ITConfig(CAN1,CAN_IT_FMP0,ENABLE);
	
/***********************************NVIC****************************************************************/

  //CAN NVIC 配置   
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
  NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;		//子优先级0
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化NVIC寄存器
	//使能接收中断
	
/*************************************CAN过滤器******************************************************/


	//使能过滤器
	CAN_FilterInitStruct.	CAN_FilterActivation = ENABLE;
	//过滤器0关联到FIFO0
	CAN_FilterInitStruct.CAN_FilterFIFOAssignment = CAN_FilterFIFO0;
	//屏蔽滤波功能
	CAN_FilterInitStruct.CAN_FilterNumber = 0;
	//标识符屏蔽位模式
	CAN_FilterInitStruct.CAN_FilterMode = CAN_FilterMode_IdList;
	//32位寄存器
	CAN_FilterInitStruct.CAN_FilterScale = CAN_FilterScale_32bit;
	
	//高16位     
	//接收ID为CAN_EXID1的消息,使用拓展位以及遥控帧
	CAN_FilterInitStruct.CAN_FilterIdHigh = ( ((CAN_EXID1<<3)|CAN_ID_EXT|CAN_RTR_DATA) & 0xffff0000 )>>16;  
	//低16位
	CAN_FilterInitStruct.CAN_FilterIdLow = ( ((CAN_EXID1<<3)|CAN_ID_EXT|CAN_RTR_DATA) & 0x0000ffff );
	
	//屏蔽位高16位
	//屏蔽ID为CAN_EXID2的消息,使用拓展位以及数据帧
	CAN_FilterInitStruct.CAN_FilterMaskIdHigh = ( ((CAN_EXID2<<3)|CAN_ID_EXT|CAN_RTR_DATA) & 0xffff0000 )>>16;
	//屏蔽位低16位
	CAN_FilterInitStruct.CAN_FilterMaskIdLow = ( ((CAN_EXID2<<3)|CAN_ID_EXT|CAN_RTR_DATA) & 0x0000ffff );
	
	
	//初始化过滤器
	CAN_FilterInit(&CAN_FilterInitStruct);
	
}

2.CAN收发函数

//发送 
void CAN_TransmitData()
{
	  extern uint8_t cntkey;
		extern CanTxMsg TX_Message;
	  TX_Message.Data[0]=cntkey;
		
		TX_Message.DLC = 8;         //数据包长度为8字节
		TX_Message.IDE = CAN_ID_EXT;
		TX_Message.ExtId = CAN_EXID1;
		TX_Message.RTR = CAN_RTR_DATA;
		TX_Message.StdId = 0;
		
		CAN_Transmit(CAN1,&TX_Message);
}
//接收中断,和USB共用
void USB_LP_CAN1_RX0_IRQHandler() 
{
	
	if(CAN_GetITStatus(CAN1,CAN_IT_FMP0)!=RESET)
	{
    CAN_ClearITPendingBit(CAN1,CAN_IT_FMP0); 
		CAN_Receive(CAN1,CAN_FIFO0,&RX_Message);
		GPIOC->ODR^=GPIO_Pin_13;
		CAN_RX_Stat = 1;
		
  }
	
}

3.主函数main

/**
  ******************************************************************************
  * @file    main.c
  * @author  ZYS
  * @version V1.0
  * @date    2024-01-05
  * @brief   can通信步进电机协同控制
  ******************************************************************************
  */ 
 
#include "zys_headfile.h"

CanTxMsg TX_Message;
CanRxMsg RX_Message;

extern bool CAN_RX_Stat;
uint8_t rx_flag=0;

uint8_t		cntkey;
uint8_t rx_data;
uint8_t	keynum = 0;
uint8_t speed1 = 4;
uint8_t dir1 = 0;
uint8_t speed2 = 4;
uint8_t dir2 = 0;

int main ( void )
{

	/* 初始化 */
  Motor_Init();
  USART1_Config ();                 //初始化串口1
  CPU_TS_TmrInit();                 //初始化DWT计数器,用于延时函数
  LED_GPIO_Config();                //初始化 LED 灯
  OLED_Init();
  key_init();

  //初始化CAN配置
  CAN_init();	
	
	for(uint8_t i=0;i<8;i++)
		{
		  TX_Message.Data[i]=0;     
		}
		
  while ( 1 )
  {
		OLED_ShowString(4,1,"spd:");
		OLED_ShowString(3,1,"dir:");
		
		OLED_ShowNum(4,6,speed1,2);//speed1
		OLED_ShowNum(3,6,dir1,1);
		OLED_ShowNum(4,8,speed2,2);
		OLED_ShowNum(3,8,dir2,1);
		
		OLED_ShowString(1,1,"cntkey:");
		OLED_ShowString(2,1,"keynum:");
		
		OLED_ShowNum(1,9,cntkey,1);
		OLED_ShowNum(2,9,keynum,1);
		
		OLED_ShowString(2,12,"rx:");
		OLED_ShowNum(2,16,rx_data,1);
		OLED_ShowString(1,12,"tx:");
		OLED_ShowNum(1,16,TX_Message.Data[0],1);
		
		CAN_TransmitData();
		
		keynum = Key_GetNum();

		if(keynum == 1){cntkey ++;}
		if(cntkey == 6){cntkey = 0;}

		rx_data = RX_Message.Data[0];
		
			switch (rx_data){
			case 0: dir1 = 0;dir2 = 0;break;
			case 1: dir1 = 1;dir2 = 1;break;
			case 2: dir1 = 1;dir2 = 0;break;
			case 3: dir1 = 0;dir2 = 1;break;
			case 4: speed1 = 20;speed2 = 20;break;
			case 5: speed1 = 4;speed2 = 4;break;
			default: cntkey = 0;break;
		}
			
			if(dir1){MotorGO1(speed1);}
			else{MotorBack1(speed1);}

			if(dir2){MotorGO2(speed1);}
			else{MotorBack2(speed1);}
	}
}

四、实物演示

STM32基于CAN总线协议控制步进电机,stm32,嵌入式硬件,单片机

STM32基于CAN总线协议控制步进电机,stm32,嵌入式硬件,单片机

STM32基于CAN总线通信的多个步进电机协同控制文章来源地址https://www.toymoban.com/news/detail-805822.html

到了这里,关于STM32基于CAN总线协议控制步进电机的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • MKS SERVO42&57D 闭环步进电机_系列12 STM32_CAN例程

    具备脉冲接口和RS485/CAN串行接口,支持MODBUS-RTU通讯协议,内置高效FOC矢量算法。 硬件开源! 网盘: 08_例程-STM32系列(CAN) 设置波特率: 菜单 → CanRate → 500K 设置从机地址: 菜单 → CanID → 01 需要一个TTL转CAN电平模块。 接线说明 代码说明 代码功能:STM32 主板通过CAN接口读取

    2024年02月10日
    浏览(37)
  • STM32控制四个步进电机(包含运行程序)

    软件: keil 5(其他版本也ok) 硬件: 步进电机(我用的是42)×4;单片机开发板(本例使用STM32F407ZGT6);电机驱动器×4;外部按键;杜邦线。 实验效果: 四个步进电机对应四个外部按键,按下对应的外部按键选择需要控制的电机。 在开发板上按下KEYO,步进电机以500HZ的频率

    2024年04月29日
    浏览(39)
  • 用STM32定时器中断产生PWM控制步进电机

    控制步进电机可以使用PWM、定时器中断、延时,这里用的就是 定时器中断来让它转动。 板子用的是正点原子的STM32F103 mini板,驱动器是DM420(DM420驱动器资料),用开关电源供电,电机就是普通的42步进电机,步距角为1.8°,虽然按照图片来看它是个蠕动泵。如下图 PUL+——PB0,

    2023年04月09日
    浏览(49)
  • 【STM32F429】HAL库的PWM中断,精确控制脉冲数,控制步进电机

    这两天在调步进电机,希望是使得步进电机每次都达到期望的高度。在查了一天的资料,发现大部分上传的资料都是使用CubeMX生成的,可复制性很高,但未免有失可读性,故上传我的心得经验。 本来原子哥的例程里有整合度很高的,已经封装好的精确控制步进电机前进距离的

    2024年02月08日
    浏览(50)
  • 基于STM32的步进电机驱动设计

    程序源码提取链接放置文章底部,自行提取即可。 采用STM32驱动28BYJ4步进电机,实现正转反转,完成角度调整。步进电机是一种将电脉冲转化为角位移的执行机构。当步进驱动器接收到一个脉冲信号,它就驱动步进电机按设定的方向转动------一个固定的角度(及步进角)。可以

    2024年02月02日
    浏览(54)
  • 【STM32】使用HAL库对ULN2003控制28BYJ-48步进电机

    步进电机是将电脉冲信号转变为角位移或线位移,通过控制施加在电机线圈上的电脉冲顺序、频率和数量,可以控制步进电机的转向、速度和旋转角度。 配合以直线运动执行机构(螺纹丝杆)或齿轮箱装置,更可以实现更加复杂、精密的线性运动控制要求。 在非超载的情况下,

    2024年02月16日
    浏览(50)
  • stm32使用TB6600驱动器控制42BYGH型步进电机

    stm32使用TB6600驱动器控制42BYGH型步进电机 例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。 24V电源就是通过电路控制开关进行高速的导通于截至,将直流电转化为高频率的交流电提供给变压

    2024年02月11日
    浏览(44)
  • AS5600步进电机编码器(原理图+pcb+stm32控制代码)

    AS5600是一个易于编程的磁性旋转位置传感器,具有高分辨率的12位模拟或PWM输出。这种非接触式系统测量一个直径磁化的轴上磁铁的绝对角度。 引脚如下图 他有两种供电模式:5V和3.3V 我们为了和stm32F103C8T6单片机的电压一致,也使用3.3V供电,然后开始画PCB。 使用嘉立创EDA画

    2024年02月03日
    浏览(52)
  • stm32F103单片机pwm控制伺服驱动器进而控制步进电机

    1.需要一台步进电机,私服驱动器,stm32单片机;先按照说明文档,连接好硬件相关线路,对应好sign+,sign-,puls+,puls-线路,其中sign只是个io口拉高拉低操作,puls是pwm波形输出口,虽然有两根线,但只是需要控制一个IO口输出波形即可; 采用主从模式,TIM1为主定时器,tim3未从定

    2024年02月04日
    浏览(49)
  • 【STM32】步进电机及其驱动(ULN2003驱动28BYJ-48丨按键控制电机旋转)

    参考文章与课程:   【视频课程】步进电机基础原理和应用——程子华主讲   【视频课程】电机系列教学视频(基于STM32硬件)——野火   【霄耀在努力】STM32驱动步进电机(原理、程序、解决电机只震动不转动问题)   步进控制系统由以下三个部分组成: 控制器

    2023年04月09日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包