mcp2510的can总线收发器程序
- 格式:doc
- 大小:38.00 KB
- 文档页数:6
本文由我司收集整编,推荐下载,如有疑问,请与我司联系基于MCP2515的Linux CAN总线驱动程序设计(一)2017/06/06 0 时间:2016-12-12作者:华清远见1.前言 CAN(Controller Area Network)总线,即控制器局域网总线,是一种有效支持分布式控制或实时控制的串行通信网络。
由于其高性能、高可靠性、及独特的设计和适宜的价而广泛应用于工业现场控制、智能楼宇、医疗器械、交通工具以及传感器等领域,并已被公认为几种最有前途的现场总线之一。
CAN总线规范已经被国际标准化组织制订为国际标准ISO11898,并得到了众多半导体器件厂商的支持。
本文使用华清远见FS2416平台。
FS2416使用Socket网络设备驱动和字符设备驱动两种方式向Linux内核提供MCP2515的驱动,本文详细介绍了使用Socket方式设计的基于MCP2515的Linux CAN总线驱动程序。
2.FS2416简介 图1 FS2416开发板 FS2416采用的是三星公司的ARM926EJ内核CPU S3C2416,无论从性能上,还是成本上, S3C2416都强于2440,是2440的最完美替代者。
作为32/16 bit RISC指令集、低成本、低功耗、高性能的微处理器。
S3C2416使用了65nm的制作工艺从而降低成本、功耗及提高性能,其使用的ARM926EJ的核心,集成了2D图形加速,添加了低功耗模式,支持内部ROM/RAM引导,支持moviNand启动和低功耗音频编解码。
此外相对于其他ARM9芯片,它的外设也得到了升级,有更多的资源。
图2 FS2416板级资源介绍 3.MCP2515简介 MCP2515是一种独立的CAN总线通信控制器,是Microchip公司首批独立CAN 解决方案的升级器件,其传输能力较Microchip公司原有CAN控制器(MCP2510)高两倍,最高通信速率可达到1Mbps。
基于MCP2515的CAN总线通信模式的设计作者:戴国强常国权来源:《电脑知识与技术》2012年第10期摘要:介绍了一种基于MCP2515的CAN总线通讯模块的硬件和软件设计。
硬件部分主要可编程的CAN通讯控制器MCP2515和高速CAN收发器TJA1050组成。
软件设计包括MCP2515的初始化,数据的发送和接收三部分。
该模块采用SPI接口,显著减少了系统的连线,简化了系统设计。
它具有较高的抗干扰能力。
关键词:CAN总线通信;MCP2515;单片机;SPI中图分类号:TP393.1文献标识码:A文章编号:1009-3044(2012)10-2409-03Design of CAN Bus Communication Module Based on MCP2515DAI Guo-qiang, CHANG Guo-quan(Department of Computer and Information, AnYang Technology University, Anyang 45500, China)Abstract: This paper expounds the design of hardware and software of CAN bus communication module based on MCP2515.The part of hardware mainly consisted with MCP2515 stand-alone CAN controller and TJA1050 high speed CAN transceiver.The design of software included initial ofMCP2515,the sending and receiving of data.This module used SPI interface to the controller, thus obviously reduced the line of a system ,and simplified system design.It had high antijamming capability.Key words: CAN bus communication; MCP2515 ; microcontroller; SPI1CAN是一种高性能、高可靠的串行通信协议在工业自动化、船舶、医疗设备和工业设备等方面得到广泛的应用。
MCP2510与F149的SPI接口的CAN实现程序转载利尔达作者:goblin1//operating SPI PORTS --CAN#include "msp430x14x.h"#include "foshan.h"uchar Data[20];uchar i=0,rx_data;unsigned long int P=1;/***********************初始化****************************/void init_spi(void){int i;WDTCTL = WDTPW + WDTHOLD; //off watchdog/*设置主时钟为TX2-------------*/do{IFG1 &=~OFIFG; //清OFIFG中断for (i = 0xff; i>0; i--);}while ((IFG1 & OFIFG) != 0);BCSCTL1 &= ~XT2OFF;BCSCTL2 |= (SELM1 + SELS); // 0x80|0x08|0x02 mclk=8 MHz/*SPI-x0 初始化--------------*/UCTL0 &=~ SWRST; //starting USART1_initUCTL0 |= CHAR+SYNC+MM; //spi主模式,8位数据UTCTL0 = STC + SSEL1 + SSEL0 + CKPL;// + CKPH; //3线模式,选SMCLK时钟UBR00 = 0x08; //1MHz @ 8MHzUBR10 = 0x00;UMCTL0 = 0x00;ME1 |= USPIE0; //SPI模块允许P3SEL |= 0x0F; //active P3.0 & P3.3 for SPIP3DIR |= 0x0A; //P3.1(SIMO)& P3.3(UCLK)//UCTL0 &=~SWRST; //endding USART0_initIE1 &=~ URXIE0; //IE1 |= URXIE0; //接收中断允许UCTL0 &=~ SWRST;}/*--------------------读数据指令---------------------------*/void r_cmd(uchar add,uchar d_long){uchar ii;TXBUF0=0x03; //0x03;while (!(UTCTL0 & TXEPT));TXBUF0=add;while (!(UTCTL0 & TXEPT));for (ii=0;ii {TXBUF0=0;while (!(UTCTL0 & TXEPT));//判断发送数据完成//while (!(IFG1 & URXIFG0));//判断接收数据到位Data[ii]=RXBUF0;}P2OUT |= BIT0;}/*--------------------写数据指令---------------------------*/ void w_cmd(uchar add,uchar data,uchar d_long){uchar ii;P2OUT &=~ BIT0;TXBUF0=0x02;while (!(UTCTL0 & TXEPT));TXBUF0=add;while (!(UTCTL0 & TXEPT));for (ii=0;ii {TXBUF0=data;while (!(UTCTL0 & TXEPT));}P2OUT |= BIT0;}/*--------------------开始发送指令-------------------------*/ void t_cmd(void){P2OUT &=~ BIT0;TXBUF0 = 0x81;while (!(UTCTL0 & TXEPT));P2OUT = BIT0;}//---------------------------//////void init_can(void);/*-----------------------MAIN-----------------------------*/void main(void){_EINT();P2SEL = 0x00;P2DIR = 0x01;P2OUT = 0xFF;init_can();w_cmd(0x31,0xaa,13);w_cmd(0x35,0x08,1);t_cmd();while(1){r_cmd(0x60,0x0f);//r_cmd(0x00);}while(1);}/*------------------CAN初始化---------------------*/void init_can(void){w_cmd(0x0f,0x80,0x01); //80配置模式//发送------------w_cmd(0x2a,0x00,0x01); //CNF1w_cmd(0x29,0xf1,0x01); //CNF2 位时序w_cmd(0x28,0x05,0x01); //CNF3w_cmd(0x0d,0x07,0x01); //芯片发送引脚使能设置//接受------------w_cmd(0x60,0x60,0x01); //0x60关闭屏蔽和滤波,接受所有报文,0x00正常屏蔽滤波w_cmd(0x0c,0x00,0x01); //接收引脚控制使能w_cmd(0x2b,0x00,0x01); //中断使能w_cmd(0x2c,0x00,0x01); //中断标志w_cmd(0x0f,0x40,0x01); //0正常模式,80配置,40环回}---------------------------------------------------------------------------------------------这个是调试通过了的SPI & CAN2510全部完整程序了,初始化430的SPI、2510,读指令、写指令、发送指令(读、写都可以一次发送N 条,因为2510有连续操作的能力)/*--------------------写数据指令---------------------------*/void w_cmd(uchar add,uchar data,uchar d_long)变量 d_long 就是长度(读指令相同)我用了光藕的,不用光藕直接连接应该没问题,2510的工作电压可以到5V ,所以可以直接用。
模拟SPI口实现对CAN控制器mcp2515的操作程序(2009-06-18 11:33:20)标签:can总线mcp2515参考程序it#include "2515.h"#include "SPI.h"#include "reg51.h"#include "Function.h"#define CAN_10Kbps 0x31#define CAN_25Kbps 0x13#define CAN_50Kbps 0x09#define CAN_100Kbps 0x04#define CAN_125Kbps 0x03#define CAN_250Kbps 0x01#define CAN_500Kbps 0x00//void SPIReset(void);//void SPIByteWrite(unsigned char ,unsigned char );//unsigned char SPIByteRead(unsigned char );unsigned char dummy;void Init2515(unsigned int IDF){SPIReset();delay_ms(1);//SPIByteWrite(CANCTRL,0x80);//CAN工作在配置模式SPIByteWrite(RXM0SIDH,0x00);SPIByteWrite(RXM0SIDL,0x00);SPIByteWrite(RXF0SIDH,0x00);SPIByteWrite(RXF0SIDL,0x00);SPIByteWrite(RXM1SIDH,0x00);SPIByteWrite(RXM1SIDL,0x00);SPIByteWrite(RXF2SIDH,0x00);SPIByteWrite(RXF2SIDL,0x00);//设置波特率为10Kbps//set CNF1,SJW=00,长度为1TQ,BRP=49,TQ=[2*(BRP+1)]/Fsoc=2*50/8M=12.5usSPIByteWrite(CNF1,CAN_125Kbps);//set CNF2,SAM=0,在采样点对总线进行一次采样,PHSEG1=(2+1)TQ=3TQ,PRSEG=(0+1)TQ=1TQSPIByteWrite(CNF2,0x80|PHSEG1_3TQ|PRSEG_1TQ);//set CNF3,PHSEG2=(2+1)TQ=3TQ,同时当CANCTRL.CLKEN=1时设定CLKOUT引脚为时间输出使能位SPIByteWrite(CNF3,PHSEG2_3TQ);//set TXB0,设置发送缓冲器0的标识符和发送的数据,以及发送的数据长度SPIByteWrite(TXB0CTRL,0x03);//设置发送缓冲器0控制寄存器清零TXREQ,发送优先级最高//BitModiMcp2515(TXB0CTRL,0x08,0x00);SPIByteWrite(TXB0SIDH,IDF);//设置发送缓冲器0的标准标识符,待修改***SPIByteWrite(TXB0SIDL,0xE0);//用到标准标识符SPIByteWrite(TXB0DLC,DLC_8);//设置发送数据的长度为8个字节//SPIByteWrite(TXB0D0,0x1E);//有待修改及确定是否使用//SPIByteWrite(TXB0D1,0x10);//有待修改及确定是否使用//设置接收缓冲器0的标识符和初始化数据//SPIByteWrite(RXB0SIDH,0x55);//设置接收缓冲器0的标准标识符,待修改***//SPIByteWrite(RXB0SIDL,0xE0);//用到标准标识符SPIByteWrite(RXB0CTRL,0x20);//仅仅接收标准标识符的有效信息,FIILHIT0=0表示RXB0 ,采用FILHIT0SPIByteWrite(RXB0DLC,DLC_8);//设置接收数据的长度为8个字节SPIByteWrite(RXF0SIDH,0xE0);//初始化接收滤波器0,待修改***SPIByteWrite(RXF0SIDL,0xE0);SPIByteWrite(RXM0SIDH,0xFF);//初始化接收屏蔽器0,待修改***SPIByteWrite(RXM0SIDL,0xE0);//设置接收缓冲器1的标识符和初始化数据//SPIByteWrite(RXB1SIDH,IDF); //设置接收缓冲器0的标准标识符,待修改***//SPIByteWrite(RXB1SIDL,0xE0);//用到标准标识符SPIByteWrite(RXB1CTRL,0x20);//仅仅接收标准标识符的有效信息,FIILHIT0=0表示RXB0 ,采用FILHIT0SPIByteWrite(RXB1DLC,DLC_8);//设置接收数据的长度为8个字节SPIByteWrite(RXF2SIDH,0x00);//初始化接收滤波器2,待修改***SPIByteWrite(RXF2SIDL,0xE0);SPIByteWrite(RXF3SIDH,0x01);//初始化接收滤波器3,待修改***SPIByteWrite(RXF3SIDL,0xE0);SPIByteWrite(RXF4SIDH,0x02);//初始化接收滤波器4,待修改***SPIByteWrite(RXF4SIDL,0xE0);SPIByteWrite(RXF5SIDH,0x56);//初始化接收滤波器5,待修改***SPIByteWrite(RXF5SIDL,0xE0);SPIByteWrite(RXM1SIDH,0xFF);//初始化接收屏蔽器1,待修改***SPIByteWrite(RXM1SIDL,0xE0);//设置接收缓冲器0中断SPIByteWrite(CANINTF,0x00);//接收完一次必须对中断标志位清0SPIByteWrite(CANINTE,0x02);//接收缓冲器0满中断使能位***修改成01-02//设置单触发模式1 使能,报文尝试发送一次;0禁止。
基于MCP2515的CAN总线控制软件的设计与实现作者:孙龙刘晖虎来源:《现代信息科技》2018年第07期摘要:控制器局域网络(Controller Area Network,CAN)在汽车、工业控制、航空等嵌入式系统开发中得到了广泛的应用。
为确保其通信功能及接口实现的正确性,需进行有针对性地测试。
为了提高软件测试过程中CAN总线接口测试的效率和质量,本文设计和开发了基于CAN总线控制器MCP2515的CAN总线控制软件,以实现测试过程中对CAN总线收发数据的模拟和监视。
关键词:软件测试;CAN总线;传输层;应用层中图分类号:TP273 文献标识码:A 文章编号:2096-4706(2018)07-0001-05Abstract:The Controller Area Network is widely used in the development of embedded systems,such as automobile,industrial control,aviation and so on. For the correctness of its communication function and interface implementation,it needs to be tested pertinent. In order to improve the efficiency and quality of CAN bus interface test in software testing,a CAN bus control software based on CAN bus controller MCP2515 is designed and developed to realize the simulation and monitoring of CAN bus and receive data in the test process.Keywords:software tests;CAN bus;transport layer;application layer1 MCP2515概述MCP2515是一款独立CAN控制器,能够简化需要与CAN总线连接的应用。
mcp2510的can总线收发器程序pcbomb发表于2008-6-30 14:47:00 阅读全文(769) |回复(1) |引用通告(0) |编辑#i nclude <stdio.h>#i nclude "mcp2510.h" void mcp_reset(void){SPI_init_hw(); //设置成SPI方式init_can」o(); //SPI_mcp_reset(); //void mcp_read( unsigned char MCPaddr, unsigned char* readdata, unsigned char length ) {unsigned char loopCnt;SPI_mcp_select(); // Select the MCP device at the SPI bus// Start reading and set first addressSPI_mcp_RD_address(MCPaddr);for (loopCnt=0; loopCnt < length; loopCnt++){// Get a byte and store at pointer*readdata = SPI_putch(MCPaddr);// Increment the pointers to next location// Test++;MCPadd 叶+;readdata++;}SPI_mcp_unselect();} void mcp_write( unsigned char MCPaddr, unsigned char* writedata, unsigned char length ) { unsigned char loopCnt;SPI_mcp_select();// Start write and set first addressSPI_mcp_WR_address( MCPaddr );for (loopCnt=0; loopCnt < length; loopCnt++){// Write a byteSPI_putch( *writedata );// Increment the pointer to next location writedata++;SPI_mcp_unselect();*********unsigned char mcp_transmit_busy(unsigned send_buf) {unsigned char temp;switch(send_buf){case 0:{temp=SPI_mcp_RD_status();〃if(temp&0x04){return 1;}return 0;break;}case 1:{temp=SPI_mcp_RD_status();〃if(temp&0x10){return 1;}return 0;break;}case 2:{temp=SPI_mcp_RD_status();〃if(temp&0 x40){return 1;}return 0;break;}}} 读取当前的MCP251C发送状态读取当前的MCP251C发送状态读取当前的MCP251C发送状态************发送数据*********************************************************************** ******************************void mcp_transmit(unsigned char mcp_addr)。
基于MCP2510的CAN总线应用及故障判定
周学文
【期刊名称】《测控技术》
【年(卷),期】2014(033)008
【摘要】对CAN总线进行了简要介绍,阐述了CAN总线控制器在设计使用过程中的注意事项、PIC16F876A处理器与MCP2510的连接管理和利用CAN控制器的不同工作模式进行初始化、自动通信检验,同时设计了RS232转CAN总线的电路,并给出了电路图,列举了MCP2510 CAN总线控制器、82C250总线收发器的在线故障判断和检修策略.
【总页数】4页(P99-102)
【作者】周学文
【作者单位】中国燃气涡轮研究院,四川江油621703
【正文语种】中文
【中图分类】TP277
【相关文献】
1.基于Mega8单片机与MCP2510的CAN总线接口设计 [J], 骆舒萍
2.基于MCP2510的CAN总线分析仪的实现 [J], 李玉龙;田野;刘桥
3.基于MCP2510的CAN总线在ESP远程监控系统中的应用 [J], 林金亮;赖月华
4.基于S3C44B0X和MCP2510的CAN总线接口的实现 [J], 高建华;李红光;陈帅
5.基于单片机和MCP2510的CAN总线通信模块的设计 [J], 张景元;杨庆华
因版权原因,仅展示原文概要,查看原文内容请购买。
MCP2510的主要特点如下:●支持CANV2.0A/B;●具有SPI接口,支持SPI模式0,0和1,1;●内含3个发送缓冲器和2个接收缓冲器,可对其优先权进行编程;●具有6个接收滤波器,2个接收滤波器屏蔽;●具有灵活的中断管理能力;●采用低拉功耗CMOS工艺技术,其工作电压范围为3.0~5.5V;有效电流为5mA,维持电流为10μA;●工作温度范围为-40~+125℃。
2 管理功能MCP2510有PDIP、SOIC和TSSOP三种封装形式,有18个引脚。
图1为18脚PDIP封装形式,有18个引脚。
图1为18脚PDP封装MCP2510的引脚排列图。
表1所列是各引脚功能的详细描述。
表1 MCP2510的引脚功能引脚名称功能1 TXCAN 去CAN总线的发送输出引脚2 RXCAN 来自CAN总线的接收输入引脚3 CLKOUT 具有可编程预分频的时钟输出引脚456 TX0RTSTX1RTSTX2RTS 发送缓冲器发送请求端,或作数字输入端78 OSC2OSC1 振荡器输出端、输入端9 Vss 地端1011 RX1BFRX0BF 接收缓冲器中断引脚,或作数字输出端12 INT 中断输出引脚13 SCK SPI接口的时钟输入端14 SI SPI接口的数据输入端15 SO SPI接口的数据输出端16 CS SPI接口的片选输入端17 RESET 复位端18 VDD 电源端3 结构及工作原理图2是MCP2510的内部结构框图,其中CAN协议机负责与CAN总线的接口,SPI接口逻辑用于实现同MCU的通讯,而寄存、缓冲器组与控制逻辑则用来完成各种方式的设定和操作控制。
现结合其工作过程将各部分的功能、原理作一介绍。
3.1 收发操作MCP2510的发送操作通过三个发送缓冲器来实现。
这三个发送缓冲器各占据14个字节的SRAM。
第一字节是控制寄存器TXBNCTRL,该寄存器里的内容设定了信息发送的条件,且给出了信息的发送状态;第二至第六字节用来存放标准的和扩展的标识符以及仲裁信息;最后八个字节则用来存放待发送的数据信息。
利用MCP2515的多路CAN总线接口及驱动程序设计结合实际需求,提出一种多路CAN总线接口的设计方法。
系统硬件主体采用AT91RM9200和MCP2515,操作系统采用ARMLinux。
详细介绍硬件的接口设计,针对该硬件接口设计分析ARMLinux下的驱动程序的设计方法,并对驱动程序实现过程中需要注意的问题进行了深入分析。
经过测试,该设计方案可以满足应用的要求。
关键词AT91RM9200 MCP2515 ARM-Linux CAN SPI 驱动程序引言在铁路系统中,为了保证列车的安全运行,需要对铁轨及周围状况进行实时检测。
目前采用的方法是在铁路沿线安装多个检测设备,用于检测洪水、大风、泥石流等自然灾害及轨温等参数。
这些设备一般采用的通信方式是RS232、RS485或CAN,并通过专线连接至监控中心的各个监控设备。
这种方式极大浪费了线路资源,也不易于设备的统一管理。
因此,需要一种安装在铁路沿线的设备,它将附近的检测设备发送的信息统一收集并通过一条专线直接送往监控中心。
为了与多个检测设备通信,必须同时具有多个RS232、RS485和CAN接口。
基于这种应用需要,本文提出了扩展多个CAN总线接口的方法。
1 系统结构1.1 芯片介绍系统采用Atmel公司的AT91RM9200(以下简称“9200”)作为MCU。
该处理器基于ARM920T内核,主频为180 MHz时,性能可达到200MIPS;最高主频为209 MHz。
该处理器还具有丰富的外设资源,非常适合工业控制领域的应用[1];采用的操作系统是ARMLinux,内核版本为2.4.19。
目前主流的CAN协议控制器一般采用I/O总线(SJA1000等)或SPI接口(MCP2515等)与MCU 进行通信。
由于本设计采用PC/104总线扩展卡的方式来扩展多个RS232和RS485接口,没有多余的I/O 片选线可用,因此最终选用9200的SPI接口与MCP2515进行多路CAN总线接口的扩展。
基于VxWorks的SPI接口芯片MCP2510的驱动程序设计谷新尧,梁作生中国矿业大学信息与电气工程学院,徐州(221008)E-mail:guxinyaoguxinlei@摘要:本文结合具体的网关设备KT700介绍了基于VxWorks 的SPI接口芯片MCP2510的驱动程序设计,并给出了部分驱动程序的核心代码。
本设备驱动程序编写的思路严格按照VxWorks 下设备驱动程序的要求, 对其它基于VxWorks 的设备驱动有很强的参考意义。
关键词:VxWorks;SPI;网关 CAN1. 前言目前, 嵌入式系统的开发已经离不开操作系统的支持, 而开发基于嵌入式操作系统的底层硬件驱动程序是研发中必不可少的工作之一。
VxWorks 是美国WindRiver公司推出的一个层次化分明的嵌入式实时操作系统(RTOS),每层各负其责,层与层之间又紧密相连。
我们要编写的驱动程序属于底层的范畴,而用户的应用程序则属于上层,它们中间还分有很多层次,而这些中间层无需开发,由VxWorks 进行维护和管理。
这样, 操作系统把各层有机地连接在一起,使代码紧凑而高效。
2. VxWorks的I/O系统与设备驱动编写带有SPI接口的MCP2510芯片完成的CAN设备驱动程序之前, 应该明确VxWorks 的I/ O 系统和设备驱动结构。
图1即VxWorks I/ O 系统层次结构。
图中最底层就是我们要编写的MCP2510芯片的驱动程序。
它作为I/O系统和硬件设备之间的连接层的作用就是屏蔽硬件操作,为I/O系统提供服务。
VxWorks 的I/ O 系统向上提供了7个统一的I/ O 接口,供应用程序调用。
向下通过ttyDrv和TyLib提供与各种字符设备驱动程序的接口。
I/ O 系统把应用程序跟驱动程序有机地连接起来。
最顶层的应用程序通过统一的I/O接口对底层的硬件进行操作。
与UNIX 类似,VxWorks所有的I/ O 设备都被当作文件来存取。
mcp2510的can总线收发器程序pcbomb 发表于 2008-6-30 14:47:00 阅读全文(769) | 回复(1) | 引用通告(0) | 编辑#i nclude <stdio.h>#i nclude "mcp2510.h"void mcp_reset(void){SPI_init_hw(); //设置成SPI方式init_can_io(); //SPI_mcp_reset(); //}void mcp_read( unsigned char MCPaddr, unsigned char* readdata, unsigned char length ) {unsigned char loopCnt;SPI_mcp_select(); // Select the MCP device at the SPI bus// Start reading and set first addressSPI_mcp_RD_address(MCPaddr);for (loopCnt=0; loopCnt < length; loopCnt++){// Get a byte and store at pointer*readdata = SPI_putch(MCPaddr);// Increment the pointers to next location// Test++;MCPaddr++;readdata++;}SPI_mcp_unselect();}void mcp_write( unsigned char MCPaddr, unsigned char* writedata, unsigned char length ) {unsigned char loopCnt;SPI_mcp_select();// Start write and set first addressSPI_mcp_WR_address( MCPaddr );for (loopCnt=0; loopCnt < length; loopCnt++){// Write a byteSPI_putch( *writedata );// Increment the pointer to next locationwritedata++;}SPI_mcp_unselect();}void mcp_read_can_id( unsigned char mcp_addr, unsigned char* ext, unsigned long* can_id ) {unsigned char tbufdata[4];*ext = 0;*can_id = 0;mcp_read( mcp_addr, tbufdata, 4);*can_id = (tbufdata[SIDH]<<3) + (tbufdata[SIDL]>>5);if ( (tbufdata[SIDL] & TXB_EXIDE_M) == TXB_EXIDE_M ){*can_id = (*can_id<<2) + (tbufdata[SIDL] & 0x03);*can_id <<= 16;*can_id = *can_id +(tbufdata[EID8]<<8) + tbufdata[EID0];*ext = 1;}}/******************************************************************************************* ************buffer:0-1******************************************************************************************** ***********/void mcp_read_can( unsigned char buffer, unsigned char* ext, unsigned long* can_id,unsigned char* dlc, unsigned char* rtr, unsigned char* data ){unsigned char mcp_addr = buffer*16 + 0x61, ctrl;mcp_read_can_id( mcp_addr, ext, can_id );mcp_read( mcp_addr-1, &ctrl, 1 );mcp_read( mcp_addr+4, dlc, 1 );if (/*(*dlc & RTR_MASK) || */(ctrl & 0x08)){*rtr = 1;}else{*rtr = 0;}*dlc &= DLC_MASK;mcp_read( mcp_addr+5, data, *dlc );}void mcp_write_can_id( unsigned char mcp_addr, unsigned char ext, unsigned long can_id ){unsigned int canid;unsigned char tbufdata[4];canid = (unsigned int)(can_id & 0x0FFFF);if ( ext == 1){tbufdata[EID0] = (unsigned char) (canid & 0xFF);tbufdata[EID8] = (unsigned char) (canid / 256);canid = (unsigned int)( can_id / 0x10000 );tbufdata[SIDL] = (unsigned char) (canid & 0x03);tbufdata[SIDL] += (unsigned char) ((canid & 0x1C )*8);tbufdata[SIDL] |= TXB_EXIDE_M;tbufdata[SIDH] = (unsigned char) (canid / 32 );}else{tbufdata[SIDH] = (unsigned char) (canid / 8 );tbufdata[SIDL] = (unsigned char) ((canid & 0x07 )*32);tbufdata[EID0] = 0;tbufdata[EID8] = 0;}mcp_write( mcp_addr, tbufdata, 4 );}/******************************************************************************************* ************buffer:0-2******************************************************************************************** ***********/void mcp_write_can( unsigned char buffer, unsigned char ext, unsigned long can_id,unsigned char dlc, unsigned char rtr, unsigned char* data ){unsigned char mcp_addr = buffer*16 + 0x31;mcp_write(mcp_addr+5, data, dlc ); // write data bytesmcp_write_can_id( mcp_addr, ext, can_id ); // write CAN idif ( rtr == 1){dlc |= RTR_MASK; // if RTR set bit in byte}mcp_write((mcp_addr+4), &dlc, 1 ); // write the RTR and DLC}/******************************************************************************************* ************检测是否发送完毕,是否已经可以进行发送*******************************************************************************************************/unsigned char mcp_transmit_busy(unsigned send_buf){unsigned char temp;switch(send_buf){case 0:{temp=SPI_mcp_RD_status();//读取当前的MCP2510发送状态if(temp&0x04){return 1;}return 0;break;}case 1:{temp=SPI_mcp_RD_status();//读取当前的MCP2510发送状态if(temp&0x10){return 1;}return 0;break;}case 2:{temp=SPI_mcp_RD_status();//读取当前的MCP2510发送状态if(temp&0x40){return 1;}return 0;break;}}}/******************************************************************************************* ************发送数据******************************************************************************************** ***********/void mcp_transmit(unsigned char mcp_addr){SPI_mcp_write_bits(mcp_addr, TXB_TXREQ_M, TXB_TXREQ_M);}#include "spi_mcp.h"void SPI_mcp_select (void){CAN_CS_c;}void SPI_mcp_unselect (void){CAN_CS_s;}void SPI_mcp_reset ( void ){SPI_mcp_select();SPI_putch(RESET);SPI_mcp_unselect();}void SPI_mcp_RD_address(unsigned char output){unsigned char store;CAN_CS_c;store = SPI_putch( READ ); // Write the command// store = SPI_putch( 0x00 ); // Write high byte in address store = SPI_putch( output ); // Write low byte in address }unsigned char SPI_mcp_RD_data(unsigned char output){unsigned char store;CAN_CS_c;store = SPI_putch( READ ); // Write the command// store = SPI_putch( 0x00 ); // Write high byte in address store = SPI_putch( output ); // Write low byte in address store = SPI_putch( output ); // Write low byte in address CAN_CS_s;return store;}void SPI_mcp_WR_address(unsigned char output){unsigned char store;CAN_CS_c;store = SPI_putch( WRITE ); // Write the command// store = SPI_putch( 0x00 ); // Write high byte in address store = SPI_putch( output ); // Write low byte in address }void SPI_mcp_WR_data(unsigned char output,unsigned char data){unsigned char store;CAN_CS_c;store = SPI_putch( WRITE ); // Write the command// store = SPI_putch( 0x00 ); // Write high byte in address store = SPI_putch( output ); // Write low byte in address store = SPI_putch( data );CAN_CS_s;}unsigned char SPI_mcp_RD_status ( void ){unsigned char store;CAN_CS_c;store = SPI_putch( RD_STAT ); // Write the commandstore = SPI_putch( RD_STAT ); // Write any byte to get a byte in returnCAN_CS_s;return store; // Command done OK}unsigned char SPI_mcp_RD_RX_STAT ( void ){unsigned char store;CAN_CS_c;store = SPI_putch( RD_RX_STAT ); // Write the commandstore = SPI_putch( RD_RX_STAT ); // Write any byte to get a byte in return CAN_CS_s;return store; // Command done OK}void SPI_mcp_write_bits( unsigned char MCPaddr, unsigned char data, unsigned char mask ) {CAN_CS_c;SPI_putch( BIT_MOD );SPI_putch( MCPaddr );SPI_putch( mask );SPI_putch( data );CAN_CS_s;}。