⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sja.c

📁 CAN__组建现场总线系统设计技术(光盘)
💻 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 + -