您的位置 首页 开关

SJA1000+C51

#includeCANBUS.H//————————————-definevariable——————————-

#include “CANBUS.H”

//————————————-define variable————————————
unsigned char receive_counter = 0;
unsigned char alc = 1;
unsigned char ecc = 1;

/************************************************************************
*函数原型: bit CAN_CREATE_COMMUNATION(void)
*参数阐明: 无
*回来值:*
* 0 ; 表明SJA1000接口正常
* 1 ; 表明SJA1000与处理器接口不正常
*
*阐明:该函数用于检测CAN操控器的接口是否正常
************************************************************************/
bit CAN_CREATE_COMMUNATION(void)
{
unsigned char temp_data;
bit Flag;
REG_TEST = 0xAA; //写入测验值
temp_data = REG_TEST;
if(temp_data == 0xaa)
{
Flag=0; //读测验正确
}
else
{
Flag=1;
}
if(!Flag)
{
REG_TEST = 0x55; //写入测验值
temp_data = REG_TEST;
if(temp_data == 0x55)
{
Flag=0; //读测验正确
REG_TEST = 0x00;
}
else
{
Flag=1;
}
}
return (Flag);
}
/************************************************************************
*函数原型: bit CAN_ENTRY_RETMODEL(void) *
*参数阐明: 无 *
*回来值: *
* 0 ; 表明成功进入复位作业形式 *
* 1 ; 表明不能进入复位作业形式 *
* *
*阐明: CAN操控器进入复位作业形式 *
************************************************************************/
bit CAN_ENTRY_RETMODEL(void)
{
bit flag;
unsigned char ErrorCount=20;
unsigned char temp_data = REG_MODE;
while(ErrorCount –)
{
REG_MODE = temp_data|RM_MODE;
temp_data = REG_MODE;
if( (temp_data & RM_MODE) != 0)
{
flag=0;
break;
}
else
{
flag=1;
}
}
return(flag);
}

/************************************************************************
*函数原型: bitCAN_QUIT_RETMODEL(void)
*参数阐明: 无
*回来值:
* 0 ; 表明成功退出复位作业形式
* 1 ; 表明不能退出复位作业形式
*阐明: CAN操控器退出复位作业形式
***********************************************************************/
bit CAN_QUIT_RETMODEL(void)
{
bit flag;
unsigned char ErrorCount=20;
unsigned char temp_data = REG_MODE;
while(ErrorCount –)
{
REG_MODE = temp_data&0xfe;
temp_data = REG_MODE;
if((temp_data&0x01) == 0)
{
flag=0;
break;
}
else
{
flag=1;
}
}
return(flag);
}

/*********************************************************************************
**函数原型: char SJASetBandRateStandard(unsigned char BandRateSize)
**参数阐明: BandRateSize 规范常用波特率(Kbps)
** 0 5
** 1 10
** 2 20
** 3 40
** 4 50
** 5 80
** 6 100
** 7 125
** 8 200
** 9 250
** 10 400
** 11 500
** 12 666
** 13 800
** 14 1000
**回来值:
** 0 ; 设置总线定时器成功
** SJA_SETBTR_ERR ; 设置总线定时器错
** SJA_NOBTRSIZE ;波特率不能设为此值
**
**阐明: 该函数用于设定在体系晶体为16MHZ时,常用的规范波特率的值。
** 参数BandRateSize只能为0~14,其它的值会回来SJA_NOBTRSIZE过错
** 本函数只能用于复位形式
***************************************************************************************/
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的预设值
};
bit CAN_SET_BANDRATE(unsigned char CAN_ByteRate)
{
bit ErrorFlag =1;
unsigned char temp_data;
unsigned char ErrorCount = 0x20; //32次报错
if(CAN_ByteRate>14)
{
ErrorFlag =1;
}
else{
while(–ErrorCount)
{
REG_BTR0 = SJA_BTR_CODETAB[CAN_ByteRate*2];
REG_BTR1 = SJA_BTR_CODETAB[CAN_ByteRate*2+1];
temp_data = REG_BTR0;
if(temp_data != SJA_BTR_CODETAB[CAN_ByteRate*2])
{
continue;
}
temp_data = REG_BTR1;
if(temp_data != SJA_BTR_CODETAB[CAN_ByteRate*2+1])
{
continue;
}
ErrorFlag=0;
break;
}//while完毕

}
return ErrorFlag ;
}

/*************************************************************************
*函数原型:CAN_SET_OBJECT
*参数阐明:
* CAN_ACR0-3:寄存检验代码寄存器(ACR)的参数设置
* CAN_AMR0-3:寄存接纳屏蔽寄存器(AMR)的参数设置
*回来值:
* 0 ;通讯目标设置成功
* 1 ;通讯目标设置失利
*阐明:设置CAN节点的通讯目标,答应接纳的报文ID号
* 答应接纳的报文,是由AMR和ACR一起决议的.
* 满意以下条件的ID号的报文才能够被接纳
*[(ID.29-ID.0)≡(AC.29-AC.0)]||(AM.29-AM.0)≡11111111
* 该子程序只能用于复位形式 *
*************************************************************************/
bit CAN_SET_OBJECT(unsigned char CAN_ACR0,unsigned char CAN_ACR1,
unsigned char CAN_ACR2,unsigned char CAN_ACR3,
unsigned char CAN_AMR0,unsigned char CAN_AMR1,
unsigned char CAN_AMR2,unsigned char CAN_AMR3)
{
bit ErrorFlag =1;
unsigned char temp_data;
unsigned char ErrorCount = 0x20; //32次报错
while(ErrorCount–)
{
REG_ACR0 = CAN_ACR0;
REG_ACR1 = CAN_ACR1;
REG_ACR2 = CAN_ACR2;
REG_ACR3 = CAN_ACR3;
REG_AMR0 = CAN_AMR0;
REG_AMR1 = CAN_AMR1;
REG_AMR2 = CAN_AMR2;
REG_AMR3 = CAN_AMR3;

temp_data = REG_ACR0;
if(temp_data!= CAN_ACR0) //校验写入值
{
continue;
}
temp_data = REG_ACR1;
if(temp_data!= CAN_ACR1) //校验写入值
{
continue;
}
temp_data = REG_ACR2;
if(temp_data != CAN_ACR2) //校验写入值
{
continue;
}
temp_data = REG_ACR3;
if(temp_data != CAN_ACR3) //校验写入值
{
continue;
}
temp_data = REG_AMR0;
if(temp_data != CAN_AMR0) //校验写入值
{
continue;
}
temp_data = REG_AMR1;
if(temp_data != CAN_AMR1) //校验写入值
{
continue;
}
temp_data = REG_AMR2;
if(temp_data != CAN_AMR2) //校验写入值
{
continue;
}
temp_data = REG_AMR3;
if(temp_data != CAN_AMR3) //校验写入值
{
continue;
}
ErrorFlag =0;
break;
}
return ErrorFlag;
}
/************************************************************************
*函数原型: bit CAN_SET_OUTCLK(unsigned char Out_Control,unsigned char Clock_Out);
*参数阐明:
* Out_Control:寄存输出操控寄存器 (OCR)的参数设置
* Clock_Out:寄存时钟分频寄存器 (CDR) 的参数设置
*
*回来值:
* 0 ;设置成功
* 1 ;设置失利
*
*阐明:设置SJA1000的输出形式和时钟分频 。该子程序只能用于复位形式 *
************************************************************************/
bit CAN_SET_OUTCLK (unsigned char Out_Control,unsigned char Clock_Out)
{
bit ErrorFlag =1;
unsigned char temp_data;
unsigned char ErrorCount = 0x20; //32次报错
while(ErrorCount–)
{
REG_OCR = Out_Control;
REG_CDR = Clock_Out;
temp_data = REG_OCR;
if(temp_data != Out_Control) //校验写入值
{
continue;
}
temp_data = REG_CDR;
if(temp_data != Clock_Out) //校验写入值
{
continue;
}
ErrorFlag =0;
break;
}
return ErrorFlag;
}
/************************************************************************
*函数原型: bitSJA_Init(void)
*参数阐明: 无
*回来值:
* 0 ; 表明初始化CAN成功
* 1 ; 表明不能初始化CAN
* 不同的要求需求修正
*阐明: 初始化CAN操控器波特率 分频和输出方法 ACK AMR等
***********************************************************************/
void SJA_Init(void)
{
unsigned char temp_data;
bit flag;
delay(125);
SJARst = 0;
delay(125);
SJARst = 1;
delay(125);

//write 0xaa 0x55 to REG_TEST
flag = CAN_CREATE_COMMUNATION();
if(flag)
{
ERR_flag = hard_ERR;
goto EXIT;
}

flag = CAN_ENTRY_RETMODEL();
if(flag) //复位形式中
{
ERR_flag = Init_ERR;
goto EXIT;
}

flag = CAN_SET_BANDRATE(ByteRate_500k);
if(flag)
{
ERR_flag = Init_ERR;
goto EXIT;
}
flag = CAN_SET_OUTCLK(0x1a,0xc8);
if(flag) //输出正常形式 推免方法 TX0
{ //CDR.7=1 pelican形式 CDR.6=1只要RX0被激活 关clockout
ERR_flag = Init_ERR;
goto EXIT;
}

REG_RBSA = 0x00;

//ACR and AMR
flag = CAN_SET_OBJECT(0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00);
if(flag)
{
ERR_flag = Init_ERR;
goto EXIT;
}

REG_IR_ABLE = 0x89; //中止使能

//REG_MODE = 0x0c; //mod.2=1进入自接纳形式 mod.3挑选单个检验滤波器(32bit)
REG_MODE = AFM_MODE;
REG_MODE = AFM_MODE; //mod.2=0正常形式 mod.3挑选单个检验滤波器(32bit)
flag = CAN_QUIT_RETMODEL();
if(flag)
{
ERR_flag = Init_ERR;
goto EXIT;
}

delay(100);
CAN_node_ID();
Rx_node_Num();
EXIT: return ;
}

/************************************************************************
*函数原型: bit Rx_node_Num( )
*参数阐明: no
*回来值:
* 此函数能够依据用户需在更改和删去
*阐明:装备CAN操控器接纳缓冲器状况
************************************************************************/
void Rx_node_Num()
{ // 假如RX信息计数器为空则LED0亮
unsigned char temp_Num;
temp_Num = REG_Receive_Counter;
if(temp_Num == 0)
{
LED0 = OFF;
}
else LED0 = ON;
return ;
}

/************************************************************************
*函数原型: can_test( )
*参数阐明: no
*回来值:
* 此函数能够依据用户需在更改和删去
*阐明:只用于硬件测验,悉数CAN装备在内,只用此函数只可测验节点状况
************************************************************************/
void can_test(void)
{
unsigned char temp_data;
temp_data = REG_SR;
if((temp_data & DOS_SR) == DOS_SR) //数据溢出状况
{
REG_CMD |= 0x0c; //clear over status and realve RX_FIFO
REG_CMD |= 0x0c;
}
if((temp_data & TBS_SR) == TBS_SR) //发送缓冲区状况 1开释
{
REG_RxBuffer0 = 0x88; //EFF 规范帧SFF,长度为8
// REG_RxBuffer1=0x00;
// REG_RxBuffer2=0x00;
// REG_RxBuffer3=0x00;
// REG_RxBuffer4=0x08; //ID.4-ID.0 and bit2~0 no use

REG_DataBuffer1 = x;
REG_DataBuffer2 = i;
REG_DataBuffer3 = a;
REG_DataBuffer4 = o;
REG_DataBuffer5 = z;
REG_DataBuffer6 = h;
REG_DataBuffer7 = a;
REG_DataBuffer8 = o;
}
CAN_cmd(TR_CMD); //TX request 恳求
temp_data = REG_SR;
temp_data &= TBS_SR; //TX buffer status 发送状况
while(temp_data == TBS_SR) //查看是否发送完结
{
ecc = REG_ECC;
temp_data = REG_SR;
temp_data &= 0X20;
}
}
/************************************************************************
*函数原型: Rx_Data( )
*参数阐明: no
*回来值:
* 设置不同的缓冲区需修正不同的接纳缓冲变量
*阐明: 界说了Rx_buffer缓冲区
************************************************************************/
void Rx_Data()
{
unsigned char temp_data;
temp_data = REG_SR;
F0 = 1;
if((temp_data & RBS_SR) == 0) //RBS Rx buffer status 1-RXFIFO have message
{
goto EXIT1;
}
Rx_buffer.dlen = REG_RxBuffer0; //node message
temp_data = Rx_buffer.dlen;

Rx_buffer.did1 = REG_RxBuffer1; //node message ID
Rx_buffer.did2 = REG_RxBuffer2;
Rx_buffer.did3 = REG_RxBuffer3;
Rx_buffer.did4 = REG_RxBuffer4;

temp_data = Rx_buffer.dlen;
if( (temp_data & 0x40) == 0x00)
{
Rx_buffer.ddata[0] = REG_DataBuffer1; //message data
Rx_buffer.ddata[1] = REG_DataBuffer2;
Rx_buffer.ddata[2] = REG_DataBuffer3;
Rx_buffer.ddata[3] = REG_DataBuffer4;
Rx_buffer.ddata[4] = REG_DataBuffer5;
Rx_buffer.ddata[5] = REG_DataBuffer6;
Rx_buffer.ddata[6] = REG_DataBuffer7;
Rx_buffer.ddata[7] = REG_DataBuffer8;
F0 = 0;
}
//F0 = 0; //realve Rx buffer succefe
CAN_cmd(RRB_CMD); //send realve commd to SJA1000
EXIT1: return;
}
/************************************************************************
*函数原型: bit CAN_node_ID( )
*参数阐明: no
*回来值:
* 此函数能够依据用户需在更改
*阐明:装备CAN操控器辨认符ID,为了便于测验装备REG_CAN_TXBUF3为开关ID
************************************************************************/
void CAN_node_ID(void)
{
unsigned char idata temp_data;
P1 = 0xf8;
temp_data = P1;
temp_data = (temp_data >> 3);
if( (temp_data & 0x1F) > 0x09 )
{
temp_data = (temp_data & 0x1F) + 0x37;
}
else temp_data = (temp_data & 0x0F) + 0x30;
REG_TxBuffer0 = 0x80; //frame is EFF data leng is 0
REG_TxBuffer1 = 0x00;
REG_TxBuffer2 = 0x00;
REG_TxBuffer3 = temp_data;
REG_TxBuffer4 = 0x00; //ID.4-ID.0 and bit2~0 no use
}
/************************************************************************
*函数原型: Tx_data( )
*参数阐明: no
*回来值:
* 此函数能够依据用户需在更改
*阐明:由全局变量Tx_buffer作缓冲,接纳CAN读出的信息.
************************************************************************/
void Tx_data()
{
unsigned char temp_data;
temp_data = REG_SR;
F0 = 1;
if( (temp_data & TCS_SR) == 0)
{
ERR_flag = no_TCS;
goto EXIT2;
}
if( (temp_data & TBS_SR)== TBS_SR ) //Tx buffer is empty?
{
REG_TxBuffer0 |= (Tx_buffer.dlen & 0x0F); //EFF 规范帧SFF,长度为8

REG_DataBuffer1 = Tx_buffer.ddata[0];
REG_DataBuffer2 = Tx_buffer.ddata[1];
REG_DataBuffer3 = Tx_buffer.ddata[2];
REG_DataBuffer4 = Tx_buffer.ddata[3];
REG_DataBuffer5 = Tx_buffer.ddata[4];
REG_DataBuffer6 = Tx_buffer.ddata[5];
REG_DataBuffer7 = Tx_buffer.ddata[6];
REG_DataBuffer8 = Tx_buffer.ddata[7];
CAN_cmd(TR_CMD); //TR=1
F0 = 0;
}
else ERR_flag = no_TBS;
EXIT2: return ;
}

/************************************************************************
*函数原型: bit CAN_cmd( )
*参数阐明: no
*回来值:
* 此函数能够依据用户需在更改和删去
*阐明: 写指令操作
************************************************************************/
void CAN_cmd(unsigned char cmd)
{
REG_CMD = cmd;
}

/************************************************************************
*函数原型: SJA_ERR( )
*参数阐明: no
*回来值:
* 此函数能够依据用户需在更改和删去
*阐明:仿真时能够知道出象牙在哪里,也呆添加其他显现作过错提示
************************************************************************/
void SJA_ERR(void)
{
unsigned char bdata temp_data;
temp_data = ERR_flag;
if( (ERR_flag & hard_ERR) == hard_ERR) //硬件过错进入死循环
{
while(1);
}
ERR_flag = temp_data;
while( (ERR_flag & Init_ERR) == Init_ERR ) //初始化过错一向比及初始化完功
{
SJA_Init();
ERR_flag = temp_data;
}
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/dianyuan/kaiguan/320028.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部