两个Arduino 与MCP2515 CAN模块通讯实现
接线:Arduino与mcp2515模块(数据发送端和接收端接线一样),注意在这里两个J1都要短接(保证回路中有120欧姆电阻)):
Arduino与EC11旋转编码器接线(数据发送端):
Arduino | EC11 |
---|---|
D2 | CLK |
D3 | DT |
D4 | SW |
VCC | 5V |
GND | GND |
程序写入前要安装好库文件(包括使用说明):https://github.com/autowp/arduino-mcp2515
程序(数据发送端)
//定义引脚连接
#include <SPI.h>
#include <mcp2515.h>
int CLK = 2;//CLK->D2
int DT = 3;//DT->D3
int SW = 4;//SW->D4
const int interrupt0 = 0;// Interrupt 0 在 pin 2 上
int count = 0;//计数值
int lastCLK = 0;//CLK历史值
struct can_frame canMsg1;
MCP2515 mcp2515(10);
void setup()
{
pinMode(SW, INPUT);
digitalWrite(SW, HIGH);
pinMode(CLK, INPUT);
pinMode(DT, INPUT);
attachInterrupt(interrupt0, ClockChanged, CHANGE);//设置中断0的处理函数,电平变化触发
Serial.begin(9600);
SPI.begin();
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ);//波特率和晶振频率(必须有)
mcp2515.setNormalMode();
canMsg1.can_id = 0x1B500101 | CAN_EFF_FLAG;//扩展帧方式
canMsg1.can_dlc = 4;//数据位数,此程序实际只用到了2个
}
void loop()
{
if (!digitalRead(SW) && count != 0) //读取到按钮按下并且计数值不为0时把计数器清零
{
count = 0;
Serial.print("count:");
Serial.println(count);
}
if (mcp2515.readMessage(&canMsg1) == MCP2515::ERROR_OK)
{
if(canMsg1.can_id==CANID)
{
int x =canMsg1.data[0];
Serial.println(x);
}
}
delay(20);//延时必须有,不然loop程序会卡住
}
//中断处理函数
void ClockChanged()
{
int clkValue = digitalRead(CLK);//读取CLK引脚的电平
int dtValue = digitalRead(DT);//读取DT引脚的电平
if (lastCLK != clkValue)
{
lastCLK = clkValue;
count += (clkValue != dtValue ? 1 : -1);//CLK和DT不一致时+1,否则-1
Serial.print("count:");
Serial.println(count);
canMsg1.data[0] = count;
canMsg1.data[1] = 0x01;
mcp2515.sendMessage(MCP2515::TXB1,&canMsg1);
}
}
接收端程序:
#include <SPI.h>
#include <mcp2515.h>
#include <Wire.h>
struct can_frame canMsg1;
MCP2515 mcp2515(10);
void setup() {
delay(1000);
SPI.begin();
Serial.begin(9600);
mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS,MCP_8MHZ);
mcp2515.setNormalMode();
canMsg1.can_id = 0x1B500101 | CAN_EFF_FLAG;
canMsg1.can_dlc = 4;
Serial.println("------- CAN Read ----------");
Serial.println("ID DLC DATA");
}
void loop() {
if (mcp2515.readMessage(&canMsg1) == MCP2515::ERROR_OK)
{
if(canMsg1.can_id==0x1B500101 | CAN_EFF_FLAG)
{
int x =canMsg1.data[0];
int y =canMsg1.data[1];
Serial.println(x);
Serial.println(y);
delay(200);
}
}
}
此测试程序结果可通过串口监视器查看,但因后来调整过,还有待完善。