// Header: 与CAN工作芯片SJA1000相关的函数
// File Name: CAN.C
// Author: wuzhe
// Date: 2015.7.19
#include <reg51.h>
#include <intrins.h>
#include <string.h>
#include "Basic_can.h"
unsigned char xdata *SJA1000_add; //SJA1000地址指针
unsigned char code rate_table[]={
0x53,0x2f, //20kbit/s
0x87,0xff,
0x47,0x2f, //50kbit/s
0x83,0xff,
0x43,0x2f, //100kbit/s
0x03,0x1c,
0x81,0xfa,
0x01,0x1c, //250kbit/s
0x80,0xfa,
0x00,0x1c, //500kbit/s
0x80,0xb6,
0x00,0x16,
0x00,0x14, //1Mbit/s
};
/*******************************************************
函数名称:bit create_communication(void)
函数功能: 在芯片的复位模式下,检测CAN控制器的通信是否正常
只用于产品测试,正常模式下不可对该寄存器操作
返回值说明:0 正常
1 不正常
********************************************************/
bit create_communication(void)
{
SJA1000_add=Bcan_test;
*SJA1000_add=0xaa;
if(*SJA1000_add==0xaa)
return 0;
else
return 1;
}
/********************************************************
函数名称: RST_SJA1000
函数功能:复位SJA1000芯片
函数参数:无
*********************************************************/
bit RST_SJA1000(void)
{
unsigned char Tempdata;
SJA1000_add=Bcan_cr; //将控制器的地址赋予指针
Tempdata = *SJA1000_add;
*SJA1000_add=(Tempdata|0x01); //给复位位写1 复位
if((*SJA1000_add&0x01)==1)
return 0;
else
return 1;
}
/********************************************************
函数名称: QRST_SJA1000
函数功能:退出SJA1000芯片复位模式
函数参数:无
*********************************************************/
bit QRST_SJA1000(void)
{
unsigned char Tempdata;
SJA1000_add=Bcan_cr; //将控制器的地址赋予指针
Tempdata = *SJA1000_add;
*SJA1000_add=(Tempdata&0xfe); //给复位位清零
if((*SJA1000_add&0x01)==0)
return 0;
else
return 1;
}
/********************************************************
函数名称: set_rate(unsigned char CAN_rate_num)
函数功能:设置CAN总线的波特率 只有在复位模式中有效
函数参数:CAN_rate_num用于存放波特率数组列表的序列号 0~12
返回值说明:0 成功
1 失败
*********************************************************/
bit set_rate(unsigned char CAN_rate_num)
{
bit wrong_flag=1;
unsigned char BTR0_data,BTR1_data;
unsigned char wrong_count =32;
if(CAN_rate_num>12) {wrong_flag=1;}
else {
while(--wrong_count)
{
BTR0_data=rate_table[CAN_rate_num*2];
BTR1_data=rate_table[CAN_rate_num*2+1];
SJA1000_add = Bcan_brt0;
*SJA1000_add = BTR0_data;
if(*SJA1000_add!=BTR0_data) continue;
SJA1000_add = Bcan_brt1;
*SJA1000_add = BTR1_data;
if(*SJA1000_add!=BTR1_data) continue;
wrong_flag=0;
break;
}
}
return wrong_flag;
}
/********************************************************
函数名称: bit set_ACR_AMR(unsigned char ACR_DATA,unsigned char AMR_DATA)
函数功能:设置验收滤波器和屏蔽寄存器的值
函数参数:ACR_DATA 验收滤波器的值
AMR_DATA 屏蔽寄存器的值
返回值说明:0 成功
1 失败
*********************************************************/
bit set_ACR_AMR(unsigned char ACR_DATA,unsigned char AMR_DATA)
{
SJA1000_add = Bcan_acr;
*SJA1000_add = ACR_DATA;
if(*SJA1000_add!=ACR_DATA) {return 1;}
SJA1000_add = Bcan_amr;
*SJA1000_add = AMR_DATA;
if(*SJA1000_add!=AMR_DATA) {return 1;}
return 0;
}
/********************************************************
函数名称: set_CLK(unsigned char mode,unsigned char set_clk_out)
函数功能:设置输出控制器和是时钟分频器
函数参数:mode 输出控制器的值
set_clk_out 时钟分频器的值
返回值说明:0 成功
1 失败
*********************************************************/
bit set_CLK(unsigned char mode,unsigned char set_clk_out)
{
SJA1000_add=Bcan_ocr;
*SJA1000_add=mode;
if(*SJA1000_add!=mode) {return 1;}
SJA1000_add=CDR;
*SJA1000_add=set_clk_out;
return 0;
}
/********************************************************
函数名称: bit SJA_send_data(unsigned char *senddatabuf)
函数功能:发送CAN总线的一帧信息
函数参数:senddatabuf发送数组的首地址
返回值说明:0 成功
1 失败
*********************************************************/
bit SJA_send_data(unsigned char *senddatabuf)
{
unsigned char sendnum,Tempdata;
SJA1000_add=Bcan_sr;
Tempdata = *SJA1000_add;
if(Tempdata&0x10) {return 1;} //正在接受
if((Tempdata&0x04)==0) {return 1;} //发送缓冲区已经被锁定
if((Tempdata&0x08)==0) {return 1;} //上次的发送未完成
SJA1000_add=Bcan_TXbuffer1;
if((senddatabuf[1]&0x10)==0)
{
sendnum=(senddatabuf[1]&0x0f) +2; //数据帧
}
else
{
sendnum =2 ; //远程帧 发送的数据长度为2
}
memcpy(SJA1000_add,senddatabuf,sendnum);
return 0;
}
/********************************************************
函数名称: bit SJA_rcv_data(unsigned char *rcvdatabuf)
函数功能:接收CAN总线的一帧信息
函数参数:rcvdatabuf接收数组的首地址
返回值说明:0 成功
1 失败
*********************************************************/
bit SJA_rcv_data(unsigned char *rcvdatabuf)
{
unsigned char rcvnum;
//SJA1000_add =Bcan_sr;
//if((*SJA1000_add&0x01)==0) {return 1;}//判断接受缓冲器重是否有信息
SJA1000_add = Bcan_RXbuffer2;
if((*SJA1000_add&0x10)==0)
{
rcvnum=(*SJA1000_add&0x0f)+2;
}
else
{
rcvnum=2;
}
SJA1000_add = Bcan_RXbuffer1;
memcpy(rcvdatabuf,SJA1000_add,rcvnum);
return 0;
}
/********************************************************
函数名称: bit SJA_rcv_data(unsigned char *rcvdatabuf)
函数功能:接收CAN总线的一帧信息
函数参数:rcvdatabuf接收数组的首地址
返回值说明:0 成功
1 失败
*********************************************************/
bit SJA_command_control(unsigned char order)
{
unsigned char STATUS_data;
SJA1000_add = Bcan_cmr;
*SJA1000_add = order;
switch(order)
{
case TR_req: //发送请求
return 0;
break;
case AT_req: //中止发送命令
SJA1000_add = Bcan_sr;
STATUS_data= *SJA1000_add;
if((STATUS_data&0x20)==0) {return 0;}
else {return 1;}
break;
case RRB_req: //s释放接收缓冲区命令
SJA1000_add = Bcan_sr;
STATUS_data= *SJA1000_add;
if((STATUS_data&0x01)==1) {return 1;}
else {return 0;}
case CD0_req:
SJA1000_add = Bcan_sr;
STATUS_data= *SJA1000_add;
if((STATUS_data&0x02)==0) {return 0;}
else {return 1;}
case GTS_req:
return 0;
break;
default:
return 1;
break;
}
}