实验室师兄之前用stm32之间进行can通信,其中一个作为主机,另外作为从机,从机负责电机运转,并取出电机的速度,然后通过can通信发送给主机,然后主机通过串口与上位机进行通信。这一部分操作可以参照以下链接:https://www.ncnynl.com/archives/201703/1414.html

现在我们选择用伺服驱动器与一个stm32进行can通信,从而实现对电机的控制,目前我们实现的是对电机的速度输入,启动电机,(并进行速度反馈,进行OLED输出,从而进行电机的PID调节)。
首先我们选择了以下图示伺服驱动器,驱动器这块选择淘宝搜索可进行can通信的编码器应该可以找到类似产品

然后按照手册,我们将电机的编码器信号线CN2,与电机相连,同时将电机三根动力线与电机相连,然后将RS232/CAN端口连出,由于我们首先测试的是商家给的PC端软件与伺服驱动器进行RS232通信,所以这里我们通过RS232与PC端相连,给伺服驱动器供电。效果图如下:

然后我们通过上位机软件给电机写入速度参数,加速度参数等,可以启动电机并有电流,位置,速度的实时反馈,初始如图:

上面进行了电机的初步测试,通过电机空载反馈回来的电流,我们初步判断电机是否工作正常,这里我们刚开始就出现电流在空载且速度较小的情况下,出现了电流输出过大的情况,于是在相关技术人员的帮助下随与商家联系更换了电机。

接下来就进入can通信的正题,can通信这一块我们最好通过实验板跑一下例程,然后结合程序去分析一下can通信的具体实现原理,及其各个寄存器的作用是什么,卡门一下stm32的技术文档(这里面时一些关于can通信的技术文档链接:https://pan.baidu.com/s/1LJJOMAxTTGgzYFfVnVGx5Q
提取码:agzo )。

想深入了解can通信,这里我推荐以下链接:
https://blog.csdn.net/qq_36355662/article/details/80607453
https://pan.baidu.com/s/1iy5z9g03Z4ZYn5gJYoN5WA?errno=0&errmsg=Auth%20Login%20Sucess&&bduss=&ssnerror=0&traceid=#list/path=%2F
(这是洋桃电子的资料,里面老师讲的很好很细,有助于对can通信理解)

首先在完成对can通信的理解后,我们会发现can通信的连线非常简单,只需要把can_h,can_l与其他can_h,can_l对应连接即可,其中两端需要串入120欧电阻,其作用是匹配总线阻抗,提高数据通信的抗干扰性及可靠行。(这里在设备较少时可以不接,但最好接上,消除干扰,本身stm32板内部已经串入120欧电阻,而且驱动器本身也有拨动按键来配置120欧电阻)
下一步我们需要按照手册编写can通信协议,通过stm32发送指令给伺服驱动器,从而实现电机的控制。这里特别提醒一下,这里需要用到can分析仪来分析到底哪里出了问题,这里我们走了弯路,问了技术人员后才发现这里离不开can分析仪对指令进行分析,can分析仪网上200元左右可以买到,如下:


接下来结合程序和手册分析一下到底如何编写指令,下面来自手册


通过这一块我们可以发现想要点对点的给伺服驱动器进行写数据操作的指令,这里伺服驱动器的ID号和组号可以通过之前的PC软件通过串口RS232写入。下一步就是需要用那些寄存器,并怎么给寄存器赋数据,这里从bite0-bite8的顺序我们可以发现指令写入的顺序。



通过 这一部分寄存器,我们实现给伺服驱动器发送速度模式,并设定速度,最后启动电机的指令。然后通过自动报告的方式可以获取到反馈回来的速度,电流,位置。
下面是在stm32上的部分程序:

//can通信发送指令
//motor_init.c的写入数据代码
void Motor_Init(void)
{CommandData[0]=Group_Motors; CommandData[1]=FCW_One2One; CommandData[2]=Register_SpeedSet; //速度设定寄存器CommandData[3]=0x02; CommandData[4]=0xFE;CommandData[5]=Register_Moter; //启动电机CommandData[6]=0x00; CommandData[7]=0x00;    CAN_SendMsg(ID_MASTER, CommandData);CommandData[0]=Group_Motors; CommandData[1]=FCW_One2One; CommandData[2]=Resister_ReportTime; //自动报告时间设置成1sCommandData[3]=0x07; CommandData[4]=0xd0;CommandData[5]=Resister_AutoReportMode; //位置反馈 ,电流,速度CommandData[6]=0x00; CommandData[7]=0x00; CAN_SendMsg(ID_LeftMotor, CommandData);
}
float Get_SpeedActual(uint32_t ID, float actual_speed)
{int speed = 0;actual_speed = 0;CommandData[0]=Group_Motors; CommandData[1]=FCR_One2One; CommandData[2]=Resister_RSpeed; //读取的输出转速CommandData[3]=0x00; CommandData[4]=0x00;CommandData[5]=0xFF; //设置为无效寄存器CommandData[6]=0x00; CommandData[7]=0x00;   Clear_canBuffer();CAN_SendMsg(ID, CommandData);OLED_ShowString(0, 2,"Lspeed:",16);while(Check_canRX()) ;if((RxMessage.StdId) == 0x05 && RxMessage.Data[2]==Resister_RSpeed ) //设置为无效寄存器)//是否收到八位字节,且为输出转速寄存器{//将得到的数组合并成原始数    speed = RxMessage.Data[3] << 8 | RxMessage.Data[4];
//      speed = RxMessage.Data[6] << 8 | RxMessage.Data[7];  //*actual_speed = RPM2Speed(speed/3000.0 * 8192.0);actual_speed = RPM2Speed(speed/8192.0 * 3000.0); //实际电机转速转换成m/s
//      OLED_ShowNumber(54, 2, actual_speed);OLED_ShowNumber(12, 4, actual_speed);//OLED_ShowString(12, 3,"stm32_master",16);return 1;}return 0;
}

在motor.h文件下,我们对寄存器进行了宏定义例如:

#ifndef __MOTOR_H
#define __MOTOR_H//FunctionCodeWrite,点对点的写数据操作功能码
#define FCW_One2One         0x1A  //发送指令,指令码,写数据,但不保存数据
#define FCW_One2One_Ri  0x1B    //接收正确后返回指令
#define FCW_One2One_E   0x1C    //接收错误后返回指令//FunctionCodeRead,点对点的读数据操作功能码
#define FCR_One2One         0x2A    // 指令的功能码,表示读数据,从机接收到指令后,把地址相应的数据内容上传
#define FCR_One2One_Ri  0x2B    //接收正确后返回指令
#define FCR_One2One_E       0x2C    //接收错误后返回指令//FunctionCodeWrite,一对多的写数据操作功能码,主机发送数据指令,接收正确后,从机返回相应数据指令
#define FCW_One2Many    0x8A  //发送指令,写数据,但不保存数据
#define FCW_One2Many_Ri 0x8B    //接收正确后返回指令
#define FCW_One2Many_E  0x8C    //接收错误后返回指令//FunctionCodeRead,一对多的读数据操作功能码
#define FCR_One2Many            0x9A    //发送指令
#define FCR_One2Many_E      0x9C    //接收错误后返回指令//相关寄存器地址
#define Register_Moter      0x00  //电机寄存器   功能:写入数据不同,电机的启动和停止
#define Register_Mode           0x02  //电机输入模式选择,功能:写入数据不同,模式不同
#define Resister_SiteMode   0x51    //位置模式寄存器
#define Register_SpeedSet   0x06  //PC模式-速度给定
#define Resister_GroupNum 0x0b  //设置从机CAN组号
#define Resister_IDNum      0x0d    //设置从机CAN-ID号
#define Resister_ReportTime     0x0c    //设置从机CAN报告时间
#define Resister_AutoReportMode     0x2e    //设置自动报告内容选择//10代表0到3000RPM 所用时间是 100ms
#define Resister_AccTimeInSpeed 0x0A    //速度模式下,加减速时间设定,
#define Resister_AccTimeInSite  0x09    //位置模式下,加减速时间设定
//设定的数字量 8192 对应实际转速 3000RPM
#define Resister_SpeedLimit         0x1D    //位置模式下,速度限幅值//读参数地址列表
#define Resister_RLocation  0x55    //定位是否完成
#define Resister_RCircuit     0xE2//输出电流
#define Resister_RSpeed         0xE4//输出转速
#define Resister_ROdomH         0xE8//位置反馈高16位
#define Resister_ROdomL         0xE9//位置反馈低16位
#define Resister_RError         0xE3//电机的组号,以及ID号
#define Group_Motors                0x00
#define ID_MASTER          0x00         //定义主机ID
#define ID_LeftMotor                0x05      //定义左伺服ID
#define ID_RightMotor               0x06      //定义右伺服ID#define PI 3.1415926
#define Diameter    25              //轮子直径
#define PlusePerRound  2000 //脉冲数每转#include "sys.h"
#include "usart.h"
#include "delay.h"
#include "led.h"
#include "oled.h"
#include "string.h"
#include "can.h"//下面的速度单位是RPM,表示转每分钟(round per minute)
void Motor_Init(void);
void Set_SpeedLimit(uint32_t ID, float limit_speed);
void Set_SpeedTarget(uint32_t ID, float target_speed);
//int Get_SpeedActual(uint32_t ID, float* actual_speed);
float Get_SpeedActual(uint32_t ID, float actual_speed);
int Get_Odometry(uint32_t ID, float* odom);
int Speed2RPM(float speed);
float RPM2Speed(int rpm);#endif

写好指令后,首先用can分析仪给电机驱动器发消息,控制电机旋转,这样可以派出伺服驱动器是否有问题
如下

波特率的设置:1M,can通道用的2

首先看到接受到的数据是来自于伺服驱动器的心跳返回,
然后发送指令,发送正确后可以返回指令,可以看到can通讯成功了

其他指令是伺服驱动器的“心跳”,里面会包含我们自动报告的位置,速度等

然后我们用stm32与伺服驱动器进行通信
写入上述程序可以运行程序:
can分析仪:

然后发送指令,停止电机运转

can分析仪:

发现我们可以控制电机的运转和停止,并通过”心跳“可以取出返回的速度,这里目前只取出了一个速度并用OLED显示,希望显示实时速度,进行PID调试,后续还需要补充。

代码分享:

链接:https://pan.baidu.com/s/1ct7v_hC6gEpfyGtFw2fvkQ
提取码:w18w

stm32与伺服驱动器进行can通信相关推荐

  1. 利用stm32+app inventor与esp8266通信

    利用stm32+app inventor与esp8266通信 stm32与esp8266通信 移动端app制作.生成.控制 本章实验的目的是将手机连接上ESP8266提供的WIFI网络,打开自定义的a ...

  2. STM32驱动W5100实现udp通信

    STM32驱动W5100实现udp通信 本文博客链接:http://blog.csdn.net/jdh99,作者:jdh,转载请注明. 环境: 主机:WIN7 开发环境:MDK4.72 MCU:STM ...

  3. STM32平台的USART串口通信

    本文目的是编写stm32串口通信程序,实现stm32上电自动循环发送hello LYJ!!!,并可通过上位机控制stm32串口发送与否.通过亲自做一下USART串口通信实验,学习如何使用stm32平台 ...

  4. Matlab 与stm32单片机之间的串口通信

    Matlab 与stm32单片机之间的串口通信 在我们用stm32做信号处理时,我时常需要用到Matlab对我们采集的数据进行分析,拟合.按照传统的方法,我们一般都会先将数据通过串口助手打印出来,再导 ...

  5. 基于串口助手的STM32与计算机进行串口通信

    基于串口助手的STM32与计算机进行串口通信 序 言 一. 串口通信概述 二.项目说明 三.实战过程 1)实现stm32向上位机发送字符 2)实现stm32发和收 3)Keil中针对stm32系统进行 ...

  6. STM32的I2C主从机通信

    最近一段时间在做I2C通信协议,需要在两块STM32之间做I2C通信,定的是主机用IO口模拟,从机用的是STM32的硬件I2C,我的项目要求是需要主从机之间能够进行一串数据收发而不出错,实验时在主机方 ...

  7. 【STM32】标准库 USART通信

    通信的目的那一点的解析:STM32虽然功能丰富,但是有一些功能是没有的,需要外挂芯片功能实现,比如蓝牙无线遥控.陀螺仪加速度计测量姿态功能,这时候就需要外接通信线连接外挂芯片,与外挂芯片交换数据,实现 ...

  8. STM32 用RS485进行半双工通信出现的问题

    最近接了一个项目,需要用到RS485总线同时和多台机器通信,方式是半双工,但是当向总线一次发送大量数据的时候,STM32就会像出现死机一样,经过调试发现串口在既不是接收数据中断,也不是发送数据中断的情 ...

  9. STM32常用协议之串口通信详解

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 一.相关理论概念 1.1 通信基本概念 1.1.1 串行/并行 1.1.2 单工/半双工/全双工 1.1.3 同步/异 ...

最新文章

  1. HDU 1273 漫步森林
  2. Hibernate的关联关系映射
  3. TF之DNN:利用DNN【784→500→10】对MNIST手写数字图片识别数据集(TF自带函数下载)预测(98%)+案例理解DNN过程
  4. c语言程序设计精髓第二周,2实型数据C语言程序设计精髓.pdf
  5. ZBarSDK扫描二维码
  6. WebDriver中的元素状态检测表
  7. mysql 添加用户_mysql创建用户与授权
  8. 第六章实验报告(函数和宏定义实验)
  9. 小程序webview不全屏_小程序不在小(深度)
  10. mysql join越多性能_mysqljoin的原理和优化
  11. qt checkbox 选中事件_Qt学习笔记3(布局管理)
  12. Stanford机器学习---第二讲. 多变量线性回归 Linear Regression with multiple variable
  13. matcaffe训练与测试
  14. python类方法和静态方法_Python 中的方法、静态方法(static method)和类方法(class method)...
  15. 基于java坦克大战游戏
  16. 定时任务cron表达式工具
  17. anjuta 连接mysql_anjuta的基本使用方法(包括如何设置MYSQL)
  18. java 写代码求导_OO_JAVA_表达式求导
  19. 计算机常用的启动方法有,加快电脑开机、运行的常用手段
  20. bcdedit添加linux引导,利用Bcdedit创建Linux系统引导

热门文章

  1. Object-oriented programming 二手车鉴定,怎么通过VIN大架号查询汽车的维修保养记录和出险记录
  2. 最全的30+个开源免费的Docker工具
  3. 为Surface Neo和Surface Duo准备代码
  4. 如何让诺基亚Booklet 3G等慢速上网本运行速度更快
  5. php 磁盘配额,Linux edquota命令:修改用户(群组)的磁盘配额
  6. mysql技能特长怎么写_自我介绍性格技能兴趣特长.doc
  7. SAP FIORI移动产品架构优化衍进之路
  8. java 数据库 树_在数据库中保存树数据(族树)
  9. 【去雾论文阅读】A Novel Fast Single Image Dehazing Algorithm Based on Artificial Multiexposure Image Fusion
  10. 基于centos7学习总结 -- 文件系统相关内容