|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2007-7-26 15:38:29
|
显示全部楼层
#include "can.h"
#include "macros.h"
extern unsigned char TX_Buffer[13];
extern unsigned char RX_Buffer[13];
unsigned char read_sja(unsigned char addr) //读SJA1000状态寄存器子程序
{
unsigned char *sja_address = (unsigned char *)startadd;
sja_address = sja_address + addr;
return (*(sja_address));
}
void write_sja(unsigned char addr,unsigned char val) //写SJA1000控制寄存器子程序
{
unsigned char *sja_address = (unsigned char *)startadd;
sja_address = sja_address + addr;
*(sja_address) = val;
}
unsigned char SJATestInterface(unsigned char testvalue)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
while(--Err_Cnt)
{
write_sja(TEST, testvalue);
if(read_sja(TEST) == testvalue)
{
Err_Flag = FALSE;
break;
}
}
return Err_Flag;
}
unsigned char SJAEntryResetMode(void)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
while(--Err_Cnt)
{
write_sja(MODE, 0x09);
if((read_sja(MODE) & 0x01) == 0x01)
{
Err_Flag = FALSE;
break;
}
}
return Err_Flag;
}
unsigned char SJAQuitResetMode(void)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
while(--Err_Cnt)
{
write_sja(MODE, 0x00);
if(read_sja(MODE) == 0x00)
{
Err_Flag = FALSE;
break;
}
}
return Err_Flag;
}
unsigned char SJATestRstMode(void)
{
unsigned char SjaFlag;
if((read_sja(MODE) & 0x01) == 0x01)
{
SjaFlag = FALSE;
}
else
SjaFlag = TRUE; //工作模式下返回TRUE
return SjaFlag;
}
unsigned char SJASetOutControl(unsigned char OutCtrl)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
if(SJATestRstMode())
{
Err_Flag = TRUE;
}
else
{
while(--Err_Cnt)
{
write_sja(OCR, OutCtrl);
if(read_sja(OCR) == OutCtrl)
{
Err_Flag = FALSE;
break;
}
}
}
return Err_Flag;
}
unsigned char SJASetAccCode(unsigned char acr0, unsigned char acr1, unsigned char acr2, unsigned char acr3)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
if(SJATestRstMode())
{
Err_Flag = TRUE;
}
else
{
while(--Err_Cnt)
{
write_sja(ACR0, acr0);
if(read_sja(ACR0) != acr0)
{
continue;
}
Err_Cnt = 0x20;
write_sja(ACR1, acr1);
if(read_sja(ACR1) != acr1)
{
continue;
}
Err_Cnt = 0x20;
write_sja(ACR2, acr2);
if(read_sja(ACR2) != acr2)
{
continue;
}
Err_Cnt = 0x20;
write_sja(ACR3, acr3);
if(read_sja(ACR3) != acr3)
{
continue;
}
Err_Flag = FALSE;
break;
}
}
return Err_Flag;
}
unsigned char SJASetClockDivision(unsigned char clockdiv)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
if(SJATestRstMode())
{
Err_Flag = TRUE;
}
else
{
while(--Err_Cnt)
{
write_sja(CDR, clockdiv);
if(read_sja(CDR) == clockdiv)
{
Err_Flag = FALSE;
break;
}
}
}
return Err_Flag;
}
unsigned char SJASetAccMask(unsigned char amr0, unsigned char amr1, unsigned char amr2, unsigned char amr3)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
if(SJATestRstMode())
{
Err_Flag = TRUE;
}
else
{
while(--Err_Cnt)
{
write_sja(AMR0, amr0);
if(read_sja(AMR0) != amr0)
{
continue;
}
Err_Cnt = 0x20;
write_sja(AMR1, amr1);
if(read_sja(AMR1) != amr1)
{
continue;
}
Err_Cnt = 0x20;
write_sja(AMR2, amr2);
if(read_sja(AMR2) != amr2)
{
continue;
}
Err_Cnt = 0x20;
write_sja(AMR3, amr3);
if(read_sja(AMR3) != amr3)
{
continue;
}
Err_Flag = FALSE;
break;
}
}
return Err_Flag;
}
//16MHZ
unsigned char SJA_BTR_CODETAB[] = {
0x53, 0x2F, //20KBPS 0
0x87, 0xFF, //40KBPS 1
0x47, 0x2F, //50KBPS 2
0x83, 0xFF, //80KBPS 3
0x43, 0x2F, //100KBPS 4
0x03, 0x1C, //125KBPS 5
0x81, 0xFA, //200KBPS 6
0x01, 0x1C, //250KBPS 7
0x80, 0xFA, //400KBPS 8
0x00, 0x1C, //500KBPS 9
0x80, 0xB6, //666KBPS 10
0x00, 0x16, //800KBPS 11
0x00, 0x14 //1000KBPS 12
};
unsigned char SJASetBaudRateStandard(unsigned char BaudRateSize)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
if(BaudRateSize > 12)
{
Err_Flag = TRUE;
}
else
{
while(--Err_Cnt)
{
write_sja(BTR0, SJA_BTR_CODETAB[BaudRateSize*2]);
if(read_sja(BTR0) != SJA_BTR_CODETAB[BaudRateSize*2])
{
continue;
}
Err_Cnt = 0x20;
write_sja(BTR1, SJA_BTR_CODETAB[BaudRateSize*2 + 1]);
if(read_sja(BTR1) != SJA_BTR_CODETAB[BaudRateSize*2 + 1])
{
continue;
}
Err_Flag = FALSE;
break;
}
}
return Err_Flag;
}
/*void SJAWriteDataToTxBuf(unsigned char Num, unsigned char Data)
{
switch(Num)
{
case 0:
TX_Buffer[0] = Data;
break;
case 1:
TX_Buffer[1] = Data;
break;
case 2:
TX_Buffer[2] = Data;
break;
case 3:
TX_Buffer[3] = Data;
break;
case 4:
TX_Buffer[4] = Data;
break;
case 5:
TX_Buffer[5] = Data;
break;
case 6:
TX_Buffer[6] = Data;
break;
case 7:
TX_Buffer[7] = Data;
break;
case 8:
TX_Buffer[8] = Data;
break;
case 9:
TX_Buffer[9] = Data;
break;
case 10:
TX_Buffer[10] = Data;
break;
case 11:
TX_Buffer[11] = Data;
break;
case 12:
TX_Buffer[12] = Data;
break;
}
}*/
unsigned char SJASetOtherReg(void)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
if(SJATestRstMode())
{
Err_Flag = TRUE;
}
else
{
while(--Err_Cnt)
{
write_sja(RXERR,0x00);
if(read_sja(RXERR) != 0x00)
{
continue;
}
Err_Cnt = 0x20;
write_sja(TXERR,0x00);;
if(read_sja(TXERR) != 0x00)
{
continue;
}
Err_Cnt = 0x20;
write_sja(ECC,0x00);
if(read_sja(ECC) != 0x00)
{
continue;
}
Err_Cnt = 0x20;
write_sja(RBSA,0x00);;
if(read_sja(RBSA) != 0x00)
{
continue;
}
Err_Flag = FALSE;
break;
}
}
return Err_Flag;
}
unsigned char SJASetIER(unsigned char value)
{
unsigned char Err_Cnt = 0x20;
unsigned char Err_Flag = TRUE;
/*if(SJATestRstMode())
{
Err_Flag = TRUE;
}
else*/
//{
while(--Err_Cnt)
{
write_sja(IER, value);
if(read_sja(IER) == value)
{
Err_Flag = FALSE;
break;
}
}
//}
return Err_Flag;
}
/*************************************************
SJA1000初始化子函数
*************************************************/
void Init_CAN(void)
{
unsigned char temp;
unsigned int k ;
CLI();
do
{
temp = SJATestInterface(0x55);
}while(temp);//检查硬件连线
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJAEntryResetMode();
}while(temp);
WDR();
read_sja(IR);//clear IR
for(k=0;k<6;k++); //延时约5us
WDR();
if(!SJATestRstMode())
{
do
{
temp = SJASetClockDivision(0xC8);
}while(temp);
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJASetOutControl(0x1a);
}while(temp);
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJASetBaudRateStandard(2);
}while(temp);
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJASetAccCode(0x00, 0x00, 0x00, 0x00);
}while(temp);
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJASetAccMask(0xFF, 0xFF, 0xFF, 0xFF);
}while(temp);
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJASetOtherReg();
}while(temp);
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJAQuitResetMode();
}while(temp);
WDR();
for(k=0;k<6;k++); //延时约5us
do
{
temp = SJASetIER(0x01);
}while(temp);
}
write_sja(CMR,0x0c); //清除数据溢出和释放接收缓冲器;
for(k=0;k<6;k++); //延时约5us
WDR();
do
{
write_sja(MODE, 0x0C);
}while((read_sja(MODE) & 0x01));
/*WDR();
for(k=0;k<6;k++); //延时约5us
if(SJATestRstMode())
{
do
{
temp = SJASetIER(0x01);
}while(temp);
}*/
SEI();
}
/*************************************************
SJA1000发送子函数
*************************************************/
void CanTransmit(void)
{
unsigned char status;
CLI(); //关中断
//实际用时对SJAWriteDataToTxBuf();的调用在个检测模块中
/*SJAWriteDataToTxBuf(0, 0x88);
SJAWriteDataToTxBuf(1, 0x00);
SJAWriteDataToTxBuf(2, 0x00);
SJAWriteDataToTxBuf(3, 0x00);
SJAWriteDataToTxBuf(4, 0x00);
SJAWriteDataToTxBuf(5, 0x01);
SJAWriteDataToTxBuf(6, 0x02);
SJAWriteDataToTxBuf(7, 0x03);
SJAWriteDataToTxBuf(8, 0x04);
SJAWriteDataToTxBuf(9, 0x05);
SJAWriteDataToTxBuf(10, 0x06);
SJAWriteDataToTxBuf(11, 0x07);
SJAWriteDataToTxBuf(12, 0xaa);*/
TX_Buffer[0]=0x88;
TX_Buffer[1]=0x00;
TX_Buffer[2]=0x00;
TX_Buffer[3]=0x00;
TX_Buffer[4]=0x00;
TX_Buffer[5]=0x01;
TX_Buffer[6]=0x02;
TX_Buffer[7]=0x03;
TX_Buffer[8]=0x04;
TX_Buffer[9]=0x05;
TX_Buffer[10]=0x06;
TX_Buffer[11]=0x07;
TX_Buffer[12]=0xaa;
while(!(read_sja(SR)&0x04)); //wait until reg2^2==1 ,即判断发送缓冲器的状态
write_sja(TXEFF,TX_Buffer[0]); //扩展帧,数据长度为8个字节
write_sja(TXID0,TX_Buffer[1]);
write_sja(TXID1,TX_Buffer[2]);
write_sja(TXID2,TX_Buffer[3]);
write_sja(TXID3,TX_Buffer[4]);
write_sja(TXDATA0,TX_Buffer[5]);
write_sja(TXDATA1,TX_Buffer[6]);
write_sja(TXDATA2,TX_Buffer[7]);
write_sja(TXDATA3,TX_Buffer[8]);
write_sja(TXDATA4,TX_Buffer[9]);
write_sja(TXDATA5,TX_Buffer[10]);
write_sja(TXDATA6,TX_Buffer[11]);
write_sja(TXDATA7,TX_Buffer[12]);
write_sja(CMR,0x10); //发送请求命令
while(!(read_sja(SR) & 0x08));//检测SR.3位,判断发送是否完成
//SEI(); //开中断
}
unsigned char CanReceive(void)
{
unsigned char result = FALSE;
unsigned char status,number,i,sff;
unsigned char prbuf;
status = read_sja(SR);
prbuf = RXEFF;
if((status&0xc3) != 0) //读取总线脱离、错误状态、接收溢出、有数据等位
{
if((status&0x80) == 0x80)
{
write_sja(MODE, 0x00);
return FALSE;
}
if((status&0x02) == 0x02)
{
write_sja(CMR, 0x0c);
return FALSE;
}
if((status&0x01) == 0x01)
{
if((read_sja(RXEFF) & 0x40) == 0x40) //如果RTR=1,为远程帧
{
write_sja(CMR, 0x04); //则释放FXFIFO
}
else //为0,则是数据帧
{
sff = read_sja(prbuf) & 0x80; //取第一个字节的最高位
number = (read_sja(prbuf) & 0x0f);//取第一个字节的低四位,即数据长度
if((sff & 0x80) == 0x80) //判断是标准帧还是扩展帧
number = number + 5; //扩展帧,则帧的总长度加5(13字节)
else
number = number + 3; //标准帧,则帧的总长度加3(11字节)
for(i = 0; i < number; i++) //读取数据
{
RX_Buffer=read_sja(prbuf);
prbuf++;
}
result = TRUE; //读取到正确的数据则返回TRUE
write_sja(CMR, 0x04); //最后释放FXFIFO
}
}
}
return result;
} |
|