1.硬件连接

硬件连接没什么复杂的,就连接对应的线即可,下面是我画的一个简单的电气连接图

2.上位机配置

上位机主要配置驱动器节点ID,波特率,心跳,CAN驱动。我用的是科亚的上位机和蓝玖的电机。使用上位机时,使用232转USB模块连接电脑,配置好波特率后即可用串口连接。当配置好一系列参数时就可以用串口把这些配置保存进驱动器了。

3.初始化

我这里用的MCU是STM32F407,下面先直接贴上我的初始化代码:

void CAN2_Mode_Init(uint8_t tsjw,uint8_t tbs2,uint8_t tbs1,uint16_t brp,uint8_t mode)
{GPIO_InitTypeDef       GPIO_InitStructure; CAN_InitTypeDef         CAN_InitStructure;CAN_FilterInitTypeDef CAN_FilterInitStructure;NVIC_InitTypeDef        NVIC_InitStructure;CAN_DeInit(CAN2);CAN_StructInit(&CAN_InitStructure);//使能相关时钟RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);//使能PORTB时钟RCC_APB1PeriphClockCmd(RCC_APB1Periph_CAN1|RCC_APB1Periph_CAN2, ENABLE);//使能CAN1和CAN2时钟//初始化GPIOGPIO_InitStructure.GPIO_Pin = GPIO_Pin_12| GPIO_Pin_13;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉GPIO_Init(GPIOB, &GPIO_InitStructure);//初始化PB12,PB13//引脚复用映射配置GPIO_PinAFConfig(GPIOB,GPIO_PinSource12,GPIO_AF_CAN2); //GPIOB12复用为CAN2GPIO_PinAFConfig(GPIOB,GPIO_PinSource13,GPIO_AF_CAN2); //GPIOB13复用为CAN2//CAN单元设置CAN_InitStructure.CAN_TTCM=DISABLE; //非时间触发通信模式CAN_InitStructure.CAN_ABOM=ENABLE;  //启用软件自动离线管理CAN_InitStructure.CAN_AWUM=DISABLE;    //睡眠模式通过软件唤醒(清除CAN->MCR的SLEEP位)CAN_InitStructure.CAN_NART=ENABLE;   //禁止报文自动传送CAN_InitStructure.CAN_RFLM=DISABLE;  //报文不锁定,新的覆盖旧的CAN_InitStructure.CAN_TXFP=DISABLE;  //优先级由报文标识符决定CAN_InitStructure.CAN_Mode= mode;//模式设置CAN_InitStructure.CAN_SJW=tsjw;   //重新同步跳跃宽度(Tsjw)为tsjw+1个时间单位 CAN_SJW_1tq~CAN_SJW_4tqCAN_InitStructure.CAN_BS1=tbs1; //Tbs1范围CAN_BS1_1tq ~CAN_BS1_16tqCAN_InitStructure.CAN_BS2=tbs2;//Tbs2范围CAN_BS2_1tq ~    CAN_BS2_8tqCAN_InitStructure.CAN_Prescaler=brp;  //分频系数(Fdiv)为brp+1CAN_Init(CAN2, &CAN_InitStructure);// 初始化CAN2//配置过滤器CAN_FilterInitStructure.CAN_FilterNumber=15;//过滤器15CAN_FilterInitStructure.CAN_FilterMode=CAN_FilterMode_IdMask;CAN_FilterInitStructure.CAN_FilterScale=CAN_FilterScale_32bit;//32位CAN_FilterInitStructure.CAN_FilterIdHigh=0x0000;32位IDCAN_FilterInitStructure.CAN_FilterIdLow=0x0000;CAN_FilterInitStructure.CAN_FilterMaskIdHigh=0x0000;//32位MASKCAN_FilterInitStructure.CAN_FilterMaskIdLow=0x0000;CAN_FilterInitStructure.CAN_FilterFIFOAssignment=CAN_Filter_FIFO0;//过滤器0关联到FIFO0CAN_FilterInitStructure.CAN_FilterActivation=ENABLE; //激活过滤器0CAN_FilterInit(&CAN_FilterInitStructure);//滤波器初始化CAN_ITConfig(CAN2,CAN_IT_FMP0,ENABLE);//FIFO0消息挂号中断允许   NVIC_InitStructure.NVIC_IRQChannel = CAN2_RX0_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;// 主优先级为3NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;// 次优先级为3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;NVIC_Init(&NVIC_InitStructure);
}

