给你程序你不一定能用啊,还要和硬件对应啊,比如你的地址确定问题。
这就是网络的程序为什么大多不能直接使用的原因啊。
给你提供一些思路
1、sja1000初始化
2、发送子程序
3、中断方式接收
下面是一些程序段
你参考下(已用于产品)
/**********SJA1000初始化***********//
void Init_SJA1000(void)
{
uchar state
uchar ACRR[4]={0XAA,0XFF,0X22,0X11}// 接收代码寄存器
uchar AMRR[4]={0xff,0xff,0xff,0xff}// 接收屏蔽寄存器
//uchar AMRR[4]={0x00,0x00,0xff,0xff}// 接收屏蔽寄存器
do// 使用do--while语句确保进入悉携复位模式
{
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 CAN
BTR0 = 0x04//0x31// 总线定时寄存器0 ;总线波特率设定
BTR1 = 0x1c//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// 使用do--while语句确保退出复位模式山陆旦
{
MODR = 0x08//MOD.3=0--双滤波器模式
state = MODR
}
while( state &0x01 )
}//////////////////////////////////////
//**********CAN发送数据到CAN-Bus***********//
void CAN_TXD(void)
{
uchar state
//初始化标示码头信息
TX_buffer[0] = 0x88//.7=0--扩展帧;.6=0--数据帧.0-.3=100--数据长度为8字节
// TX_buffer[1] = 0xFF//本帧信息的ID
//TX_buffer[2] = 0xFF
TX_buffer[3] = 0xFF
TX_buffer[4] = 0xFF
do //查询SJA1000是否处于接收状态,当SJA1000不处于接收状态时才可继续执行
{
state = SR //SR为SJA1000的状态寄存器
}
while( state &0x10 ) //SR.4=1 正在接收,等待
do //查询SJA1000是否处于发送完毕状态
{
state = SR
}
while(!(state &0x08))//SR.3=0,发送请求未处理完,等待直到SR.3=1
do //查询发送缓冲器状态
{
state = SR
}
while(!(state &0x04))//SR.2=0,发送缓冲器被锁。等待直到SR.2=1
//将待发送的一帧数据信息存入SJA1000的相应寄存器中
TBSR0 = TX_buffer[0]
TBSR1 = TX_buffer[1]
TBSR2 = TX_buffer[2]
TBSR3 = TX_buffer[3]
TBSR4 = TX_buffer[4]
TBSR5 = TX_buffer[5]
TBSR6 = TX_buffer[6]
TBSR7 = TX_buffer[7]
TBSR8 = TX_buffer[8]
TBSR9 = TX_buffer[9]
TBSR10 = TX_buffer[10]
TBSR11 = TX_buffer[11]
TBSR12 = TX_buffer[12]
CMR = 0x04//置位发送请求
}//////////////////////////////////////
//**********中断接收来自CAN-Bus数据***********//
void inter1_can_rxd( void ) interrupt 0
{
uchar state
EA = 0 //关CPU中断
IE0 = 0//由于是中断INT1是电平触发方式,所以需要软件将INT1的中断请求标志IE0清零
state = IR//IR为SJA1000的中断寄存器
if( state &0x01) //若IR.0=1--接收中断
{
RX_buffer[0] = RBSR0
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中断
}//////////////////////////////////////
//********** ***********//
希望对你能有帮助
plc接收CAN总线上的信息,可以配置成CANopen基本协议进行9针口程序编写。
CAN协议用于汽车中各种不同元件之间的通信,以喊模则此取代昂贵而笨重的配电线束。该协议的健壮性使其用途延伸到其他自动化码档和工业应用。
CAN协议的特性包括完整性的串行数据通讯、提供实时支持、传输速率高达1Mb/s、同时具有11位的寻址以及检错能力。
CAN总线使用串行数据传输方式,可以1Mb/s的速率在40m的双绞线上运行,也可以使用光缆连接,而且在这种总线上总线协议支持多主控制器。
扩展资料:
CAN协议总线的工作原理:
CAN与I2C总线的许多细节很类似,但也有一些明显的区别。当CAN总线上的一个节点(站)发送数据时,它以报文形式广播给网络中所有节点。对每个节点来说,无论数据是否是发给自己的,都对其进行接收。
每组报文开头的11位字符为标识符,定义了报文的优先级,这种报文格式称为面向内容的编址方案。
在同一系统中标识符是唯一的,不可能有两个站发送具有相同标识符的报文。当几个站同时竞争总线读取时,这种配置十分重要。
参考资料来源:百度百科—可编程逻辑控制器 (可编程控制器件)
参考郑棚资料来源:百度百科—CAN总线协议
汇编语言中数据和程序在内存单元中存放的时候没有区别,都是二进制信息。如果cs:ip指向某个内存单元,那么cpu就从这个仔锋单元开始往下执行,所以这里就是指令(程序)。
如果滑戚让用任何一种存储器寻址方式指向某个单元,并且是作为 *** 作数来使用的,那么这就是数据。
其实如果只是单纯看一个内存单元,是无法区分到底是数据还是程序的信局。只能是写程序时,用汇编指令做不同的解释。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)