STM32-Arduino编程 CAN总线通信
环境说明
开发软件:vscode+PlatformIO
操作系统:win10
开发板:STM32F103C8T6
CAN总线通信模块:TJA1050
使用Arduino开发STM32原因
STM32开发比较常用的软件有Keil和STM32Cube,但是用过的同学都应该发现这两款软件对于新手不怎么友好,需要花费很长的时间才能做到入门。特别是在开发一些比较复杂的程序时,比如植入freertos,安排几个任务,能把人给折磨死。与Keil和STM32Cube相同的的是,STM32-Arduino也是采用的库函数开发,并不存在低人一等的说法。当然需要承认的是相比于寄存器开发的程序还是要差一点的。STM32-Arduino在库函数得到基础上进一步的封装,可以大大的降低程序中出现的配置出错的问题,让新手的同学可以更快的开发出高质量的STM32的程序。
直接开始操作
首先打开platformIO,创建工程。
工程名称随便,要设定好对应的开发板。我这里使用的是开发板STM32F103C8T6,至于为什么要用这个开发板,主要是因为穷。如果需要使用其他的板子,在创建工程时设定好对应的板子即可。
工程创建好之后,在Libraries中搜索TJA1050,便可以找到eXoCAN库,将其加入到STM32CAN的工程中。
eXoCAN的库中找到example文件夹中找到例程,将其中一个例程复制到main.cpp中,我复制的是bpCanBlink.ino中的例程。加入串口通信的程序将CAN总线通信的信息通过串口输出出来,最终程序如下。
#include <Arduino.h>
/*
bpCanBlink.ino 4/24/20
C:\Users\jhe\Documents\PlatformIO\mySTM32LIBS\eXoCAN\bpCanBlink.cpp
This simple example requires two STM32f103 boards. One of the boards is loaded
with the 'frame' using txMsg = 0x069. The second board gets loaded with the second
frame where tsMsgID = 0x005 by uncommenting that section.
On each board connect CAN default RX and TX pins(11,12) together. Then connect
the boards together: +5V, Gnd., and Can TX/RX.
When a board receives a CAN message it toggles its LED. One board sends a message
every second and the other every five seconds.
RAM: 904 bytes
Flash: 12988 bytes
working 4/25
*/
#include <arduino.h>
#include <eXoCAN.h>
#define bluePillLED PC13
int txMsgID = 0x069;
uint8_t txData[8]{0x00, 0x01, 0x23, 0x45, 0xab, 0xcd, 0xef, 0xff};
uint8_t txDataLen = 8;
uint32_t txDly = 5000; // mSec
int id, fltIdx;
uint8_t rxbytes[8];
eXoCAN can;
void setup()
{
Serial.begin(115200);
can.begin(STD_ID_LEN, BR250K, PORTA_11_12_WIRE_PULLUP); // 11b IDs, 250k bit rate, no transceiver chip, portA pins 11,12
can.filterMask16Init(0, 0, 0x7ff, 0, 0); // filter bank 0, filter 0: don't pass any, flt 1: pass all msgs
pinMode(bluePillLED, OUTPUT);
}
uint32_t last = 0;
void loop()
{
if (millis() / txDly != last) // tx every txDly
{
last = millis() / txDly;
can.transmit(txMsgID, txData, txDataLen);
}
if (can.receive(id, fltIdx, rxbytes) > -1) // poll for rx
{
digitalToggle(bluePillLED);
Serial.println(id);
}
}
测试硬件,两单片机的程序相同,其中TJA1050的RX接PA11,TX接PA12,不要想当然的把TJA1050接到一般的串口上。
测试结果,可见串口接收的程序将CAN总线通信的Id打印出来,而发送的Id为0x069,转成10进制便是105,与串口打印的结果一致。
下面说一下感受,CAN总线通信相比于串口通信和SPi通信是具有明显的优势的,其在构建网络的过程中不需要一个主机来进行数据的交换,但发送的数据是共享的容易出现信息的泄露。所以使用前综合考虑它的利弊。