主函数对CAN初始化的时候直接调用这个函数即可,传入的参数决定了CAN的波特率。由于我用的MCU是f407,其CAN时钟频率为42MHZ,所以公式即为42M/(tsjw+1+tbs2+1+tbs1+1)*brp

我用的电机仅支持波特率250K,所以我的初始化调用是这样写的:

CAN2_Mode_Init(CAN_SJW_1tq, CAN_BS1_7tq, CAN_BS2_6tq, 12, CAN_Mode_Normal);//配置并启动CAN接口  250k波特率=42M/(1+7+6)*12

对了,还可以开启CAN接收中断,这样就可以接收到电机的心跳包和回复包了,但若要进接收中断就必须先开启CAN 1的时钟,再开启CAN2时钟,还必须将过滤器设置在14-27之间

//CAN2_RX0中断服务函数
void CAN2_RX0_IRQHandler(void)
{CAN_Receive(CAN2, 0, &CAN2RxMessage);//将CANFIFO中收到的数据储存到“CAN2RxMessage”变量中CAN2_rx_flag = FLAG_OK;//标志位置位//    printf("can2irq\r\n");
}

我这个电机初始化完了还需要发送一条使能指令:

void Servo_can_enable_test(void)
{uint8_t post_can2;CAN2TxMsg.ExtId = 0x00000601;//CANOpen协议,正常通信包,主机发送ID为:0x600 + 目标设备idCAN2TxMsg.DLC = 4;CAN2TxMsg.IDE = CAN_ID_EXT;// 使用扩展标识符CAN2TxMsg.RTR=0;// 消息类型为数据帧,一帧8位CAN2TxMsg.Data[0] = 0x23;CAN2TxMsg.Data[1] = 0x0D;//索引的低8位(LSB)0x00CAN2TxMsg.Data[2] = 0x20;//索引的高8位(MSB) 0x20CAN2TxMsg.Data[3] = 0x01;//子索引 0x01post_can2=CAN_Transmit(CANOPEN_PORT, &CAN2TxMsg);}

直接在初始化完了之后调用一次就行,为啥要发这几个字节呢,因为厂家文档写的,具体情况具体讨论,有可能你的电机配置与我不同,这就需要你仔细发现问题了

使能之后就可以发送扩展帧数据驱动电机旋转了,比如我要让电机以100的速度旋转,我是这样写的:

void Servo_speed_tx_test(void)
{
//  uint8_t post_can1,i;uint8_t post_can1;CAN2TxMsg.ExtId = 0x00000601;//CANOpen协议,正常通信包,主机发送ID为:0x600 + 目标设备idCAN2TxMsg.DLC = 8;CAN2TxMsg.IDE = CAN_ID_EXT;// 使用扩展标识符CAN2TxMsg.RTR=0;// 消息类型为数据帧,一帧8位CAN2TxMsg.Data[0] = 0x23;CAN2TxMsg.Data[1] = 0x00;//索引的低8位(LSB)0x00CAN2TxMsg.Data[2] = 0x20;//索引的高8位(MSB) 0x20CAN2TxMsg.Data[3] = 0x01;//子索引 0x01CAN2TxMsg.Data[4] = 0x64;//(0x00FF&speed_data)CAN2TxMsg.Data[5] = 0x00;//(0xFF00&speed_data)>>8CAN2TxMsg.Data[6] = 0x00;CAN2TxMsg.Data[7] = 0x00;post_can1=CAN_Transmit(CANOPEN_PORT, &CAN2TxMsg);printf("post_can1:%d\r\n",post_can1);}

直接在while(1)中调用即可,但调用的时候必须加延时,如果不加延时就会导致数据发送过快,邮箱一直被占用,这样也是驱动不了电机的。但如果你需要频繁地改动速度,不可能每次都计算好速度高低位再写入,这样太麻烦了。我们需要直接填入速度值,然后再在函数内部自动计算高低位并填入指令中发送出去。我是这样写的

//CANOpen读取或写入从设备的寄存器
int8_t CAN_OPEN_Read_Or_Write_Driver_Reg(   uint8_t dev_addr,uint16_t index,uint8_t subindex,uint8_t *data,uint8_t len,uint8_t wr_state)
{uint8_t i;CAN2TxMsg.ExtId = 0x600 + dev_addr;//CANOpen协议,正常通信包,主机发送ID为:0x600 + 目标设备idCAN2TxMsg.DLC = 8;CAN2TxMsg.IDE = CAN_ID_EXT;// 使用扩展标识符CAN2TxMsg.RTR=0;// 消息类型为数据帧,一帧8位CAN2TxMsg.Data[1] = index & 0xFF;//索引的低8位(LSB)0x00CAN2TxMsg.Data[2] = (index >> 8) & 0xFF;//索引的高8位(MSB) 0x20CAN2TxMsg.Data[3] = subindex;//子索引 0x01//CAN发送状态为:写寄存器if(wr_state == CAN_OPEN_REG_WRITE){//不同的数据长度,data[0]的值不同if(len == 1){CAN2TxMsg.Data[0] = 0x2F;}else if(len == 2){CAN2TxMsg.Data[0] = 0x2B;}else if(len == 4){CAN2TxMsg.Data[0] = 0x23;}else{return CAN_OPEN_WRONG_LENGTH;}//将数据写入待发送的变量中for (i = 4 ; i < 4+len ; i++){CAN2TxMsg.Data[i] = data[i-4];}for (i = 4+len ; i < 8 ; i++){CAN2TxMsg.Data[i] = 0;}}else if(wr_state == CAN_OPEN_REG_READ)//CAN发送状态为:读寄存器{CAN2TxMsg.Data[0] = (2 << 5);//由于读寄存器一般不需要带参数,所以数据长度data[0]一般为0X40(即:2 << 5)for (i = 4 ; i < 8 ; i++){CAN2TxMsg.Data[i] = 0;}}CAN2_Receive_Flag_Init();//为了保险,将CAN接收数据的标志位重置,以免将CAN发送之前收到的CAN数据错误地当成了其对应地应答CAN_Transmit(CANOPEN_PORT, &CAN2TxMsg);return CAN_OPEN_SUCCESS ;
}

然后,再调用即可

int32_t speed1_test=50;
CAN_OPEN_Read_Or_Write_Driver_Reg(SERVO_ID, 0x2000, MOTOR_1_ID, (uint8_t *)&speed1_test, 4,CAN_OPEN_REG_WRITE);

CANOpen协议中还有许多操作也是类似的道理,我这里就不一一介绍了,下面我会贴上我的源代码,供大家参考:CAN扩展帧_电机

基于CANOpen协议驱动直流无刷减速电机相关推荐

  1. 直流无刷减速电机PID控制

    最近做了直流无刷减速电机的控制的项目,针对项目中遇到的问题做下总结. #PID_Control PID 代码(速度环 位置环 串级) STM32F407VET6 STM32CubeMX 更新记录 V1 ...

  2. 997直流有刷减速电机调试

    给王八用的轮毂和履带电机是997直流有刷减速电机,本文记录该电机的调试过程. 硬件信息 电机 电机的淘宝链接:997暴力直流行星齿轮减速电机24V12低速大扭力正反转可调中轴马达-淘宝网 (taoba ...

  3. pwm 正弦波_CC6420 低噪声,高效率,5V/12V 450mA 单相正弦波直流无刷马达驱动

    特性  内置可调增益高灵敏度霍尔传感器  效率高,采用控制专利技术实现零电流换相(ZCS)和零磁场换相(ZBS)  噪声低,采用SVPWM 技术实现对电机的正弦波控制,降低了电磁噪声  PWM ...

  4. ACS606开发方案… 源码,伺服驱动,无刷,直流…

    ACS606开发方案- 源码,伺服驱动,无刷,直流- tb341810831

  5. 基于maxwell的6极36槽永磁同步电机(永磁直流无刷)模型,水冷

    基于maxwell的6极36槽永磁同步电机(永磁直流无刷)模型,水冷,24.5kw, 绕组类型:分布式绕组,直流电压270Vdc,对6极 额定转速9000rpm,扭矩额定扭矩:输出扭矩不低于26Nm, ...

  6. 张飞老师硬件第二十四部--马达驱动--原理图设计①----5三项直流无刷永磁电机相关

    三项直流无刷永磁电机的单相导通/星型连接/三角连接 每种连接的优缺点 大家自行消化吧

  7. 直流有刷减速电机结构及其工作原理

    寒假无聊拆了个直流有刷减速电机.下面介绍一下它的结构和工作原理 直流电机 直流电机和直流减速电机: 构造上相差的是一个减速齿轮组. 普通的直流电机当空载时,电机的转速由电压决定,直流减速电机的转速由齿 ...

  8. 频率计的交流耦合和直流耦合的区别_风机盘管直流无刷与普通交流电机有什么区别和不同?...

    注:水舒适整理原创,转载请注明出处,面斥不雅直流无刷风机盘管由于具有节能.无级调速.安静.寿命长等优点,所以在许多新建项目中都被广泛应用,并且也越来越得到市场的认可与青睐.那么,直流无刷风机盘管与普通 ...

  9. stm32代码生成,基于模型的设计(MBD) 无刷直流电机MATLAB开发板建模代码生成控制 MBD电机控制资料

    stm32代码生成,基于模型的设计(MBD) 无刷直流电机MATLAB开发板建模代码生成控制 MBD电机控制资料 控制算法采用MATLAB建模并生成代码的方式 配套电机 开发板 模型 源代码和视频 P ...

最新文章

  1. logstash创建不了索引_「技术选型」Elasticsearch vs. Solr-选择您的开源搜索引擎
  2. automation服务器不能创建对象的问题
  3. 易语言 mysql 卡死_易语言操作MYsql 所有课程停发
  4. 工业机器人电路图讲解话术_6张经典电路图分析助你进阶高级电工,你都会了吗?...
  5. boost::remove_copy相关的测试程序
  6. arcgis将点的属性赋值给面
  7. Java 添加、更新和移除PDF超链接
  8. 技术圈儿007---Redis 生产架构选型解决方案
  9. delphi控件属性大全-详解-简介
  10. 走近openGauss数据库
  11. 计算机 开机硬盘灯一直亮,硬盘灯一直亮,教您电脑硬盘指示灯一直亮怎么办
  12. 计算机断层CT检查肺部混浊,揪出早期肺癌 低剂量电脑断层检查
  13. wuauclt.exe是什么进程?为什么运行?wuauclt.exe进程介绍
  14. 2019新版《黑马web前端课程+项目实践课程》
  15. Python爬虫:爬取某鱼颜值主播图片并保存到本地升级版!
  16. Oracle中如何查询CLOB字段类型的内容
  17. 魔法宝石(邻接表+dfs更新)
  18. 剑指 Offer 05. 替换空格 三种方法
  19. 百度AI技术「通用物体与场景识别」开发使用体验
  20. 【汇总】行为识别、时序行为检测、弱监督行为检测、时空行为定位论文代码(持续更新!!!)

热门文章

  1. 医学院交换去计算机学院,皖南医学院学生2018年赴台湾元培医事科技大学参加交换生项目交流心得...
  2. 阿里巴巴淘系开源首个多模态直播服饰检索数据集
  3. 还不会用Vue写出的excel表实现pdf导出吗?来,豪豪手把手教你
  4. 北航2017级算法第一次上机---芸如的入学测试
  5. python获取地图上经纬度_Python获取各大地图平台经纬度数据,哪家的数据最准确?...
  6. 辐射定标、辐射校正、大气校正、正射校正等相关概念
  7. kind多节点端口映射
  8. canvas实现矩形框,用来进行图片框选
  9. 在 Mac 上的“邮件”中添加学校电子邮件帐户(厦门大学邮件账户)
  10. ps4仁王服务器不稳定,原来《仁王》放弃独占PS4早有预兆 未来将是跨平台大潮...