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

📄 basiccan.c

📁 基于51单片机的CAN总线节点程序
💻 C
📖 第 1 页 / 共 3 页
字号:
		 #include<reg52.h>
#include <string.h>

#define uchar unsigned char 
#define uint unsigned int 


#define         SJA_BaseAdr       0x0000     //定义sja1000的片选基址

//计算SJA1000在电路中的实际地址:基址+内部寄存器地址

/************************************************************************
 * 以下的定义为SJA1000的内部寄存器的地址,不可修改                      *
 *     各寄存器的具体功能清参阅sja1000的数据手册                        *
 ************************************************************************/
#define         REG_CONTROL       SJA_BaseAdr+0x00       //内部控制寄存器

#define         REG_COMMAND       SJA_BaseAdr+0x01       //命令寄存器

#define         REG_STATUS        SJA_BaseAdr+0x02       //状态寄存器

#define         REG_INTERRUPT     SJA_BaseAdr+0x03       //中断寄存器

#define         REG_ACR           SJA_BaseAdr+0x04       //验收代码寄存器

#define         REG_AMR           SJA_BaseAdr+0x05       //验收屏蔽寄存器

#define         REG_BTR0          SJA_BaseAdr+0x06       //总线定时寄存器0 

#define         REG_BTR1          SJA_BaseAdr+0x07       //总线定时寄存器1 

#define         REG_OCR           SJA_BaseAdr+0x08       //输出控制寄存器

#define         REG_TEST          SJA_BaseAdr+0x09       //测试寄存器
  

//以下为发送缓冲区寄存器定义

#define         REG_TxBuffer1     SJA_BaseAdr+0x0A         //发送缓冲区1
#define         REG_TxBuffer2     SJA_BaseAdr+0x0B         //发送缓冲区2
#define         REG_TxBuffer3     SJA_BaseAdr+0x0C         //发送缓冲区3
#define         REG_TxBuffer4     SJA_BaseAdr+0x0D         //发送缓冲区4
#define         REG_TxBuffer5     SJA_BaseAdr+0x0E         //发送缓冲区5
#define         REG_TxBuffer6     SJA_BaseAdr+0x0F         //发送缓冲区6
#define         REG_TxBuffer7     SJA_BaseAdr+0x10         //发送缓冲区7
#define         REG_TxBuffer8     SJA_BaseAdr+0x11         //发送缓冲区8
#define         REG_TxBuffer9     SJA_BaseAdr+0x12         //发送缓冲区9
#define         REG_TxBuffer10    SJA_BaseAdr+0x13         //发送缓冲区10

//以下为接收缓冲区寄存器定义
#define         REG_RxBuffer1     SJA_BaseAdr+0x14         //接收缓冲区1
#define         REG_RxBuffer2     SJA_BaseAdr+0x15         //接收缓冲区2
#define         REG_RxBuffer3     SJA_BaseAdr+0x16         //接收缓冲区3
#define         REG_RxBuffer4     SJA_BaseAdr+0x17         //接收缓冲区4
#define         REG_RxBuffer5     SJA_BaseAdr+0x18         //接收缓冲区5
#define         REG_RxBuffer6     SJA_BaseAdr+0x19         //接收缓冲区6
#define         REG_RxBuffer7     SJA_BaseAdr+0x1A         //接收缓冲区7
#define         REG_RxBuffer8     SJA_BaseAdr+0x1B         //接收缓冲区8
#define         REG_RxBuffer9     SJA_BaseAdr+0x1C         //接收缓冲区9
#define         REG_RxBuffer10    SJA_BaseAdr+0x1D         //接收缓冲区10

/************************************************************************
 *内部地址 01EH 备用                                                    *
 ************************************************************************/

/************************************************************************
 *时钟分频寄存器(内部地址01FH)                                          *
 ************************************************************************/
#define         REG_CDR           SJA_BaseAdr+0x1F          //时钟分频寄存器


uchar xdata  *SJA_BCANAdr;//定义指向片外RAM的指针(SJA1000的基址)

static uchar data BandRateBuf;//用于保存当前要设置的波特率

static uchar idata send_data[10];//用于缓存将要发送的数据

static uchar idata code_led[20]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x67,0x77,0x7C,0x39,0x5E,0x79,0x71,0x40,0x76,0x73,0x38};
	   //依次表示0,1,2,3,4,5,6,7,8,9,A,b,C,d,E,F,-,H,P,L

	   
static uchar data SetSystemBuf[4]={0,0,0,0};//用于显示的数据缓冲区

static uint idata band_rate[13]={20,40,50,80,100,125,200,250,400,500,666,800,1000};//用于显示选择的波特率



sbit P20=P2^0;

sbit sja=P2^0;

sbit P32=P3^2;

sbit P17=P1^7;//74LS373N的选通信号

sbit P14=P1^4;//LED灯的选择信号
sbit P15=P1^5;

sbit P16=P1^6;//蜂鸣器的选通信号

sbit ST=P3^0;//ADC0809的选通信号
sbit OE=P3^1;

/************************************************************************
 *定义命令字                                                            *
 ************************************************************************/ 
#define         TR_CMD           0x01          //发送请求命令
#define         AT_CMD           0x02          //夭折发送命令
#define         RRB_CMD          0x04          //释放接收缓冲区
#define         COS_CMD          0x08          //清除超载状态
#define         GTS_CMD          0x10          //进入睡眠状态命令  

/************************************************************************
 *定义16M的晶体下,CAN总线波特率                                        *
 ************************************************************************/
#define         ByteRate_20k      0x00          //波特率20kbps
#define         ByteRate_40k      0x01          //波特率40kbps
#define         ByteRate_50k      0x02          //波特率50kbps
#define         ByteRate_80k      0x03          //波特率80kbps
#define         ByteRate_100k     0x04          //波特率100kbps
#define         ByteRate_125k     0x05          //波特率125kbps
#define         ByteRate_200k     0x06          //波特率200kbps
#define         ByteRate_250k     0x07          //波特率250kbps
#define         ByteRate_400k     0x08          //波特率400kbps
#define         ByteRate_500k     0x09          //波特率500kbps
#define         ByteRate_666k     0x0a          //波特率666kbps
#define         ByteRate_800k     0x0b          //波特率800kbps
#define         ByteRate_1000k    0x0c          //波特率1000kbps

/*-------------------------------------------------------------------------------------------
 *  以下为BASICCAN SJA1000的错误字                                                          *
 -------------------------------------------------------------------------------------------*/
#define     CAN_INTERFACE_0K    0                /*SJA1000接口正常                       */
#define     CAN_BUS_0K          0                /*CAN总线工作正常                       */
#define     CAN_INTERFACE_ERR   0XFF             /*SJA1000接口错误?                     */
#define     CAN_ENTRESET_ERR    0XFE             /*SJA1000不能进入复位模式   */
#define     CAN_QUITRESET_ERR   0XFD             /*SJA1000不能退出复位模式       */
#define     CAN_INITOBJECT_ERR  0XFC             /*初始化报文验收滤波器错    */
#define     CAN_INITBTR_ERR     0XFB             /*初始化总线波特率错          */
#define     CAN_INITOUTCTL_ERR  0XFA             /*初始化输出控制错误            */
#define     CAN_INTCLKDIV_ERR   0XF9             /*初始化时钟分频控制器错        */
#define     CAN_BUS_ERR         0XF8             /*SJA1000发送数据错                     */


//延时
void delay_ms(uint n)
{
	uint k,j;
	for(k=0;k<n;k++)
		{
			for(j=0;j<500;j++);
		}
}

/************************************************************************
 *以下为基本的函数说明(BasicCAN)                                       *
 ************************************************************************/

/************************************************************************
 *函数原型:  bit   BCAN_CREATE_COMMUNATION(void)                        * 
 *参数说明:  无                                                         *
 *返回值:                                                               *
 *           0 ; 表示SJA1000接口正常                                    *
 *           1 ; 表示SJA1000与处理器接口不正常                          *
 *                                                                      * 
 *说明:该函数用于检测CAN控制器的接口是否正常                            *
 ************************************************************************/
 bit   BCAN_CREATE_COMMUNATION(void)
 {  
    SJA_BCANAdr=REG_TEST;                     //访问测试寄存器            
    
    *SJA_BCANAdr   =0xaa;                     //写入测试值
    if(*SJA_BCANAdr == 0xaa)
    {
        return    0;                          //读测试正确
    }
    else
    {    
       return    1;
    } 
 }       

/************************************************************************
 *函数原型:      bit   BCAN_ENTER_RETMODEL(void)                        *
 *参数说明:  无                                                         *
 *返回值:                                                               *
 *           0 ; 表示成功进入复位工作模式                               *
 *           1 ; 表示不能进入复位工作模式                               *
 *                                                                      * 
 *说明:      CAN控制器进入复位工作模式                                  *
 ************************************************************************/ 
 bit   BCAN_ENTER_RETMODEL(void)
 {
    uchar   TempData;
    SJA_BCANAdr  = REG_CONTROL;                   //访问地址指向控制寄存器 
    TempData=  *SJA_BCANAdr;                      //保存原始值
    *SJA_BCANAdr=(TempData|0x01);                 //置位复位请求
    if((*SJA_BCANAdr&0x01) == 1)
    {
       return   0;
    }
    else
    {
       return   1;
    }
    
 }

/************************************************************************
 *函数原型:      bit   BCAN_QUIT_RETMODEL(void)                         *
 *参数说明:  无                                                         *
 *返回值:                                                               *
 *           0 ; 表示成功退出复位工作模式                               *
 *           1 ; 表示不能退出复位工作模式                               *
 *                                                                      * 
 *说明:      CAN控制器退出复位工作模式                                  *
 ************************************************************************/ 
 bit   BCAN_QUIT_RETMODEL(void)
 {
    uchar   TempData;
    SJA_BCANAdr = REG_CONTROL;                   //访问地址指向控制寄存器 
    TempData    = *SJA_BCANAdr;                  //保存原始值
    *SJA_BCANAdr=(TempData&0xfe);       		 //清除复位请求
    if((*SJA_BCANAdr&0x01) == 0)
    {
       return   0;                               //退出成功
    }
    else
    {
       return   1;                              //
    }

 }

 /************************************************************************
;*函数原型:   bit   BCAN_SET_BANDRATE(uchar CAN_ByteRate)       *
;*参数说明:  R7            波特率(Kbit/s) BTR0     BTR1               *
;*           0	            20              053H,    02FH                *
;*           1	            40              087H,    0FFH               *  
;*           2	            50              047H,    02FH               *
;*           3	            80              083H,    0FFH                *
;*           4	            100             043H,    02fH                *
;*           5	            125             03H,     01cH                 *
;*           6              200             081H,    0faH               *
;*           7	            250             01H,     01cH            *
;*           8	            400             080H,    0faH                *
;*           9	            500             00H,     01cH               *
;*           10	            666             080H,    0b6H                 *
;*           11	            800             00H,     016H             *
;*           12	            1000            00H,     014H                  *
;*返回值:                                                               *
;*           0 ;波特率设置成功                                          *
;*           1 ;波特率设置失败                                          *
;*                                                                      * 
;*说明:设置CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ,       *
;*     其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于        *
;*     复位模式                                                         *  
;************************************************************************/
unsigned  char	code	SJA_BTR_CODETAB[]={
    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的预设值
    0x80,0x23                     //;1000KBPS的预设值
   
};

bit   BCAN_SET_BANDRATE(uchar CAN_ByteRate)
{
  uchar  BTR0_num,BTR1_num;
  BTR0_num = SJA_BTR_CODETAB[CAN_ByteRate*2];
  BTR1_num = SJA_BTR_CODETAB[CAN_ByteRate*2+1];
  //将波特率的的预设值装入sja1000的总线定时器
  SJA_BCANAdr=REG_BTR0;          		//访问地址指向总线定时寄存器0
  *SJA_BCANAdr=BTR0_num;      			//写入参数
  if(*SJA_BCANAdr != BTR0_num)			//校验写入值
  {
    return  1; 
  }
  SJA_BCANAdr=REG_BTR1;         		//访问地址指向总线定时寄存器0
  *SJA_BCANAdr=BTR1_num;      			//写入参数
  if(*SJA_BCANAdr != BTR1_num)			//校验写入值
  {
    return  1; 
  }

  return    0;

⌨️ 快捷键说明

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