📄 sja.c
字号:
/*
* sja.c
*
* CAN总线通讯
*
*
* 原作者:刘篷,孙占辉
*
* 修改:陈真勇(SA01010010)
* w3wind@sina.com or
* zychen@ustc.edu.cn
* 中国科学技术大学自动化系
* 2002/6/12
*/
/*
修改:王占成
zcwang@mail.ustc.edu.cn
2003.4.28
*/
#include "sja.h"
#include "Xdata.h"
#include "link.h"
#include "delay.h"
#include "watchdog.h"
/*extern BYTE canmode[17]; /*存放控制字 */
/* direct access to 8051 memory areas */
BYTE read_sja(BYTE addr) reentrant using 0
{
return ((BYTE volatile*)0x2F000L)[addr]; /*SJA基址为0x2000*/
}
void write_sja(BYTE addr,BYTE val) reentrant using 0
{
((BYTE volatile*)0x2F000L)[addr]=val;
}
/*
* function below used for SJA settings,system startup display
*/
void btransmit() reentrant;
void send_reset_frame(BYTE md_addr) using 0
{
BYTE temp_reg,relay_time;
write_sja(1,0x08);
temp_reg=read_sja(4);
write_sja(4,0x00);
TXdata[0]=0x08;
TXdata[1]=0x40;
TXdata[2]=0x00;
TXdata[3]=0x5f;
TXdata[4]=0x05;
TXdata[5]=md_addr;
TXdata[6]=0x00;
TXdata[7]=0x00;
TXdata[8]=0x00;
TXdata[9]=0x00;
TXdata[10]=0x00;
relay_time=md_addr;
while(relay_time--){/* delay some time relate to module address in order to avoid crash*/
delay(5);
}
btransmit();
write_sja(4,temp_reg);
clear_watchdog();
}
/* init SJA1000 */
void init_sja(BYTE md_addr,BYTE baud)
{
read_sja(3);
do{
write_sja(0,0x01);
}while(!(read_sja(0)&0x01));
write_sja(6,baud); /*bustime0 default 0xc3*/
write_sja(7,0xA3); /*bustime1 default 0xa3*/
write_sja(8,0x1A); /*output control*/
write_sja(31,0xc7); /*PeliCAN mode,bypass the input comparator*/
write_sja(14,0x00);
write_sja(15,0x00);
write_sja(16,md_addr); /*acceptcode default ffffffff*/
write_sja(17,0xff);
write_sja(18,0x03);
write_sja(19,0xff);
write_sja(20,0xc0); /*acceptmask default ffffffff*/
write_sja(21,0xff);
write_sja(22,0xc0);
write_sja(23,0xff);
write_sja(4,0x09);
write_sja(1,0x04);
/*can_mode[17],0 mode,1 inter,2 bustime0,3 bustime1,4 outputcontrol,5 clockdivide,6-9 acode,10-13 amask,14 errorlimit,15 RXecount,16 TXecount*/
do{
write_sja(0,0x00); /*SJA1000 workingmode normal+++++++++++++++++++++++++++*/
}while(!read_sja(0)&0x08 );
send_reset_frame(md_addr);/*发出初始帧*/
}
void btransmit() reentrant using 0
{
BYTE j;
BYTE can_addr;
EA=0;
can_addr=16;
do{
}while(! (read_sja(2)&0x04) ); /* wait until reg2^2==1 */
CANLAMP=0;/* light LED */
for(j=0;j<11;j++) {/* write 11 bytes data to transmit buffer */
write_sja(can_addr++,TXdata[j]);
}
CANLAMP=1;/* disable LED */
write_sja(0x01,0x01);/* send out */
EA=1;
}
/* 读取帧
* return value: 0 successful,1 failure
*/
BYTE receive() using 0
{
int i=0;
BYTE addr=16;
if(read_sja(2)&0x01)
{
CANLAMP=0;
do{
for(i=0;i<11;i++){
RXdata[i]=read_sja(addr++);/*接收数据,读接收寄存器*/
}
write_sja(0x01,0x04); /*清空寄存器*/
}while(read_sja(2)&0x01);
read_sja(3);
CANLAMP=1;
return 0;
}
else
{
write_sja(0x01,0x0c);
read_sja(3);
return 1;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -