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

📄 sja_bcanfunc.c

📁 8051单片机访问外围器件的代码
💻 C
字号:
/**
 * @file
 * Driver for the CAN chip SJA1000 in Basic CAN mode
 * 
 * SJA_BCANFUNC.c
 * Copyright(C) 2007 Agate Logic Corporation. All rights reserved.
 * This file is licensed under the terms of Agate Logic SDK License Agreement.
 * 
 * @author bxu@agatelogic.com.cn
*/

#define CAN_GLOBALS	///< define macro "CAN_GLOBALS" as empty

#include <ag1f1.h>
#include "SJA_BCANCONF.H"
#include <intrins.h>
#define ALLDELAY _nop_();_nop_();_nop_();_nop_();

/**
 * @brief Write data to the specified register.
 * 
 * The Function write the specified data to the specified register of CAN chip.
 * 
 * @param Adr The address of the register to write to.
 * @param Value The data to write.
 * 
 * @return N/A
*/
void    WriteSjaReg(uchar Adr, uchar Value)
{
	CAN_CS=1;
	ALLDELAY
	CAN_RD=1;
	ALLDELAY
	CAN_WR=1;
	ALLDELAY
	CAN_DIR=0;//output direction
	ALLDELAY
	CAN_ALE=1;
	ALLDELAY
	CAN_ADDA=Adr;//addr output
	ALLDELAY
	CAN_ALE=0;//latch addr
	ALLDELAY
	CAN_CS=0;//chip select
	ALLDELAY
	CAN_ADDA=Value;//value output
	ALLDELAY
	CAN_WR=0;//WRITE start
	ALLDELAY
	CAN_WR=1;//WRITE end
	ALLDELAY
	CAN_CS=1;//chip unselect
	ALLDELAY
}

/**
 * @brief Read the specified register.
 * 
 * The Function read the value of the specified register of CAN chip.
 * 
 * @param Adr The address of the register to read from.
 * 
 * @return The value of the specified register
*/
uchar   ReadSjaReg(uchar Adr)
{
	uchar uctmp=0;
	CAN_CS=1;
	ALLDELAY
	CAN_RD=1;
	ALLDELAY
	CAN_WR=1;
	ALLDELAY
	CAN_DIR=0;//output direction
	ALLDELAY
	CAN_ALE=1;
	ALLDELAY
	CAN_ADDA=Adr;//addr output
	ALLDELAY
	CAN_ALE=0;//latch addr
	ALLDELAY
	CAN_DIR=1;//input direction
	ALLDELAY
	CAN_CS=0;//chip select
	ALLDELAY
	CAN_RD=0;//READ start
	ALLDELAY
	uctmp=CAN_ADDA;//value input
	ALLDELAY
	CAN_RD=1;//READ end
	ALLDELAY
	CAN_CS=1;//chip unselect
	ALLDELAY
	return uctmp;
}

/**
 * @brief Test the interface of CAN chip.
 * 
 * The Function first write the test register and then read back
 * the value of the test register. If the value is equal the value written, 
 * that means the communication with CAN chip is right.
 * 
 * @return The result of test.
 * @retval 0 means the interface work right
 * @retval 1 means the interface work wrong
*/
 bit   BCAN_CREATE_COMMUNATION(void)
 {
    WriteSjaReg(REG_TEST,0xaa);
    if(ReadSjaReg(REG_TEST) == 0xaa)
    {
        return    0;
    }
    else
    {    
       return    1;
    } 
 }

/**
 * @brief Drive the CAN chip enter the reset mode.
 * 
 * The Function set the control register to drive the chip to enter the reset mode,
 * then read back the value of the control register to check whether the chip has 
 * entered the reset mode.
 * 
 * @return The result of the operation.
 * @retval 0 means enter the reset mode successfully
 * @retval 1 means enter the reset mode falsely
*/
 bit   BCAN_ENTER_RETMODEL(void)
 {
    unsigned   char   TempData;
    TempData=  ReadSjaReg(REG_CONTROL);
    WriteSjaReg(REG_CONTROL, (TempData|0x01));
    if((ReadSjaReg(REG_CONTROL)&0x01) == 1)
    {
       return   0;
    }
    else
    {
       return   1;
    }
    
 }

/**
 * @brief Drive the CAN chip quit the reset mode.
 * 
 * The Function set the control register to drive the chip to quit the reset mode,
 * then read back the value of the control register to check whether the chip has 
 * quit the reset mode.
 * 
 * @return The result of the operation.
 * @retval 0 means quit the reset mode successfully
 * @retval 1 means quit the reset mode falsely
*/
 bit   BCAN_QUIT_RETMODEL(void)
 {
    unsigned   char   TempData;
    TempData=  ReadSjaReg(REG_CONTROL);
    WriteSjaReg(REG_CONTROL, (TempData&0xfe));
    if((ReadSjaReg(REG_CONTROL)&0x01) == 0)
    {
       return   0;
    }
    else
    {
       return   1;
    }
 }

/// The present value to set the baud rate
unsigned  char	code	SJA_BTR_CODETAB[]={
    0xbf,0xff,                     //;5KBPS
    0x67,0x2f,                     //;10KBPS
    0x53,0x2F,                     //;20KBPS
    0x87,0xFF,                     //;40KBPS
    0x47,0x2F,                     //;50KBPS
    0x83,0xFF,                     //;80KBPS
    0x43,0x2f,                     //;100KBPS
    0x03,0x1c,                     //;125KBPS
    0x81,0xfa,                     //;200KBPS
    0x01,0x1c,                     //;250KBPS
    0x80,0xfa,                     //;400KBPS
    0x00,0x1c,                     //;500KBPS
    0x80,0xb6,                     //;666KBPS
    0x00,0x16,                     //;800KBPS
    0x00,0x14                      //;1000KBPS
  };

/**
 * @brief Set the baud rate.
 * 
 * The Function write the present value to the bus time register to set the baud rate as specified,
 * then read back the value of the bus time register to check whether the register have set properly,
 * if the register value is wrong then do the write and check operation again till 20 loops.
 * This function can only run under reset mode.
 * 
 * @param CAN_ByteRate The constant of the baud rate to set, refer to the header file.
 * 
 * @return The result of the operation.
 * @retval 0 means baud rate is set successfully
 * @retval 1 means baud rate is set falsely
*/
bit	BCAN_SET_BANDRATE(unsigned char CAN_ByteRate)
{
	bit ErrorFlag = 1;		
	unsigned char ErrorCount = 0x20;
	if(CAN_ByteRate>14)
	{
		ErrorFlag =1;
	}
    else
    {
		while(--ErrorCount)
		{
			WriteSjaReg(REG_BTR0,SJA_BTR_CODETAB[CAN_ByteRate*2]);
			WriteSjaReg(REG_BTR1,SJA_BTR_CODETAB[CAN_ByteRate*2+1]);
			if(ReadSjaReg(REG_BTR0) != SJA_BTR_CODETAB[CAN_ByteRate*2])continue;
			if(ReadSjaReg(REG_BTR1) != SJA_BTR_CODETAB[CAN_ByteRate*2+1])continue;
			ErrorFlag=0;
			break;
		}
	}
	return	ErrorFlag ;
}

/**
 * @brief Set the communication object.
 * 
 * The Function set the acceptance code register and the acceptance mask register,
 * then read back the value of the registers to check whether the register have set properly,
 * This function can only run under reset mode.
 * 
 * @param BCAN_ACR The value to write to the acceptance code register.
 * @param BCAN_AMR The value to write to the acceptance mask register.
 * 
 * @return The result of the operation.
 * @retval 0 means set successfully
 * @retval 1 means set falsely
*/
bit    BCAN_SET_OBJECT(unsigned char  BCAN_ACR,unsigned char  BCAN_AMR)
{
  WriteSjaReg(REG_ACR,BCAN_ACR);
  if(ReadSjaReg(REG_ACR) != BCAN_ACR)
  {
    return  1; 
  }
  WriteSjaReg(REG_AMR,BCAN_AMR);
  if(ReadSjaReg(REG_AMR) != BCAN_AMR)
  {
    return  1; 
  }
  return    0;
}

/**
 * @brief Set the output mode and the output clock of CAN chip.
 * 
 * The Function set the output control register and the clock divider register,
 * then read back the value of the registers to check whether the register have set properly,
 * This function can only run under reset mode.
 * 
 * @param Out_Control The value to write to the output control register.
 * @param Clock_Out The value to write to the clock divider register.
 * 
 * @return The result of the operation.
 * @retval 0 means set successfully
 * @retval 1 means set falsely
*/
bit  BCAN_SET_OUTCLK (unsigned char Out_Control, unsigned char Clock_Out)
{
  WriteSjaReg(REG_OCR,Out_Control);
  if(ReadSjaReg(REG_OCR) != Out_Control)
  {
    return 1;
  } 
  WriteSjaReg(REG_CDR,Clock_Out);
  return 0;
}


/**
 * @brief Initialize the CAN chip.
 * 
 * The Function write the specified value to the corresponding register
 * to initialize the CAN chip.
 * This function can only run under reset mode.
 * 
 * @param BCAN_ACR The value to write to the acceptance code register.
 * @param BCAN_AMR The value to write to the acceptance mask register.
 * @param Bus_Timing0 The value to write to the bus time register 0.
 * @param Bus_Timing1 The value to write to the bus time register 1.
 * @param Out_Control The value to write to the output control register.
 * @param Clock_Out The value to write to the clock divider register.
 * 
 * @return The result of the operation.
 * @retval 0 means the chip is initialized successfully
 * @retval 1 means the chip is initialized falsely
*/
bit             BCAN_HW_INIT(unsigned char  BCAN_ACR,       
                             unsigned char  BCAN_AMR,      
                             unsigned char  Bus_Timing0,   
                             unsigned char  Bus_Timing1,   
                             unsigned char  Out_Control,    
                             unsigned char  Clock_Out      
                             ) 
{
  WriteSjaReg(REG_ACR,BCAN_ACR);
  if(ReadSjaReg(REG_ACR) != BCAN_ACR)
  {
    return  1; 
  }
  WriteSjaReg(REG_AMR,BCAN_AMR);
  if(ReadSjaReg(REG_AMR) != BCAN_AMR)
  {
    return  1; 
  }
  WriteSjaReg(REG_BTR0,Bus_Timing0);
  if(ReadSjaReg(REG_BTR0) != Bus_Timing0)
  {
    return  1; 
  }
  WriteSjaReg(REG_BTR1,Bus_Timing1);
  if(ReadSjaReg(REG_BTR1) != Bus_Timing1)
  {
    return  1; 
  }
  WriteSjaReg(REG_OCR,Out_Control);
  if(ReadSjaReg(REG_OCR) != Out_Control)
  {
    return  1; 
  } 
  WriteSjaReg(REG_CDR,Clock_Out);
  return    0;
}                         

/**
 * @brief Write the data array to the transmit buffer.
 * 
 * The Function write the specified data array to the transmit buffer.
 * 
 * @param SendDataBuf The data array to write to the buffer.
 * 
 * @return The result of the operation.
 * @retval 0 means the data array is written successfully
 * @retval 1 means the data array is written falsely
*/
 bit   BCAN_DATA_WRITE(unsigned char *SendDataBuf)
 {
	uchar  TempCount,uctmp;
	uctmp = ReadSjaReg(REG_STATUS);
	if((uctmp & 0x08) == 0)	//Check whether the last transmit operation has finished or not.
	{
		return	1;
	}

	if((uctmp & 0x04) == 0)	//Check whether the transmit buffer is locked or not.
	{
		return	1;
	}

   if((SendDataBuf[1]&0x10)==0)        //check the RTR bit
   { 
     TempCount =(SendDataBuf[1]&0x0f)+2;	//calculate the length of the data array
   }
   else
   {
     TempCount =2;	//remote frame
   }
   for(uctmp=0;uctmp<TempCount;uctmp++)
   {
     WriteSjaReg(REG_TxBuffer1+uctmp,SendDataBuf[uctmp]);
   }
   return 0;
}

/**
 * @brief Read the data array from the receive buffer.
 * 
 * The Function read the data from the receive buffer and save them to the specified data array.
 * 
 * @param RcvDataBuf The data array to save the data read from the recv buffer.
 * 
 * @return The result of the operation.
 * @retval 0 means receive successfully
 * @retval 1 means receive falsely
*/
 bit    BCAN_DATA_RECEIVE(unsigned char *RcvDataBuf)
 {
	uchar  TempCount,uctmp;
	if((ReadSjaReg(REG_STATUS)&0x01)==0)	//check the receive buffer is valid or not
	{
		return 1;
	}

	uctmp=ReadSjaReg(REG_RxBuffer2);	//read recv buffer 2
	if((uctmp&0x10)==0)	// check the RTR bit
	{
		TempCount=(uctmp&0x0f)+2;	//calculate the length of the data array
	}
	else
	{
		TempCount=2;
	}
	for(uctmp=0;uctmp<TempCount;uctmp++)
	{
		RcvDataBuf[uctmp]=ReadSjaReg(REG_RxBuffer1+uctmp);
	}
	return  0;
 }

/**
 * @brief Drive the CAN chip to do a command.
 * 
 * The Function write the command to the command register to drive the chip to do this command.
 * 
 * @param cmd The command to do.
 * 
 * @return The result of the operation.
 * @retval 0 means the command is done successfully
 * @retval 1 means the command is done falsely
*/
 bit  BCAN_CMD_PRG(unsigned char cmd)
 {
   WriteSjaReg(REG_COMMAND,cmd);
   switch(cmd)
   {
     case  TR_CMD:
           return    0;
           break;
     case  AT_CMD:
           if((ReadSjaReg(REG_STATUS) & 0x20)==0)
           {
              return  0;
           }
           else
           {
              return  1;
           }   
           break; 
     case  RRB_CMD:
           if((ReadSjaReg(REG_STATUS) & 0x01)==1)
           {
             return  1;
           }
           else
           {
              return  0;
           }   
           break; 
  
     case  COS_CMD:
           if((ReadSjaReg(REG_STATUS) & 0x02)==0)
           {
             return  0;
           }
           else
           {
              return  1;
           }   
           break; 
     
     case  GTS_CMD:
           return    0;
           break; 
     default:
             return  1;
             break; 
   }
 }

⌨️ 快捷键说明

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