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

📄 16m

📁 基于CAN总线的NMEA2000协议
💻
📖 第 1 页 / 共 2 页
字号:
#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,0x99,0x99,0x99,0x99,           /*                 */
                            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_remote3( 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  t0 =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 )!=  0x01)
              writeSJAreg( CAN_BTR0 , 0x01 );     /*  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 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -