RT-Thread studio配置can hal库 驱动GM6020

RT-Thread studio配置can hal库 驱动GM6020

最近由裸机系统转战rt-thread,在刚入手RT-Thread的过程中记录一些东西吧,可能是刚做的原因,软件还不是那么完整好用,希望以后可以越来越好。手头正好有一个大疆的GM6020电机,想用can做一个驱动来试一下。
提前说明一下,由于我按照官方的教程调用函数没有成功,而且响应的文件也没自动加载,不知道是我的原因还是软件不支持,现在我是直接用hal库的函数驱动,效果一样,也是在studio里面直接操作,希望有懂的大神可以指出正确的操作。

1、新建工程

新建工程
这里我用的是stm32f103vet6芯片,板子是自己做的。

2、CubeMx配置

先新建一个工程
在这里插入图片描述
打开下载接口,否则芯片烧写一次后就会被锁死
在这里插入图片描述
外部时钟
在这里插入图片描述
时钟配置!!这里很重要!!!!我就是因为这里没配置好!不同的芯片根据自己的芯片手册配就行了,或者找野火的资料hal库开发指南里面有一些芯片的说明!
在这里插入图片描述
使能can 打开接收中断
在这里插入图片描述
接下来是配置can 我这里用的是1Mbps 设置BS1 BS2的时候可以先把数调大一个再调回来,这个报错不影响使用
在这里插入图片描述
project配置
在这里插入图片描述
这里选中可以将驱动代码单独生成一个.c .h文件
在这里插入图片描述
生成工程
在这里插入图片描述

3、RT-Thread studio代码移植

首先打开setting里的can模块
在这里插入图片描述
打开宏
在这里插入图片描述
时钟函数,注意只需要将大括号内的代码覆盖掉drv_clk.c中的函数代码,函数名不要改
在这里插入图片描述
如下
在这里插入图片描述
然后将生成的can.c can.h复制到studio工程下的drivers文件夹下
在这里插入图片描述
编译一下studio工程 左侧会自动显示添加的文件
在这里插入图片描述
由于cubemx生成的代码中没有can的过滤器配置,这里需要自己添加,在can.c中

HAL_StatusTypeDef CAN_Filter_Init(CAN_HandleTypeDef *h_can)
{
  CAN_FilterTypeDef sFilterConfig;

  sFilterConfig.FilterBank = 0;   //chenal 0
  sFilterConfig.FilterMode = CAN_FILTERMODE_IDMASK;
  sFilterConfig.FilterScale = CAN_FILTERSCALE_32BIT;
  sFilterConfig.FilterIdHigh = ((((uint32_t)0x205<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF0000)>>16;
  sFilterConfig.FilterIdLow = (((uint32_t)0x205<<3)|CAN_ID_EXT|CAN_RTR_DATA)&0xFFFF;
  //MASK bit 0 means don't care,bit 1 means match
  sFilterConfig.FilterMaskIdHigh = 0x0000;   //无需匹配
  sFilterConfig.FilterMaskIdLow = 0x0000;
  sFilterConfig.FilterFIFOAssignment = CAN_FILTER_FIFO0; //FIFO0
  sFilterConfig.FilterActivation = CAN_FILTER_ENABLE;   //enable filter
  sFilterConfig.SlaveStartFilterBank = 0;
  if (HAL_CAN_ConfigFilter(h_can, &sFilterConfig) != HAL_OK)
  {
    rt_kprintf("rt_can_filter_error!!\r\n");
    Error_Handler();
    return HAL_ERROR;
  }
  //regist RX_IT
  if (HAL_CAN_ActivateNotification(h_can, CAN_IT_RX_FIFO0_MSG_PENDING) != HAL_OK)  //??CAN_IT_RX_FIFO0_MSG_PENDING ?????????
  {
    rt_kprintf("rt_an_error!!\r\n");
    Error_Handler();
    return HAL_ERROR;
  }
 return HAL_OK;
}

自己写一个发送函数,调用的库函数发送HAL_CAN_AddTxMessage() can.c中

uint8_t HAL_CAN_SendTxMessage(CAN_TxHeaderTypeDef *TxHeader,uint32_t std_id, uint8_t aData[],uint16_t lengh)
{
  uint32_t TxMailBox;
  uint8_t FreeTxMailBoxNum;

  TxHeader->StdId = std_id;
  TxHeader->DLC = lengh;
  TxHeader->IDE = CAN_ID_STD;
  TxHeader->RTR = CAN_RTR_DATA;
  TxHeader->TransmitGlobalTime = DISABLE;

  while(0 == FreeTxMailBoxNum)
  {
   FreeTxMailBoxNum = HAL_CAN_GetTxMailboxesFreeLevel(&hcan);
  }

  if (HAL_CAN_AddTxMessage(&hcan, TxHeader, aData, &TxMailBox) != HAL_OK)
  {
    /* Transmission request Error */
    Error_Handler();
    return 0;
  }
 return 1;
}

can.c 里添加收发结构体
在这里插入图片描述
can.h将#include <main.h>改#include <board.h>
并且声明一下结构体

在这里插入图片描述
can.c 添加GM6020的数据包发送程序,并将函数添加到.h文件中声明

uint8_t txdata[8] ;
void can_6020()
{
    txdata[0] = 5000>>8;
    txdata[1] = 5000&0x00ff;
    MX_CAN_Init();
    CAN_Filter_Init(&hcan);
    HAL_CAN_Start(&hcan);
    HAL_CAN_ActivateNotification(&hcan, CAN_IT_RX_FIFO0_MSG_PENDING);



    while(1)
    {
        HAL_CAN_SendTxMessage(&TxHeader,0x1FF, txdata,8);
        rt_thread_mdelay(100);
    }
}

在drv_common.c里添加中断服务函数
在这里插入图片描述

void USB_LP_CAN1_RX0_IRQHandler(void)
{
    HAL_CAN_IRQHandler(&hcan);
}

*该函数会自动调用void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef hcan)
因此我们在can.c里添加这个函数

简单写一下测试用,实际可根据自己的需要加筛选器,以及具体的中断接收函数,这里只给出介绍

void HAL_CAN_RxFifo0MsgPendingCallback(CAN_HandleTypeDef *hcan)
{
    uint8_t aRxData[8];

    if(HAL_CAN_GetRxMessage(hcan, CAN_RX_FIFO0, &RxHeader, aRxData) == HAL_OK)
    {
        //rt_kprintf("can 6020 receive message !!!\r\n");
    }
}

到这基本配置完成,接下来就是添加一个线程来验证一下程序。

4、添加线程

main.c

#include <rtthread.h>

#define DBG_TAG "main"
#include "can.h"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>

static rt_thread_t can6020_thread = RT_NULL;

int main(void)
{
    can6020_thread =
                    rt_thread_create("can6020_thread",
                                                   can_6020,
                                                   RT_NULL,
                                                   512,
                                                   5,
                                                   20);
            if(can6020_thread!=RT_NULL)
                                    {
                                        rt_thread_startup(can6020_thread);
                                    }else
                                    {
                                     return -1;
                                    }
}

编译–>烧录,电机轻松起转!中断成功进入!
在这里插入图片描述

注意:添加的函数需要声明,相关的头文件需要引用,跟keil用法一样。


更新一下,刚看到有人用正规做法驱动的can

RT-Thread studio开发环境下使用can

  • 7
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_45786595

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值