STM32,odrive之间的can通信配置

尝试用STM32与odrive进行can通信

记录一下学习过程,自用。
国外使用odirve进行开发时,基本用的都是树莓派+usb串口,考虑到学习成本和物料成本问题,暂定用stm32can来控制odrive。

1.can通信简介:

CAN,全称为“Controller Area Network”,即控制器局域网,是一种多主方式的异步串行通讯总线,是国际上应用最广泛的现场总线之一。

2. stm32can的配置

基于正点原子的探索者开发板,通过CUBEMX进行CAN的基本配置。

  1. 波特率配置,配置为250KHz在这里插入图片描述

  2. 开启接收中断
    在这里插入图片描述

  3. 在cubemx配置之后,还需要在Keil里编写CAN的发送_接收函数以及过滤器的配置等等。
    配置代码如下:

3.1cang过滤器配置

 void CAN_Config(void)
{
    CAN_FilterTypeDef  sFilterConfig;
    /*##-2- Configure the CAN Filter ###########################################*/
    sFilterConfig.FilterBank = 0;
    sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
    sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
    sFilterConfig.FilterIdHigh = 0x0000;
    sFilterConfig.FilterIdLow = 0x0000;
    sFilterConfig.FilterMaskIdHigh = 0x0000;
    sFilterConfig.FilterMaskIdLow = 0x0000;
    sFilterConfig.FilterFIFOAssignment = CAN_RX_FIFO0;
    sFilterConfig.FilterActivation = ENABLE;
    sFilterConfig.SlaveStartFilterBank = 14;
    if (HAL_CAN_ConfigFilter(&hcan1, &sFilterConfig) != HAL_OK)
    {
        /* Filter configuration Error */
        Error_Handler();
    }
    /*##-3- Start the CAN peripheral ###########################################*/
    if (HAL_CAN_Start(&hcan1) != HAL_OK)
    {
        /* Start Error */
        Error_Handler();
    }
    /*##-4- Activate CAN RX notification #######################################*/
    if (HAL_CAN_ActivateNotification(&hcan1, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)
    {
        /* Notification Error */
        Error_Handler();
    }
}

3.2发送函数
注,添加了Frame_type参数是为了方便修改发送帧的类型(数据帧和远程帧)
在odrive中 数据帧为控制指令,远程帧为请求返回数据(比如编码器计数,电压,电流等等)

uint8_t CAN_Send_Msg(CAN_HandleTypeDef *hcan,uint16_t StdID,uint8_t *msg,uint8_t len,uint8_t Frame_type)
{
    uint8_t index=0;
    uint32_t TxMailbox;   //邮箱
    uint8_t send_buf[8] = {0};
    TxHeader.StdId=StdID;        //标准标识符
    TxHeader.ExtId=0;        //扩展标识符(29位)
    TxHeader.IDE=CAN_ID_STD;    //使用标准帧
    TxHeader.RTR = Frame_type != CAN_RTR_REMOTE ? CAN_RTR_DATA : CAN_RTR_REMOTE;  //数据帧为发送数据,远程帧为请求返回数据
    //TxHeader.RTR = CAN_RTR_DATA;
    TxHeader.DLC=len;
    /*****填充消息******/
    for ( index = 0; index < len; index++) {
            send_buf[index] = msg[index];
    }
    /*****发送消息*****/
    if(HAL_CAN_AddTxMessage(&hcan1, &TxHeader, send_buf, &TxMailbox) != HAL_OK)//发送
    {
        return 1;
    }
    return 0;
}

接收函数

uint8_t CAN1_Receive_Msg(uint8_t *buf)
{
    uint32_t i;
    uint8_t	RxData[8];
	
  //数据在这里已经被填充到了RxData中
    if(HAL_CAN_GetRxMessage(&hcan1, CAN_RX_FIFO0, &RxHeader, RxData) != HAL_OK)
    {
        return 0xF2;
    }
    /*****填充消息******/
    for(i=0;i<RxHeader.DLC;i++)
        buf[i]=RxData[i];
    return RxHeader.DLC;
}

3.Odirve控制函数:

配置完can后,编写odrive的控制函数。根据官方给的通信协议编写,协议中提到有节点id和指令id,要完成对odrive的控制,需要将指令ID和节点id的合成为标准id ,同时对数据进行填充。

/*
 * 函数名:odrive_set_pos
 * 函数作用:向目标odrive发送位置指令
 * 函数参数:Node_id,DATA
 * * */
uint8_t odrive_set_pos(int node_id,float pos)
{
    uint16_t id = (node_id<<5)|SET_INPUT_POS;//合成标准id
    union ByteToFloat can_bf;//数据转换并赋值
    can_bf.value = pos/4;/*传动比为4*/
    uint8_t pos_data[8] = {0};
    memcpy(pos_data,(const void *)can_bf.data,4);
    if(CAN_Send_Msg(&hcan1 ,id,pos_data,8,CAN_RTR_DATA) == 0) {//发送
        HAL_GPIO_WritePin(GPIOF, GPIO_PIN_9, GPIO_PIN_RESET);
        return 0;
    }
    else {
        return -1;
    }
}

/* 函数名:get_pos_data
 * 函数作用:更新电机的位置信息,速度信息
 * 返回值:无
 * */
uint8_t get_pos_data(int node_id){
    uint16_t id = (node_id<<5)|GET_ENCODER_COUNT;//合成指令id
    uint8_t  pos_data[8];
    pos_data[0] = 16;
    pos_data[1] = 0;
    pos_data[2] = 0;
    pos_data[3] = 0;
    pos_data[4] = 0;
    pos_data[5] = 0;
    pos_data[6] = 0;
    pos_data[7] = 0;
    if(CAN_Send_Msg(&hcan1 ,id,pos_data,8,CAN_RTR_REMOTE) == 0) {//发送
        return 0;
    }
    else {
        return -1;
    }
}

本人stm32属于初学阶段,若描述有误,或者代码编写不规范的地方,请各位指出。

评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值