📄 24m
字号:
#include <reg51.h>
#include <absacc.h>
/************** SJA1000 内部寄存器地址定义 ********/
#define CAN_MODE 0 /* 模式寄存器 */
#define CAN_CMR 1 /* 命令寄存器 */
#define CAN_SR 2 /* 状态寄存器 */
#define CAN_IR 3 /* 中断寄存器 */
#define CAN_IER 4 /* 中断允许寄存器 */
#define CAN_BTR0 6 /* 总线定时寄存器0 */
#define CAN_BTR1 7 /* 总线定时寄存器1 */
#define CAN_OCR 8 /* 输出控制寄存器 */
#define CAN_TEST 9
#define CAN_ALC 11 /* 仲裁丢失捕捉寄存器 */
#define CAN_ECC 12 /* 错误代码捕捉寄存器 */
#define CAN_EWLR 13 /* 错误报警限额寄存器 */
#define CAN_RXERR 14 /* 接受错误计数寄存器 */
#define CAN_TXERR 15 /* 发送错误计数寄存器 */
#define CAN_RBSA 30 /* 接受缓存器起始地址寄存器 */
#define CAN_CDR 31 /* 时钟分频寄存器 */
#define CAN_ACR0 16 /* 验收代码寄存器0 */
#define CAN_ACR1 17 /* 验收代码寄存器1 */
#define CAN_ACR2 18 /* 验收代码寄存器2 */
#define CAN_ACR3 19 /* 验收代码寄存器3 */
#define CAN_AMR0 20 /* 验收屏蔽寄存器0 */
#define CAN_AMR1 21 /* 验收屏蔽寄存器1 */
#define CAN_AMR2 22 /* 验收屏蔽寄存器2 */
#define CAN_AMR3 23 /* 验收屏蔽寄存器3 */
unsigned char tx_data[13]={0x88,0x88,0x88,0x88,0x88, /* */
0x11,0x22,0x33,0x44, /* */
0x55,0x66,0x77,0x88}; /* 输入输出数据数组 其中tx_data[0]的4,5位
在SJA1000中保留未用,在此用来区分输入,输出数据*/
unsigned char rx_data[13]={0,0,0,0,0,
0,0,0,0,
0,0,0,0};
unsigned char bdata sr ,ir; /* 记录SJA1000 内部状态 */
bit getremote=0; /* 远程帧标记 收到远程帧请求后 置1 */
bit timer0up=0; /* 秒计时 到1秒 置1 */
unsigned char t0count=0;
unsigned char mytime; /* 用于记录0到9的ASCII 每秒增加1,远程帧访问增加1 */
void can_init( void ) ;
void can_txdata ( void ) ;
void can_rxdata ( void ) ;
void dealmessage_remote( void ) ;
/******************************************************************/
/******************* write reg of SJA1000 ****************/
/******************************************************************/
void writeSJAreg ( unsigned char SJAadd , unsigned char value)
{
unsigned char temp_write = value ;
XBYTE[ 0x8000 + SJAadd ] = temp_write ;
}
/******************************************************************/
/******************* read reg of SJA1000 ****************/
/******************************************************************/
unsigned char readSJAreg( unsigned char SJAadd )
{
return( XBYTE[ 0x8000 + SJAadd ] );
}
/******************************************************************/
/******************* set the reg bit of SJA1000 ****************/
/******************************************************************/
void setREGbit(unsigned char SJAadd , unsigned char value)
{
unsigned char temp ;
temp = readSJAreg( SJAadd ) ;
temp |= value ;
writeSJAreg( SJAadd , temp ) ;
}
/******************************************************************/
/******************* clear the reg bit of SJA1000 ****************/
/******************************************************************/
void clearREGbit(unsigned char SJAadd , unsigned char value)
{
unsigned char temp ;
temp = readSJAreg( SJAadd ) ;
temp &= value ;
writeSJAreg( SJAadd , temp ) ;
}
/******************************************************************/
/******************* test bit of SJA1000 ****************/
/******************************************************************/
unsigned char testREGbit(unsigned char SJAadd , unsigned char value)
{
unsigned char temp ;
temp = readSJAreg( SJAadd ) ;
temp &= value ;
return (temp) ;
}
/******************************************************************/
/******************* initializtion of CPU ****************/
/******************************************************************/
void cpu_init(void)
{
IE = 0x03; /* EX0=1 */
IP = 0x01; /* INT0 为高优先*/
TCON = 0x10 ; /* T0 and INT0 */
TMOD = 0x01; /* T0 方式1 ,定时器 */
TH0 = 0x3c;
TL0 = 0x0b0;
EA = 1;
}
/******************************************************************/
/******************* initializtion of SJA1000 ****************/
/******************************************************************/
void can_init(void)
{
// while (readSJAreg( CAN_MODE )!= 0x01)
writeSJAreg( CAN_MODE , 0x01 ) ; /* 进入复位模式 */
while (readSJAreg( CAN_CDR )!= 0x88)
writeSJAreg( CAN_CDR , 0x88 ) ; /* 工作在pelican模式,时钟关闭CLOCK OFF */
while( readSJAreg( CAN_RBSA )!= 0x00)
writeSJAreg( CAN_RBSA , 0x00 ); /* 设置接收缓冲器地址FIFO起始地址为0 */
while( readSJAreg( CAN_OCR )!= 0x1A)
writeSJAreg( CAN_OCR , 0x1A ); /* 推挽输出 */
while( readSJAreg( CAN_BTR0 )!= 0x02)
writeSJAreg( CAN_BTR0 , 0x02 ); /* BRT0 = 0x01, BRT1 = 0x1c 500kbps */
while( readSJAreg( CAN_BTR1 )!= 0x1c)
writeSJAreg( CAN_BTR1 , 0x1c ); /* 设置为250kbps BRT0 = 0x03, BRT1 = 0x1c */
while( readSJAreg( CAN_AMR0 )!= 0xff)
writeSJAreg( CAN_AMR0 , 0xff );
while( readSJAreg( CAN_AMR1 )!= 0xff)
writeSJAreg( CAN_AMR1 , 0xff );
while( readSJAreg( CAN_AMR2 )!= 0xff)
writeSJAreg( CAN_AMR2 , 0xff );
while( readSJAreg( CAN_AMR3 )!= 0xff)
writeSJAreg( CAN_AMR3 , 0xff );
while( readSJAreg( CAN_ACR0 )!= 0xff)
writeSJAreg( CAN_ACR0 , 0xff );
while( readSJAreg( CAN_ACR1 )!= 0xff)
writeSJAreg( CAN_ACR1 , 0xff );
while( readSJAreg( CAN_ACR2 )!= 0xff)
writeSJAreg( CAN_ACR2 , 0xff );
while( readSJAreg( CAN_ACR3 )!= 0xff)
writeSJAreg( CAN_ACR3 , 0xff );
while( readSJAreg( CAN_IER )!= 0x01)
writeSJAreg( CAN_IER , 0x01 ); /* 开放,接收中断,出错报警,数据溢出 */
while( readSJAreg( CAN_TXERR )!= 0x00)
writeSJAreg( CAN_TXERR , 0x00 ); /* 清除发送错误计数寄存器 */
while( readSJAreg( CAN_RXERR )!= 0x00)
writeSJAreg( CAN_RXERR , 0x00 ); /* 清除接收错误计数寄存器 */
while( readSJAreg( CAN_MODE )!= 0x0c)
writeSJAreg( CAN_MODE , 0x0c ); /* 单向滤波器,自检测模式 */
}
/*************************************************************/
/************* 发送子程序 ****************/
/************* 通过tx_data[]传参 ****************/
/************* 使用此程序前要预先将数据放入tx_data[]中 ******/
/*************************************************************/
void can_txdata ( )
{
unsigned char i , length ;
sr = CAN_SR;
do{ ;}
while(!(sr^3)) ; /* 判断上次发送是否完成,未完成,等待 */
do{ ;}
while(sr^2) ; /* 判断发送缓冲器是否锁定,锁定,等待 */
// if(sr^1)
// writeSJAreg( CAN_CMR , 0X0C ); /* 清除数据溢出 释放接收缓冲器*/
// do{ can_rxdata ( );}
// while(readSJAreg(29)) ;
switch(tx_data[0]&0xC0)
{
case 0x00: /*标准帧、数据帧*/
length = ( tx_data[0] & 0x0f ) ;
if(length>8) length = 8;
length += 3; break ;
case 0x40: /*标准帧、远程帧*/
length = 3; break ;
case 0x80: /*扩展帧、数据帧*/
length = ( tx_data[0] & 0x0f ) ;
if(length>8) length = 8;
length += 5; break ;
case 0xc0: /*扩展帧、远程帧*/
length = 5; break ;
default: break;
}
for(i=0 ; i<length ; i++)
{
writeSJAreg( 16+i , tx_data[i] );
}
writeSJAreg( CAN_CMR , 0X11 ); /* 启动自收发*/
// writeSJAreg( CAN_CMR , 0X02 );
ir = readSJAreg( CAN_IR ) ;
}
/*************************************************************/
/************* 接收子程序 ****************/
/************* 将接收到的数据存入rx_data[]中 ***********/
/*************************************************************/
void can_rxdata ( void )
{
unsigned char length;
unsigned char i;
rx_data[0] = length = readSJAreg( 16 ) ;
switch(length&0xC0)
{
case 0x00: /*标准帧、数据帧*/
length = ( rx_data[0] & 0x0f ) ;
if(length>8) length = 8;
length += 3; break ;
case 0x40: /*标准帧、远程帧*/
length = 3; break ;
case 0x80: /*扩展帧、数据帧*/
length = ( rx_data[0] & 0x0f ) ;
if(length>8) length = 8;
length += 5; break ;
case 0xc0: /*扩展帧、远程帧*/
length = 5; break ;
default: break;
}
for (i=0;i<length;i++)
{
rx_data[i] = readSJAreg( 16+ i ) ;
}
writeSJAreg( CAN_CMR , 0X0c ); /* 接收完毕,释放接收缓冲区 */
}
/*********************************************************/
/************* 接收中断程序 ******************/
/*********************************************************/
void int0() interrupt 0
{
EA = 0 ; /* 关中断 */
can_rxdata ( );
getremote =1;
EA = 1 ;
}
/*********************************************************/
/************* 定时器中断程序 ******************/
/*********************************************************/
void timer0() interrupt 1
{
EA = 0 ; /* 关中断 */
t0count++;
if(t0count>=20)
{
P2 = 0xff;
timer0up = 1;
t0count = 0;
}
if(mytime>=57)
{mytime = 0x2f;}
TH0 = 0x3c;
TL0 = 0xb0;
EA = 1 ;
}
/*********************************************************/
/************* 命令处理程序 ******************/
/*********************************************************/
void dealmessage_remote( void )
{
char j ;
// tx_data[13]={0x88,0xf0,0xf0,0xf0,0x88, /* 上位机显示一串1 */
// / 0x13,0x35,0x33,0x30, /* 1/3 5 3 0 */
// 0x39,0x30,0x32,0x4e}; /* 9 0 2 N */
for (j=0;j<50;j++);
tx_data[5] = 0x13;
tx_data[6] = 0x35;
tx_data[7] = 0x33;
tx_data[8] = 0x30;
tx_data[9] = 0x39;
tx_data[10] = 0x30;
tx_data[11] = 0x32;
tx_data[12] = 0x4e;
can_txdata ( );
for (j=0;j<50;j++);
// tx_data[13]={0x88,0xf0,0xf0,0xf0,0x88, /* 地理坐标 */
// 0x23,0x30,0x30,0x31, /* 2/3 0 0 1 */
// 0x35,0x30,0x34,0x30}; /* 5 0 4 0 */
tx_data[5] = 0x23;
tx_data[6] = 0x30;
tx_data[7] = 0x30;
tx_data[8] = 0x31;
tx_data[9] = 0x35;
tx_data[10] = 0x30;
tx_data[11] = 0x34;
tx_data[12] = 0x30;
can_txdata ( );
for (j=0;j<50;j++);
// tx_data[13]={0x88,0xf0,0xf0,0xf0,0x88, /* 地理坐标 */
// 0x33,0x57,0x32,0x32, /* 3/3 W 2 2 */
// 0x32,0x32,0x32,0x32}; /* 2 2 2 2 */
mytime++;
tx_data[5] = 0x33;
tx_data[6] = 0x57;
tx_data[7] = 0x32;
tx_data[8] = 0x32;
tx_data[9] = 0x32;
tx_data[10] = mytime;
tx_data[11] = 0x32;
tx_data[12] = mytime;
can_txdata ( );
}
main ()
{ char i,j ,temp=0;
for(i=0;i<255;i++)
for (j=0;j<255;j++);
cpu_init();
P2 =0xc0; /*硬件复位SJA1000*/
for (j=0;j<100;j++);
P2 =0xff;
can_init( ) ;
writeSJAreg( CAN_TEST , 0xaa );
temp = readSJAreg( CAN_TEST ) ;
writeSJAreg( CAN_TEST , 0x55 );
temp = readSJAreg( CAN_TEST ) ;
getremote =0;
mytime = 0x2f;
for (j=0;j<255;j++);
while(1)
{
if(getremote) //(timer0up)&&
{
if( 0x88 == rx_data[1])
{
switch(rx_data[0]&0xC0)
{
case 0x00: /*标准帧、数据帧*/
break ;
case 0x40: /*标准帧、远程帧*/
break ;
case 0x80: /*扩展帧、数据帧*/
break ;
case 0xc0: /*扩展帧、远程帧*/
dealmessage_remote();
P2 = 0x60; /*点发光二极管*/
getremote = 0 ;
break ;
default: break;
}
}
}
if(timer0up) // (!getremote)&&
{
dealmessage_remote();
timer0up =0;
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -