📄 sja1000.c
字号:
*SJA_BCANAdr=(TempData|0x01); //置位复位请求
if((*SJA_BCANAdr&0x01) == 1)
{
return 0;
}
else
{
return 1;
}
}
/************************************************************************
*说明: CAN控制器退出复位工作模式 *
************************************************************************/
bit 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; //退出成功
}
}
/************************************************************************
;*说明:设置CAN控制器SJA1000通信波特率.SJA1000的晶振为必须为16MHZ, *
;* 其它晶体的频率的值的波特率,需自己计算 。该子程序只能用于 *
;* 复位模式 *
;************************************************************************/
uchar 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的预设值
0x00,0x14 //;1000KBPS的预设值
};
bit SET_BANDRATE(uchar CAN_bps)
{
uchar BTR0_num,BTR1_num;
BTR0_num = SJA_BTR_CODETAB[CAN_bps*2];
BTR1_num = SJA_BTR_CODETAB[CAN_bps*2+1];
//将波特率的的预设值装入sja1000的总线定时器
SJA_BCANAdr=REG_BTR0; //访问地址指向总线定时寄存器0
*SJA_BCANAdr=BTR0_num; //写入参数
if(*SJA_BCANAdr != BTR0_num) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_BTR1; //访问地址指向总线定时寄存器1
*SJA_BCANAdr=BTR1_num; //写入参数
if(*SJA_BCANAdr != BTR1_num) //校验写入值
{
return 1;
}
return 0;
}
/************************************************************************
;*说明:设置CAN节点的通讯对象,允许接收的报文ID号的高8位(D10--D3) 。 *
;* 允许接收的报文,是由AMR和ACR共同决定的. *
;* 满足以下条件的ID号的报文才可以被接收 *
;*[(ID.10-ID.3)≡(AC.7-AC.0)]||(AM.7-AM.0)≡11111111 *
;* 该子程序只能用于复位模式 * *
;************************************************************************/
bit SET_OBJECT(uchar BCAN_ACR,uchar BCAN_AMR)
{
SJA_BCANAdr=REG_ACR; //访问地址指向验收代码寄存器(ACR)
*SJA_BCANAdr=BCAN_ACR; //写入参数
if(*SJA_BCANAdr != BCAN_ACR) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_AMR; //访问地址指向验收屏蔽寄存器(AMR)
*SJA_BCANAdr=BCAN_AMR; //写入参数
if(*SJA_BCANAdr != BCAN_AMR) //校验写入值
{
return 1;
}
return 0;
}
/************************************************************************
;*说明:设置SJA1000的输出模式和时钟分频 。该子程序只能用于复位模式 * *
;************************************************************************/
bit SET_OUTCLK (uchar Out_Control,uchar Clock_Out)
{
SJA_BCANAdr=REG_OCR ; //访问地址指向输出控制寄存器
*SJA_BCANAdr=Out_Control; //写入参数
if(*SJA_BCANAdr != Out_Control) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_CDR; //访问地址指向时钟分频寄存器
*SJA_BCANAdr=Clock_Out; //写入参数
return 0;
}
/***********************************************************************
*说明:CAN控制器的初始化只能在复位模式下才能完成。初始化操作之前请先进入*
* 到复位操作模式,并将要初始化的各参数的值按数据手册中的计算方法,正 *
* 确的按实际需要计算好参数后,将参数写入对应的寄存器 。 *
************************************************************************/
bit HW_INIT(uchar BCAN_ACR,uchar BCAN_AMR,uchar Bus_Timing0,
uchar Bus_Timing1,uchar Out_Control,uchar Clock_Out)
{
SJA_BCANAdr=REG_ACR; //访问地址指向验收代码寄存器(ACR)
*SJA_BCANAdr=BCAN_ACR; //写入参数
if(*SJA_BCANAdr != BCAN_ACR) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_AMR; //访问地址指向验收屏蔽寄存器(AMR)
*SJA_BCANAdr=BCAN_AMR; //写入参数
if(*SJA_BCANAdr != BCAN_AMR) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_BTR0; //访问地址指向总线定时寄存器0
*SJA_BCANAdr=Bus_Timing0; //写入参数
if(*SJA_BCANAdr != Bus_Timing0) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_BTR1; //访问地址指向总线定时寄存器1
*SJA_BCANAdr=Bus_Timing1; //写入参数
if(*SJA_BCANAdr != Bus_Timing1) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_OCR ; //访问地址指向输出控制寄存器
*SJA_BCANAdr=Out_Control; //写入参数
if(*SJA_BCANAdr != Out_Control) //校验写入值
{
return 1;
}
SJA_BCANAdr=REG_CDR; //访问地址指向时钟分频寄存器
*SJA_BCANAdr=Clock_Out; //写入参数
return 0;
}
/************************************************************************
*说明: 将待发送特定帧各式的数据,送入SJA1000发送缓存区中,然后启动 *
* SJA1000发送。 *
* 特定帧格式为:开始的两个字节存放 '描述符' ,以后的为数据 *
* 描述符包括11位长的ID(标志符)\1位RTR\4位描述数据长度的DLC共16位 *
************************************************************************/
bit DATA_WRITE(uchar *SendDataBuf)
{
uchar TempCount;
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x08) == 0) //判断上次发送是否完成
{
return 1;
}
if((*SJA_BCANAdr&0x04)==0) //判断发送缓冲区是否锁定
{
return 1;
}
SJA_BCANAdr = REG_TxBuf1; //访问地址指向发送缓冲区1
if((SendDataBuf[1]&0x10)==0) //判断RTR,从而得出是数据帧还是远程帧
{
TempCount =(SendDataBuf[1]&0x0f)+2; //输入数据帧
}
else
{
TempCount =2; //远程帧
}
memcpy(SJA_BCANAdr,SendDataBuf,TempCount);
return 0;
}
/************************************************************************
*说明:CAN控制器接收数据,仅限于接收数据 *
************************************************************************/
bit RECEIVE(uchar *RcvDataBuf)
{
uchar TempCount;
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr&0x01)==0) //判断报文是否有效
{
return 1;
}
SJA_BCANAdr = REG_RxBuf2; //访问地址指向接收缓冲区2
if((*SJA_BCANAdr&0x10)==0) //如果是数据帧
{
TempCount=(*SJA_BCANAdr&0x0f)+2; //计算报文中数据的个数
}
else
{
TempCount=2;
}
SJA_BCANAdr = REG_RxBuf1; //访问地址指向接收缓冲区1
memcpy(RcvDataBuf,SJA_BCANAdr,TempCount); //读取接收缓冲区的报文
return 0;
}
/************************************************************************
*说明: 执行sja1000命令 *
************************************************************************/
bit CMD_PRG(uchar cmd)
{
SJA_BCANAdr=REG_COMMAND; //访问地址指向命令寄存器
*SJA_BCANAdr=cmd; //启动命令字
switch(cmd)
{
case TR_CMD: //发送请求命令
return 0;
break;
case AT_CMD: //夭折发送命令
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x20)==0) //判断是否正在发送
{
return 0;
}
else
{
return 1;
}
break;
case RRB_CMD: //释放接收缓冲区
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 0x01)==1) //判断是否释放成功
{
return 1;
}
else
{
return 0;
}
break;
case COS_CMD: //清除超载状态
SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
if((*SJA_BCANAdr & 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 + -