?? 24m
字號:
#include <reg51.h>
#include <absacc.h>
/************** SJA1000 內部寄存器地址定義 ********/
#define CAN_MODE 0 /* 模式寄存器 */
#define CAN_CMR 1 /* 命令寄存器 */
#define CAN_SR 2 /* 狀態(tài)寄存器 */
#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 /* 發(fā)送錯誤計數寄存器 */
#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中保留未用,在此用來區(qū)分輸入,輸出數據*/
unsigned char rx_data[13]={0,0,0,0,0,
0,0,0,0,
0,0,0,0};
unsigned char bdata sr ,ir; /* 記錄SJA1000 內部狀態(tài) */
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 為高優(yōu)先*/
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 ); /* 清除發(fā)送錯誤計數寄存器 */
while( readSJAreg( CAN_RXERR )!= 0x00)
writeSJAreg( CAN_RXERR , 0x00 ); /* 清除接收錯誤計數寄存器 */
while( readSJAreg( CAN_MODE )!= 0x0c)
writeSJAreg( CAN_MODE , 0x0c ); /* 單向濾波器,自檢測模式 */
}
/*************************************************************/
/************* 發(fā)送子程序 ****************/
/************* 通過tx_data[]傳參 ****************/
/************* 使用此程序前要預先將數據放入tx_data[]中 ******/
/*************************************************************/
void can_txdata ( )
{
unsigned char i , length ;
sr = CAN_SR;
do{ ;}
while(!(sr^3)) ; /* 判斷上次發(fā)送是否完成,未完成,等待 */
do{ ;}
while(sr^2) ; /* 判斷發(fā)送緩沖器是否鎖定,鎖定,等待 */
// 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 ); /* 啟動自收發(fā)*/
// 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 ); /* 接收完畢,釋放接收緩沖區(qū) */
}
/*********************************************************/
/************* 接收中斷程序 ******************/
/*********************************************************/
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; /*點發(fā)光二極管*/
getremote = 0 ;
break ;
default: break;
}
}
}
if(timer0up) // (!getremote)&&
{
dealmessage_remote();
timer0up =0;
}
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -