前言
本文续接上一篇文章,之前我们已经搭建好了esp32的开发环境,以及初始工程。接下来我们开始实现can驱动相关,以及使用c++封装can接口。
一、编程之前先看原理图

can转换芯片的tx与rx分别接在TWAI_TX, TWAI_RX上,再看主控部分原理图

从原理图上看到
tx --> IO2 --> GPIO_NUM_2
rx --> IO42 --> GPIO_NUM_42
二、封装can驱动
先看下我们基础工程的目录结构

我们需要创建一个新的文件夹来存放我们的can驱动(他们一般叫组件),我们在项目根目录下创建一个名为components的文件夹,创好后的目录结构如下

我们在这个components组件目录下创建一个can文件夹,用来存放我们得can驱动。
然后在can文件夹下,创建一个can.hpp的c++文件,.hpp可以把源码和声明放在一起。可以先写成下图所示

此时假如我们编译,应该是要报错,报错原因是找不到can.hpp

我们在main目录下的CMakeLists.txt中加入can.hpp的路径,便可以编译通过

接下来我们接着封装can驱动
一般来说can需要指定TX,RX两个引脚,而在我们编程阶段这两个引脚一定是写死的,因为这个时候开发板都已经出来了,can的引脚也改变不了,这非常符合常量的定义,且是编译期常量,联系到c++,说到编译期,第一个想到的关键字是constexpr,然后就是模板。因为模板的参数可以是常量,与该场景非常契合,且效率无敌。于是我们可以将can类改为模板类,如下图所示

我们接下来封装can驱动,按照基本接口来,我们应该是需要4个接口,分别是
init, read, write, deinit。
init对应构造函数,deinit对应析构函数,read从总线读取数据,write为向can总线写入数据。
我们首先来写构造函数(init),在构造函数中我们需要传入can的速率,需要有参构造。

#pragma once
#include "driver/twai.h"
template <int tx, int rx>
class Can {
private:
twai_handle_t _handler {
nullptr};
public:
explicit Can(int kbps) {
twai_general_config_t gConfig = TWAI_GENERAL_CONFIG_DEFAULT(static_cast<gpio_num_t>(tx), static_cast<gpio_num_t>(rx), TWAI_MODE_NORMAL);
twai_timing_config_t tConfig;
switch (kbps) {
case 1:
tConfig = TWAI_TIMING_CONFIG_1KBITS();
break;
case 5:
tConfig = TWAI_TIMING_CONFIG_5KBITS();
break;
case 10:
tConfig = TWAI_TIMING_CONFIG_10KBITS();
break;
case 16:
tConfig = TWAI_TIMING_CONFIG_16KBITS();
break;
case 20:
tConfig = TWAI_TIMING_CONFIG_20KBITS();
break;
case 25:
tConfig = TWAI_TIMING_CONFIG_25KBITS();
break;
case 50:
tConfig = TWAI_TIMING_CONFIG_50KBITS();
break;
case 100:
tConfig = TWAI_TIMING_CONFIG_100KBITS();
break;
case 125:
tConfig = TWAI_TIMING_CONFIG_125KBITS();
break;
case 250:
tConfig = TWAI_TIMING_CONFIG_250KBITS();
break;
case 500:
tConfig = TWAI_TIMING_CONFIG_500KBITS();
break;
case 800:
tConfig = TWAI_TIMING_CONFIG_800KBITS();
break;
case 1000:
tConfig = TWAI_TIMING_CONFIG_1MBITS();
break;
case 1024:
tConfig = TWAI_TIMING_CONFIG_1MBITS();
break;
default:
tConfig = TWAI_TIMING_CONFIG_500KBITS();
break;
}
twai_filter_config_t fConfig = TWAI_FILTER_CONFIG_ACCEPT_ALL();
ESP_ERROR_CHECK(twai_driver_install_v2(&gConfig, &tConfig, &fConfig, &_handler));
ESP_ERROR_CHECK(twai_start_v2(_handler))
1680




被折叠的 条评论
为什么被折叠?



