CAN单节点的自通信程序
- 格式:doc
- 大小:54.00 KB
- 文档页数:9
CAN总线通讯基于51单片机应用第一章前言1.1 概述控制器局域网(CAN-Controller Area Network)属于现场总线(Fieldbus)的范畴,是众多的属于现场总线标准之一,它适用于工业控制系统,具有通信速率高、可靠性强、连接方便、性能价格比高等诸多特点。
它是一种有效支持分布式控制或实时控制的串行通信网络,以其短报文帧及CSMA/CD-AMP(带有信息优先权及冲突检测的载波监听多路访问)的MAC(媒介访问控制)方式而倍受工业自动化领域中设备互连的厚爱。
CAN的应用范围遍及从高速网络到低成本的多线路网络,它可以应用于汽车系统、机械、技术设备和工业自动化里几乎任何类型的数据通信。
随着计算机硬件、软件及集成电路技术的迅速发展,同时消费类电子产品、计算机外设、汽车和工业应用等的需求不断增加。
高速、高可靠和低成本的通信介质的要求也随之提高。
现场总线是当今自动化领域技术发展的热点之一,它为分布式控制系统实现各节点之间实时、可靠的数据通信提供了强有力的技术支持。
微处理器中常用的串行总线是通用异步接收器传输总线(UART)、串行通信接口(SCI)、同步外设接口(SPI)、内部集成电路(I2C)和通用串行总线(USB),以及车用串行总线,包括控制器区域网(CAN)和本地互连网(LIN)等。
这些总线在速度、物理接口要求和通信方法学上都有所不同。
在计算机数据传输领域内,长期以来使用的通信标准,尽管被广泛使用,但是无法在需要使用大量的传感器和控制器的复杂或大规模的环境中使用。
控制器局部网CAN(CONTROLLER AERANETW0RK)就是为适应这种需要而发展起来的。
随着汽车电子技术的发展,消费者对于汽车功能的要求越来越多,汽车上所用的电控单元不断增多,电控单元之间信息交换的需求,使得电子装置之间的通讯越来越复杂,同时意味着需要更多的连接信号线,这就促进了车用总线技术的发展。
CAN 总线的出现,就是为了减少不断增加的信号线,所有的外围器件都可以被连接到总线上由于CAN总线具有可靠性高、实时性好、成本合理等优点,逐渐被应用于如船舶、航天、工业测控、自动化、电力系统、楼宇监控等其他领域中。
can通信流程CAN(Controller Area Network)是一种先进的实时通信协议,广泛应用于汽车、工业控制和航空领域等。
下面将详细介绍CAN通信的工作原理和通信流程。
CAN通信是基于多主/多从的总线式通信系统,由控制器、传感器、执行器等节点组成。
每个节点都通过CAN控制器与总线相连接,通过CAN 总线进行信息的传递和交互。
CAN通信的基本流程如下:1.初始化:系统上电后,每个节点的CAN控制器需要进行初始化,包括设置CAN总线的工作模式、波特率以及接收和发送缓冲区等。
2.确定通信参数:各节点需要约定通信的ID、数据格式、信息长度等通信参数,以确保节点之间的信息交互是有效的。
3.发送数据:节点通过CAN控制器将要发送的数据封装成CAN帧,并通过CAN总线发送出去。
CAN帧包括帧起始位、ID、数据、帧检验位等。
4.接收数据:其他节点通过CAN控制器监听总线上的CAN帧,当有CAN帧到达时,进行接收。
每个节点通过识别CAN帧的ID来判断是否是自己所需要的数据,如果是,则进行数据解析,否则将其丢弃。
5.确认发送:发送节点接收到其他节点发送的数据后,会发送一个确认帧,表示自己已经成功接收到该数据。
6.错误处理:CAN总线具有自动差错检测和纠错能力,如果在通信过程中出现了错误,例如数据丢失、位错误等,节点会根据错误类型进行纠正或重新发送。
总的来说,CAN通信的流程是通过CAN控制器进行数据的封装、发送和解析,节点之间通过CAN总线进行数据的传递和交互。
每个节点根据CAN帧的ID来判断是否需要接收数据,并对接收到的数据进行解析和处理。
通过不断的发送、接收和确认,实现节点之间的实时通信。
CAN通信具有高可靠性、高带宽、抗干扰等特点,适用于多节点、多任务的控制系统。
在汽车领域中,CAN通信可以实现车载电子控制单元(ECU)之间的信息交换,提高汽车的安全性和可靠性。
而在工业控制领域,CAN通信可以连接分散的传感器和执行器,实现实时的数据交互和控制。
竭诚为您提供优质文档/双击可除can总线常用通信协议篇一:史上最全can总线协议规则一、can总线简介can是控制器局域网络(controllerareanetwork,can)的简称,是由研发和生产汽车电子产品著称的德国bosch公司开发了的,并最终成为国际标准(iso11898)。
是国际上应用最广泛的现场总线之一。
在建立之初,can总线就定位于汽车内部的现场总线,具有传输速度快、可靠性高、灵活性强等优点。
上世纪90年代can总线开始在汽车电子行业内逐步推广,目前已成为汽车电子行业首选的通信协议,并且在医疗设备、工业生产、楼宇设施、交通运输等领域中取得了广泛的应用。
二、can总线技术及其规范2.1性能特点(1)数据通信没有主从之分,任意一个节点可以向任何其他(一个或多个)节点发起数据通信,通信方式灵活,且无需站地址等节点信息;(2)can网络上的节点信息分成不停的优先级,可满足不同的实时要求,高优先级节点信息最快可在134μs内得到传输;(3)采用非破坏性总线仲裁技术,当多个节点同时向总线发送信息时,优先级较低的节点会主动退出发送,而高优先级的节点可不受影响的继续发送数据,从而大大节省了总线冲突仲裁时间。
尤其是在网络负载很重的情况下也不会出现网络瘫痪的情况;(3)通信距离最远可达10km(速率低于5kbps)速率可达到1mbps(通信距离小于40m);(4)通信的硬件接口简单,通信线少,传输介质可以是双绞线,同轴电缆或光缆。
can总线适用于大数据量短距离通信或者长距离小数据量,实时性要求比较高,多主多从或者各个节点平等的现场中使用。
(5)采用短帧结构,传输时间短,受干扰概率低,每帧信息都有cRc校验及其他检验措施,数据出错率极低;(6)节点在严重错误的情况下具有自动关闭输出的功能,以使总线上其他节点的操作不受影响。
(7)can总线使用两根信号线上的差分电压传递信号,显性电平可以覆盖隐形电平。
2.2技术规范2.2.1can的分层结构图1can的分层结构逻辑链路控制子层(llc)的功能:为数据传送和远程数据请求提供服务,确认由llc子层接收的报文实际上已被接收,为恢复管理和通知超载提供信息。
单片机CAN通信发送与接收实例一、概述在现代的自动化控制系统中,通信技术起着至关重要的作用。
CAN (Controller Area Network)总线作为一种先进的数据通信协议,被广泛应用于汽车、工业控制、航天以及其他领域。
本文将介绍基于单片机的CAN通信发送与接收实例,以供读者学习和参考。
二、CAN通信原理1. CAN通信特点1.1 高可靠性:CAN总线采用冗余校验以及非常靠谱的错误处理机制,提高了整个系统的可靠性。
1.2 高实时性:CAN总线的通信速度非常快,延迟时间短,适合高实时性的通信需求。
1.3 多主机系统:CAN总线支持多主机系统工作,适合网络化控制系统的需要。
2. CAN通信结构CAN通信的结构包含以下三个重要部分:物理层、数据链路层和应用层。
物理层负责数据的物理传输,数据链路层包括帧的发送和接收,而应用层则是用户数据和应用信息的处理。
三、CAN通信的硬件设计1. CAN总线控制器单片机需要带有CAN总线控制器才能进行CAN通信,常见的单片机型号包括AT89C51、ATmega16等。
2. CAN收发器CAN总线收发器用于将单片机的数字信号转换为CAN总线能够接受的电压信号,并将CAN总线的电压信号转换为单片机能够接受的数字信号。
3. 连接线路连接线路需要根据CAN总线的规范进行设计,要求信号线和接地线布局合理、阻抗匹配以及电气特性良好。
四、CAN通信的软件设计1. CAN总线初始化在进行CAN通信之前,需要对CAN总线进行初始化,包括波特率的设定、模式的选择以及滤波器的配置等。
2. 数据发送单片机通过CAN总线控制器将数据发送到CAN总线上的其他节点,发送数据时需要注意数据格式、ID的选择以及发送优先级等。
3. 数据接收单片机从CAN总线上接收其他节点发送过来的数据,接收数据时需要注意数据格式的解析、ID的识别以及接收缓冲器的管理等。
五、CAN通信的实例代码以下是基于AT89C51单片机的CAN通信发送与接收的实例代码:```c#include <reg52.h>sbit P1_0 = P1^0;sbit P1_2 = P1^2;void CAN_Init() {// CAN总线初始化代码}void CAN_SendData(u8 ID, u8 data) {// CAN总线发送数据的代码}u8 CAN_ReceiveData(u8* ID) {u8 data;// CAN总线接收数据的代码return data;}void m本人n() {CAN_Init();while(1) {CAN_SendData(0x01, 0x55);if(P1_0 == 1) {u8 ID, data;data = CAN_ReceiveData(ID);if(ID == 0x02 data == 0xAA) {P1_2 = 1;}}}}```六、实验结果经过实验验证,基于AT89C51单片机的CAN通信发送与接收代码能够正常工作,并成功实现了数据的发送和接收。
CAN的工作原理CAN(Controller Area Network)是一种广泛应用于汽车、工业控制和通信领域的串行通信协议。
它的工作原理是基于一种分布式通信机制,可以同时连接多个节点,实现高效的数据传输和控制。
CAN的工作原理可以简单概括为以下几个方面:1. 物理层:CAN总线采用双绞线作为传输介质,通常使用差分信号传输方式。
这种方式可以有效地反抗电磁干扰,提高通信的可靠性。
CAN总线上的每一个节点都通过一个传输线连接到总线上。
2. 数据链路层:CAN总线采用一种基于帧的通信协议,数据传输以帧为单位进行。
每一个CAN帧由四个部份组成:起始位、帧类型位、数据位和CRC校验位。
起始位用于同步节点的时钟,帧类型位用于标识数据帧或者远程帧,数据位用于传输实际的数据,CRC校验位用于检测数据传输的错误。
3. 帧传输:CAN总线上的节点可以同时发送和接收数据。
当一个节点要发送数据时,它首先检查总线上是否有其他节点正在发送数据,如果没有,则它可以开始发送数据。
发送节点会将数据和标识符封装成一个CAN帧,并通过总线发送出去。
其他节点在接收到这个CAN帧后,会检查标识符,如果匹配,则接收数据。
4. 碰撞检测:由于CAN总线是一种共享总线结构,多个节点可能同时发送数据,导致碰撞。
为了解决碰撞问题,CAN总线采用了非破坏性的碰撞检测机制。
当一个节点发送数据时,它会同时监听总线上的数据,如果检测到其他节点同时发送数据,那末发送节点会住手发送,并等待一个随机的时间后重新发送。
5. 优先级:CAN总线上的每一个节点都有一个惟一的标识符,用于标识节点的优先级。
当多个节点同时发送数据时,具有更低标识符的节点具有更高的优先级,可以优先发送数据。
这种优先级机制可以确保重要数据的及时传输。
总的来说,CAN的工作原理基于分布式通信机制,通过物理层和数据链路层的协议实现数据的高效传输和控制。
它具有高可靠性、抗干扰能力强、支持多节点等特点,因此在汽车、工业控制和通信领域得到广泛应用。
CAN的工作原理CAN(Controller Area Network)是一种广泛应用于汽车电子系统中的通信协议。
它的工作原理是基于串行通信的方式,通过在汽车各个电子模块之间传递数据和控制信息,实现各个模块之间的相互协调和通信。
CAN的工作原理可以简单分为物理层和数据链路层两个部分。
1. 物理层:CAN协议使用差分信号传输数据,这种差分信号可以有效抵抗噪声干扰。
CAN总线上的每个节点都有一个CAN收发器,用于将数字信号转换成差分信号并发送到总线上。
CAN总线上的每个节点都通过终端电阻连接,形成一个总线拓扑结构。
2. 数据链路层:CAN协议采用了一种基于CSMA/CD(载波监听多点接入/冲突检测)的访问机制。
当一个节点准备发送数据时,首先检测总线上的信号是否被其他节点占用,如果没有被占用,则发送数据。
如果多个节点同时发送数据,就会发生冲突,此时节点会停止发送,并根据一定的算法进行重传。
CAN协议中的数据帧包括以下几个部分:- 起始位(Start of Frame,SOF):表示数据帧的开始。
- 标识符(Identifier):用于标识数据帧的类型和发送节点的地址。
- 控制位(Control):包括数据长度和远程传输请求等信息。
- 数据域(Data):包含实际的数据信息。
- CRC(Cyclic Redundancy Check):用于校验数据的完整性。
- 确认位(Acknowledgement):用于确认数据的正确接收。
- 结束位(End of Frame,EOF):表示数据帧的结束。
CAN协议支持两种工作模式:标准帧和扩展帧。
标准帧使用11位的标识符,可以传输8字节的数据;而扩展帧使用29位的标识符,可以传输更大长度的数据。
CAN协议具有以下特点:- 高可靠性:CAN总线具有抗干扰能力强、误码率低的特点,能够在恶劣的环境下正常工作。
- 高实时性:CAN总线的通信速率较高,可以满足实时性要求。
- 灵活性:CAN总线可以连接多个节点,节点之间可以进行灵活的数据交换和控制。
can总线的通信协议Can总线是一种广泛应用于汽车行业的通信协议,它采用了差分信号传输技术,具有高可靠性和抗干扰能力。
Can总线的通信协议包括物理层、数据链路层和应用层三个部分,下面将逐一介绍。
一、物理层Can总线的物理层主要定义了通信的电气特性和连接方式。
Can总线采用双绞线进行通信,其中一根线为CAN_H,另一根为CAN_L,通过差分信号的方式传输数据。
双绞线的使用使得Can总线具有较好的抗干扰能力,可以在噪声较多的环境中正常工作。
同时,Can总线还采用了差分驱动器和终端电阻的方式来提高信号的可靠性和传输距离。
二、数据链路层Can总线的数据链路层主要负责数据传输的控制和错误检测。
Can总线采用了CSMA/CD(载波监听多路访问/冲突检测)的传输机制,即节点在发送数据之前先监听总线上是否有其他节点正在发送数据,若有,则等待一段时间后再发送。
这种机制可以有效避免数据冲突。
Can总线的数据链路层还包括帧格式的定义。
Can总线的数据传输单位是帧,每个帧由起始位、标识符、控制位、数据域和校验位组成。
其中,标识符用于标识帧的类型和发送节点,数据域用于存储实际的数据信息,校验位用于检测数据传输过程中是否发生错误。
三、应用层Can总线的应用层主要定义了数据的传输和处理方式。
Can总线上的节点可以进行点对点通信或广播通信。
点对点通信是指两个节点之间进行数据传输,而广播通信是指一个节点向整个总线发送数据,所有节点都能接收到。
Can总线上的节点需要事先约定好数据的传输格式和意义,以确保数据的正确解析和处理。
通常情况下,Can总线上的数据是采用十六进制表示的,通过不同的标识符和数据域来区分不同的数据类型和含义。
这样的设计使得Can总线可以同时传输多种类型的数据,满足复杂系统中各种需求。
总结:Can总线的通信协议具有高可靠性、抗干扰能力强的特点,广泛应用于汽车行业。
通过物理层、数据链路层和应用层的定义和规范,Can总线实现了节点之间的可靠通信和数据传输。
自定义CAN通信协议一、资源节点分配。
1.I/O输入地址00H---1FH2.I/O输出地址20H----3FH3.模拟量输入地址40H---5FH4.模拟量输出地址60H---7FH5.设备标识地址80H----9FH6.通信参数地址A0H----BFH6.1. A0H 本机物理地址(生产者地址)6.2. A1H 主机物理地址(消费者地址1默认第一个为主机地址0)6.3 A2H 主机物理地址(消费者地址2)6.4 A3H 主机物理地址(消费者地址3)6.5 A4H 主机物理地址(消费者地址4)6.6 A5H 主机物理地址(消费者地址5)6.7 A6H 主机物理地址(消费者地址6)A7H 从机物理地址(服务者地址1)A8H 从机物理地址(服务者地址2)A9H 从机物理地址(服务者地址3)AAH 从机物理地址(服务者地址4)ABH 从机物理地址(服务者地址5)ACH 从机物理地址(服务者地址6)6.8. ADH CAN波特率(1=10K,2=50K,3=100K,4=200K,5=500K)6.9. AEH 用户设置波特率(1=10K,2=50K,3=100K,4=200K,5=500K)6.10. AFH 从站循环发送时间单位为2ms6.11 B0H 节点心跳时间单位5ms6.12 B1H 节点发送数据方式(0主从方式。
1循环发送。
2主动发送。
)6.13 B2H 节点主动发送的资源节点起始地址6.14 B3H 节点主动发送的数据量6.15 B4H 本机为主机或者从机7. 自定义地址区域C0H----FFH二、29位标识符分配1. 物理地址分配28—23位(源地址)2. 目的地址分配22----17位3. 功能码地址分配16——13位4. 被操作的资源节点起始地址分配12---5位5. 主动帧/应答帧分配4位6. 保留位3----0位三、数据域分配第一个数据为分段码。
(6---7位表示分段标识,0----5位表示分段计数器)四、功能码编码1. 00H保留2.01H删除连接3. 02H建立连接4. 03H通信参数设置5. 04H写连续的资源节点6. 05H读连续的资源节点7. 06H节点心跳(由从机主动发送节点心跳)此功能码不用应答8.07H五、功能码解析1. 01H删除连接和02建立连接:一个节点可以是其他节点的主机也可以是其他节点的从机,但是在整个网络中绝对主机是地址为00的主机,他管理整个网络的网络联机,即各个相对主机的分配或者取消,网络参数的设置由00绝对主机设置。
/****************************************************************************** ********项目:基于CAN总线的自收发通信说明:主程序部分功能:外部按键每按下一次,计数值加一,同时计数值在数码管1、2上显示。
在计数值加一后,会使CAN总线上重新发送数据,此时接收端的计数值也同步更新显示在数码管3、4上(为便于观察,接收显示的值比发送值大3)。
// CAN主要参数: PeliCAN模式,扩展帧EFF模式// 29位标示码结构:// 发送数据结构:计数结果,0x02,0x03,0x04,0x05,0x06,0x07,0x08// 接收数据结构: 待显示数据+其它7个字节的数据// 本节点的接收代码寄存器值: 0x11,0x22,0x33,0x44// 本节点的屏蔽代码寄存器值:0x00,0x00,0x00,0x00;可以接收本节点的数据// 目的节点地址:0x11,0x22,0x33,0x44;可以被本节点接收模块:can_self.c作者:PIAE GROUP注释修改者:特权修改时间:08.6.17.******************************************************************************* *******//***感谢PIAE工作组提供的源码,这里特权根据自己的编程习惯做了一些修改并添加详细注释***/#include <reg52.h>#include <intrins.h>#include "define.h"/////////////////////////////////////////////////函数:inter0_key (外部中断INT0)//说明:INT0按键为计数按键// 每按下一次键,计数值加一//入口:按键中断//返回:按键加一///////////////////////////////////////////////void inter0_key(void) interrupt 0{EA = 0; //关闭中断Txd_data++; //计数结果增1,即待发送的数据增1TXD_flag = 1; //发送数据标志位置位,即重新发送数据以更新数码管的显示数值EA = 1; //重新开启中断}/////////////////////////////////////////////////函数:inter1_can_rxd (外部中断INT1)//说明:接收数据函数,在中断服务程序中调用//入口:无//返回:无///////////////////////////////////////////////void inter1_can_rxd( void ) interrupt 2{uchar state;EA = 0; //关CPU中断IE1 = 0; //由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零state = IR; //IR为SJA1000的中断寄存器if( state & 0x01) //若IR.0=1--接收中断{ //接收数据帧RX_buffer[0] = RBSR;RX_buffer[1] = RBSR1;RX_buffer[2] = RBSR2;RX_buffer[3] = RBSR3;RX_buffer[4] = RBSR4;RX_buffer[5] = RBSR5;RX_buffer[6] = RBSR6;RX_buffer[7] = RBSR7;RX_buffer[8] = RBSR8;RX_buffer[9] = RBSR9;RX_buffer[10] = RBSR10;RX_buffer[11] = RBSR11;RX_buffer[12] = RBSR12;RXD_flag = 1; //接收标志置位,以便进入接收处理程序CMR = 0X04; //CMR.2=1--接收完毕,释放接收缓冲器state = ALC; //释放仲裁随时捕捉寄存器(读该寄存器即可)state = ECC; //释放错误代码捕捉寄存器(读该寄存器即可)}IER = 0x01; // IER.0=1--接收中断使能EA = 1; //重新开启CPU中断}/////////////////////////////////////////////////函数:main//说明:主函数//入口:无//返回:无///////////////////////////////////////////////void main(void){init_mcu();init_sja1000();while(1){rxd_deal(); //接收处理程序txd_deal(); //发送处理程序led_show(0,Txd_data); //数码管1-2显示发送数据子程序led_show(1,Rxd_data+3); //数码管3-4显示接收数据子程序}}/////////////////////////////////////////////////函数:init_mcu//说明:单片机I/O口初始化// 主要是各中断寄存器的初始化//入口:无//返回:无///////////////////////////////////////////////void init_mcu(void){SJA_RST = 1; //CAN总线复位管脚复位无效SJA_CS = 0; //CAN总线片选有效EX1 = 1; //开MCU外部中断INT1IT1 = 0; //MCU外部中断INT1设置为电平触发,该中断口连接CAN总线接收中断口IT0 = 1; //MCU外部中断INT0设置为下降沿触发EX0 = 1; //开MCU外部中断INT0EA = 1; //开MCU总中断SJA_CS = 1; //CAN总线片选无效,使得对数据总线的操作不会影响SJA1000。
}/////////////////////////////////////////////////函数:init_sja1000//说明:独立CAN控制器SJA1000的初始化//入口:无//返回:无///////////////////////////////////////////////void init_sja1000(void){uchar state;uchar ACRR[4];uchar AMRR[4];// 接收代码寄存器ACRR[0] = 0x11;ACRR[1] = 0x22;ACRR[2] = 0x33;ACRR[3] = 0x44;// 接收屏蔽寄存器,只接收主机发送的信息AMRR[0] = 0x00;AMRR[1] = 0X00;AMRR[2] = 0x00;AMRR[3] = 0x00;// 使用do--while语句确保进入复位模式do{MODR = 0x09; // 设置MOD.0=1--进入复位模式,以便设置相应的寄存器state = MODR;}while( !(state & 0x01) );// 对SJA1000部分寄存器进行初始化设置CDR = 0x88; // CDR为时钟分频器,CDR.3=1--时钟关闭, CDR.7=0---basic CAN, CDR.7=1---Peli CANBTR0 = 0x31; // 总线定时寄存器0 ;总线波特率设定BTR1 = 0x1c; // 总线定时寄存器1 ;总线波特率设定IER = 0x01; // IER.0=1--接收中断使能;IER.1=0--关闭发送中断使能OCR = 0xaa; // 配置输出控制寄存器CMR = 0x04; // 释放接收缓冲器// 初始化接收代码寄存器ACR0 = ACRR[0];ACR1 = ACRR[1];ACR2 = ACRR[2];ACR3 = ACRR[3];// 初始化接收屏蔽寄存器AMR0 = AMRR[0];AMR1 = AMRR[1];AMR2 = AMRR[2];AMR3 = AMRR[3];// 使用do--while语句确保进入自接收模式do{MODR = 0x04; //MOD.2=1--进入自接收模式,MOD.3=0--双滤波器模式state = MODR;}while( !(state & 0x04) );}/////////////////////////////////////////////////函数:rxd_deal//说明:接收处理程序;检测接收标志状态位,// 如果置位则进行接收处理//入口:无//返回:无///////////////////////////////////////////////void rxd_deal(void){if( RXD_flag ) //RXD_flag=0说明无数据可以接收,RXD_flag=1说明有数据可以接收{EA = 0; //关闭CPU中断RXD_flag = 0; //RXD_flag清零,以便下次查询Rxd_data = RX_buffer[5]; //CAN总线要接收的数据,也是要在数码管3-4位置显示的数据EA = 1; //重新开启CPU中断}}/////////////////////////////////////////////////函数:txd_deal//说明:发送处理程序;检测发送标志状态位,// 如果置位则进行发送数据处理//入口:无//返回:无///////////////////////////////////////////////void txd_deal(void){if( TXD_flag == 1 )//若TXD_flag=1,要求进行数据的发送处理{_nop_();TXD_flag = 0; //RXD_flag清零,以便下次查询can_txd(); //发送数据帧_nop_();_nop_();} //发送数据帧后,SJA1000将产生接收中断}/////////////////////////////////////////////////函数:can_txd//说明:发送扩展数据帧//入口:无//返回:无///////////////////////////////////////////////void can_txd(void){uchar state;uchar TX_buffer[ N_can ] ; //N_can=13,TX_buffer数组为待传送的数据帧//初始化标示码头信息TX_buffer[0] = 0x88; //.7=0--扩展帧;.6=0--数据帧; .0-.3=100--数据长度为8字节TX_buffer[1] = 0x11; //本节点地址TX_buffer[2] = 0x22;TX_buffer[3] = 0x33;TX_buffer[4] = 0x44;//初始化发送数据单元TX_buffer[5] = Txd_data; //发送的第1个字节数据,也是数码管要显示的数据(计数结果)TX_buffer[6] = 0x22; //2TX_buffer[7] = 0x33; //3TX_buffer[8] = 0x44; //4TX_buffer[9] = 0x55; //5TX_buffer[10] = 0x66; //6TX_buffer[11] = 0x77; //7TX_buffer[12] = 0x88; //8//初始化数据信息EA = 0; //关中断//查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行do{state = SR; //SR为SJA1000的状态寄存器LED_RED = 0; //点亮LED1}while( state & 0x10 ); //SR.4=1 正在接收,等待//查询SJA1000是否处于发送完毕状态do{state = SR;LED_RED = 0; //点亮LED1}while(!(state & 0x08)); //SR.3=0,发送请求未处理完,等待直到SR.3=1//查询发送缓冲器状态do{state = SR;LED_RED = 0; //点亮LED1}while(!(state & 0x04)); //SR.2=0,发送缓冲器被锁。