[电工&电子] 51单片机CAN总线通讯,MCP2515模块,普中科技单片机电路板--正常模式,双机

[复制链接]
查看161 | 回复0 | 2024-7-20 16:17:44 | 显示全部楼层 |阅读模式
>

一、51单片机与MCP2515链接 

 *    P2^6 -> MCP2515_SCK     SPI时钟引脚  *    P2^5 -> MCP2515_MOSI    SPI主机输出从机输入引脚  *    P2^1 -> MCP2515_MISO    SPI主机输入从机输出引脚  *    P2^0 -> MCP2515_CS    SPI片选引脚 //MCP2515引脚定义sbit MCP2515_SCK  = P2^6;//SPI时钟引脚 sbit MCP2515_MOSI = P2^5;//SPI主机输出从机输入引脚 sbit MCP2515_MISO = P2^1;//SPI主机输入从机输出引脚 sbit MCP2515_CS   = P2^0;//SPI片选引脚  

主要目的是避开普中科技单片机P2.4 P2.3 P2.2与数码管链接的三个管脚。

配置MCP2515为CAN正常模式。

MCP2515_WriteByte(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//将MCP2515设置为正常模式,退出配置模式    temp=MCP2515_ReadByte(CANSTAT);//读取CAN状态寄存器的值  if(OPMODE_NORMAL!=(temp&0xE0))//判断MCP2515是否已经进入正常模式  {    MCP2515_WriteByte(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//再次将MCP2515设置为回环模式,退出配置模式  }

二、单片机程序

1、A单片机初始化mcp2515,设置为标准ID=0x001,标准ID为11位,既000 0000 0001,高位寄存器TXB0SIDH为0000 0000,低位寄存器TXB0SIDL为0010 0000,低位寄存器的高三位为标准ID的最低三位。

MCP2515_WriteByte(TXB0SIDH,0x00);//发送缓冲器0标准标识符高位MCP2515_WriteByte(TXB0SIDL,0x20);//发送缓冲器0标准标识符低位

滤波寄存器设置为B单片机的标准ID码,0x002,也就是说选择接受B单片机的数据。RXF0SIDH=0000 0000=0x00 RXF0SIDL=0100 0000=0x40,带颜色部分就是0x002

  MCP2515_WriteByte(RXF0SIDH,0x00);//配置验收滤波寄存器n标准标识符高位  MCP2515_WriteByte(RXF0SIDL,0x40);//配置验收滤波寄存器n标准标识符低位

屏蔽寄存器0x7ff,也就是全部检测,精确匹配。

MCP2515_WriteByte(RXM0SIDH,0xff);//配置验收屏蔽寄存器n标准标识符高位MCP2515_WriteByte(RXM0SIDL,0xe0);//配置验收屏蔽寄存器n标准标识符低位

MCP2515初始化完整程序

/******************************************************************************** 函数名  : MCP2515_Init* 描述    : MCP2515初始化配置* 输入    : 无* 输出    : 无* 返回值  : 无* 说明    : 初始化包括:软件复位、工作波特率设置、标识符相关配置等。*******************************************************************************/void MCP2515_Init(void){  unsigned char temp=0;
MCP2515_Reset(); //发送复位指令软件复位MCP2515 Delay_Nms(1); //通过软件延时约nms(不准确)
//设置波特率为125Kbps //set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=[2*(BRP+1)]/Fsoc=2*50/8M=12.5us MCP2515_WriteByte(CNF1,CAN_125Kbps); //set CNF2,SAM=0,在采样点对总线进行一次采样,PHSEG1=(2+1)TQ=3TQ,PRSEG=(0+1)TQ=1TQ MCP2515_WriteByte(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ); //set CNF3,PHSEG2=(2+1)TQ=3TQ,同时当CANCTRL.CLKEN=1时设定CLKOUT引脚为时间输出使能位 MCP2515_WriteByte(CNF3,PHSEG2_3TQ); MCP2515_WriteByte(TXB0SIDH,0x00);//发送缓冲器0标准标识符高位 MCP2515_WriteByte(TXB0SIDL,0x20);//发送缓冲器0标准标识符低位 MCP2515_WriteByte(RXB0SIDH,0x00);//清空接收缓冲器0的标准标识符高位 MCP2515_WriteByte(RXB0SIDL,0x00);//清空接收缓冲器0的标准标识符低位 MCP2515_WriteByte(RXB0CTRL,0x20);//仅仅接收标准标识符的有效信息 MCP2515_WriteByte(RXB0DLC,DLC_1);//设置接收数据的长度为8个字节 MCP2515_WriteByte(RXF0SIDH,0x00);//配置验收滤波寄存器n标准标识符高位 MCP2515_WriteByte(RXF0SIDL,0x40);//配置验收滤波寄存器n标准标识符低位// MCP2515_WriteByte(RXF1SIDH,0x02);//配置验收滤波寄存器n标准标识符高位// MCP2515_WriteByte(RXF1SIDL,0x40);//配置验收滤波寄存器n标准标识符低位 MCP2515_WriteByte(RXM0SIDH,0xff);//配置验收屏蔽寄存器n标准标识符高位 MCP2515_WriteByte(RXM0SIDL,0xe0);//配置验收屏蔽寄存器n标准标识符低位 MCP2515_WriteByte(CANINTF,0x00);//清空CAN中断标志寄存器的所有位(必须由MCU清空) //MCP2515_WriteByte(CANINTE,0x01);//配置CAN中断使能寄存器的接收缓冲器0满中断使能,其它位禁止中断 MCP2515_WriteByte(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//将MCP2515设置为正常模式,退出配置模式 temp=MCP2515_ReadByte(CANSTAT);//读取CAN状态寄存器的值 if(OPMODE_NORMAL!=(temp&0xE0))//判断MCP2515是否已经进入正常模式 { MCP2515_WriteByte(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//再次将MCP2515设置为回环模式,退出配置模式 }}

main.c完整程序,用了两个按键,分别改变第一个与第二个数据,按下任意两个之一,都发送一次数据。

/********************************************************************************** * 工程名  :MCP2515模块-标准帧例程 * 普中科技15单片机开发板+MCP2515 CAN模块 * 硬件连接:          P2^6 -> MCP2515_SCK     SPI时钟引脚  *         P2^5 -> MCP2515_MOSI    SPI主机输出从机输入引脚  *         P2^1 -> MCP2515_MISO    SPI主机输入从机输出引脚  *         P2^0 -> MCP2515_CS    SPI片选引脚 
**********************************************************************************/#include <reg52.h>#include "MCP2515.H"#define uchar unsigned char#define uint unsigned int
uchar CAN_W_Buffer[8]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07};unsigned char CAN_R_Buffer[8]={0};uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07, 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//显示0~F的值sbit key1=P3^2;sbit key2=P3^3;uchar len=0;//****************毫秒延时函数*************************void delay(uint ms){ uint j; for(;ms>0;ms--) for(j=124;j>0;j--);}/******************************************************************************** 函数名 : display* 描述 : 显示函数函数,* 输入 : dat--显示数据0-F,pos显示位置 0-7 从右到左* 输出 : 无* 返回值 : 无* 说明 : 无*******************************************************************************/void display(uchar dat,uchar pos){ P2=(P2&0xe3)+(pos<<2); P0=tab[dat]; delay(2); P0=0;}/******************************************************************************** 函数名 : main* 描述 : 主函数,用户程序从main函数开始运行* 输入 :* 输出 :* 返回值 :* 说明 :*******************************************************************************/void main(void){ MCP2515_Init(); //MCP2515初始化配置 while(1) { if(key1==0) { delay(20); if(!key1) { while(!key1); CAN_W_Buffer[0]++; CAN_Send_Buffer(CAN_W_Buffer,2);//CAN发送指定长度的数据 } } if(key2==0) { delay(20); if(!key2) { while(!key2); CAN_W_Buffer[1]++; CAN_Send_Buffer(CAN_W_Buffer,2);//CAN发送指定长度的数据 } } if(MCP2515_ReadByte(CANINTF)&0X01) { len=CAN_Receive_Buffer(CAN_R_Buffer); } display(len,7); display(CAN_R_Buffer[0]/16,1); display(CAN_R_Buffer[0]%16,0); display(CAN_R_Buffer[1]/16,3); display(CAN_R_Buffer[1]%16,2); }}

编译后下载到A单片机中。

2、B单片机

初始化mcp2515,设置为标准ID=0x002,标准ID为11位,既000 0000 0001,高位寄存器TXB0SIDH为0000 0000,低位寄存器TXB0SIDL为0100 0000,低位寄存器的高三位为标准ID的最低三位。

MCP2515_WriteByte(TXB0SIDH,0x00);//发送缓冲器0标准标识符高位MCP2515_WriteByte(TXB0SIDL,0x40);//发送缓冲器0标准标识符低位

滤波寄存器设置为A单片机的标准ID码,0x001,也就是说选择接受A单片机的数据。RXF0SIDH=0000 0000=0x00 RXF0SIDL=0010 0000=0x40,带颜色部分就是0x001

  MCP2515_WriteByte(RXF0SIDH,0x00);//配置验收滤波寄存器n标准标识符高位  MCP2515_WriteByte(RXF0SIDL,0x20);//配置验收滤波寄存器n标准标识符低位

屏蔽寄存器0x7ff,也就是全部检测,精确匹配。

MCP2515_WriteByte(RXM0SIDH,0xff);//配置验收屏蔽寄存器n标准标识符高位MCP2515_WriteByte(RXM0SIDL,0xe0);//配置验收屏蔽寄存器n标准标识符低位

MCP2515初始化完整程序

/******************************************************************************** 函数名  : MCP2515_Init* 描述    : MCP2515初始化配置* 输入    : 无* 输出    : 无* 返回值  : 无* 说明    : 初始化包括:软件复位、工作波特率设置、标识符相关配置等。*******************************************************************************/void MCP2515_Init(void){  unsigned char temp=0;
MCP2515_Reset(); //发送复位指令软件复位MCP2515 Delay_Nms(1); //通过软件延时约nms(不准确)
//设置波特率为125Kbps //set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=[2*(BRP+1)]/Fsoc=2*50/8M=12.5us MCP2515_WriteByte(CNF1,CAN_125Kbps); //set CNF2,SAM=0,在采样点对总线进行一次采样,PHSEG1=(2+1)TQ=3TQ,PRSEG=(0+1)TQ=1TQ MCP2515_WriteByte(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ); //set CNF3,PHSEG2=(2+1)TQ=3TQ,同时当CANCTRL.CLKEN=1时设定CLKOUT引脚为时间输出使能位 MCP2515_WriteByte(CNF3,PHSEG2_3TQ); MCP2515_WriteByte(TXB0SIDH,0x00);//发送缓冲器0标准标识符高位 MCP2515_WriteByte(TXB0SIDL,0x40);//发送缓冲器0标准标识符低位 MCP2515_WriteByte(RXB0SIDH,0x00);//清空接收缓冲器0的标准标识符高位 MCP2515_WriteByte(RXB0SIDL,0x00);//清空接收缓冲器0的标准标识符低位 MCP2515_WriteByte(RXB0CTRL,0x20);//仅仅接收标准标识符的有效信息 MCP2515_WriteByte(RXB0DLC,DLC_1);//设置接收数据的长度为8个字节 MCP2515_WriteByte(RXF0SIDH,0x00);//配置验收滤波寄存器n标准标识符高位 MCP2515_WriteByte(RXF0SIDL,0x20);//配置验收滤波寄存器n标准标识符低位// MCP2515_WriteByte(RXF1SIDH,0x02);//配置验收滤波寄存器n标准标识符高位// MCP2515_WriteByte(RXF1SIDL,0x40);//配置验收滤波寄存器n标准标识符低位 MCP2515_WriteByte(RXM0SIDH,0xff);//配置验收屏蔽寄存器n标准标识符高位 MCP2515_WriteByte(RXM0SIDL,0xe0);//配置验收屏蔽寄存器n标准标识符低位 MCP2515_WriteByte(CANINTF,0x00);//清空CAN中断标志寄存器的所有位(必须由MCU清空) //MCP2515_WriteByte(CANINTE,0x01);//配置CAN中断使能寄存器的接收缓冲器0满中断使能,其它位禁止中断 MCP2515_WriteByte(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//将MCP2515设置为正常模式,退出配置模式 temp=MCP2515_ReadByte(CANSTAT);//读取CAN状态寄存器的值 if(OPMODE_NORMAL!=(temp&0xE0))//判断MCP2515是否已经进入正常模式 { MCP2515_WriteByte(CANCTRL,REQOP_NORMAL|CLKOUT_ENABLED);//再次将MCP2515设置为回环模式,退出配置模式 }}

其它不变,编译后下载到B单片机中。

正确链接电路,A,B单片机分别上电,两个单片机就可以通过CAN总线通讯了。

A单片机程序:MCP2515模块-标准帧正常模式A单片机程序(STC89).rar 

B单片机程序:MCP2515模块-标准帧正常模式B单片机(STC89).rar


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则