📄 sja.c
字号:
/*
* sja.c
*
* CAN总线通讯
*
*
* 原作者:刘篷,孙占辉
*
* 修改:陈真勇(SA01010010)
* w3wind@sina.com or
* zychen@ustc.edu.cn
* 中国科学技术大学自动化系
* 2002/6/12
*/
#include "type.h"
#include "link.h"
#include "delay.h"
#include "watchdog.h"
BYTE canmode[17]; /* 存放控制字 */
BYTE TXdata[11]; /* 发送缓冲区 */
BYTE RXdata[11]; /* 接收缓冲区 */
void ctransmit() reentrant;
/* direct access to 8051 memory areas */
BYTE read_sja(BYTE addr) reentrant using 0
{
return ((BYTE volatile*)0x30000L)[addr];
}
void write_sja(BYTE addr,BYTE val) reentrant using 0
{
((BYTE volatile*)0x30000L)[addr]=val;
}
/*
* function below used for SJA settings,system startup display
*/
void set_canmode(BYTE md_addr,BYTE baud)
{
canmode[0]=0x00;/*normal mode,single filter*/
canmode[1]=0x09;/*enable receive and overflow interrupt*/
canmode[2]=baud;/*bustime0*/
canmode[3]=0xA3;/*bustime1*/
canmode[4]=0x1A;/*output control*/
canmode[5]=0xC7;/*clock divide pelican mode,bypass comparator*/
canmode[6]=md_addr;
canmode[7]=0xff;
canmode[8]=0x03;
canmode[9]=0xff;
canmode[10]=0xc0;
canmode[11]=0xff;
canmode[12]=0xc0;
canmode[13]=0xff;
}
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);
clear_watchdog();
}
ctransmit();
write_sja(4,temp_reg);
}
/* init SJA1000 */
void init_sja(BYTE md_addr,BYTE baud)
{
set_canmode(md_addr,baud);
read_sja(3);
do{
write_sja(0,0x01);
}while(!(read_sja(0)&0x01));
write_sja(6,canmode[2]); /*bustime0 default 0xc3*/
write_sja(7,canmode[3]); /*bustime1 default 0xa3*/
write_sja(8,canmode[4]); /*output control*/
write_sja(31,canmode[5]); /*PeliCAN mode,bypass the input comparator*/
write_sja(14,0x00);
write_sja(15,0x00);
write_sja(16,canmode[6]); /*acceptcode default ffffffff*/
write_sja(17,canmode[7]);
write_sja(18,canmode[8]);
write_sja(19,canmode[9]);
write_sja(20,canmode[10]); /*acceptmask default ffffffff*/
write_sja(21,canmode[11]);
write_sja(22,canmode[12]);
write_sja(23,canmode[13]);
write_sja(4,canmode[1]);
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(0x00,canmode[0]); /*SJA1000 workingmode normal*/
}while(!read_sja(0)&0x08 );
send_reset_frame(md_addr);/*发出初始帧*/
}
void ctransmit() reentrant using 0
{
int 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() reentrant 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 + -