?? can.c
字號:
/******************************************
MCU:ATMEGA8515
Frequence: 8M
******************************************/
#include "iom8515v.h"
#include "macros.h"
#include "MAIN.h"
#include "CAN.h"
#define startadd 0x7f00 //SJA1000的首地址
uchar CanMode[14];
uchar TransBuffer[13];
uchar RxBuffer[13];
uchar RevFlag;
#define FALSE 0
#define TRUE 1
#define MODE 0x00 //模式寄存器
#define CMR 0x01 //命令寄存器
#define SR 0x02 //狀態寄存器
#define IR 0x03 //中斷寄存器
#define IER 0x04 //中斷使能寄存器
#define BTR0 0x06 //總線時序寄存器0
#define BTR1 0x07 //總線時序寄存器1
#define OCR 0x08 //輸出控制寄存器
#define TEST 0x09
#define ALC 0x0B //仲裁丟失捕捉寄存器
#define ECC 0x0C //錯誤代碼捕捉寄存器
#define EWLR 0x0D //錯誤報警限額寄存器
#define RXERR 0x0E //RX錯誤計數寄存器
#define TXERR 0x0F //TX錯誤計數寄存器
#define ACR0 0x10 //驗收代碼寄存器
#define ACR1 0x11
#define ACR2 0x12
#define ACR3 0x13
#define AMR0 0x14 //驗收屏障寄存器
#define AMR1 0x15
#define AMR2 0x16
#define AMR3 0x17
///////////////////////////
#define TXEFF 0x10
#define TXID0 0x11
#define TXID1 0x12
#define TXID2 0x13
#define TXID3 0x14
#define RXEFF 0x10
#define RXID0 0x11
#define RXID1 0x12
#define RXID2 0x13
#define RXID3 0x14
#define TXDATA0 0x15
#define TXDATA1 0x16
#define TXDATA2 0x17
#define TXDATA3 0x18
#define TXDATA4 0x19
#define TXDATA5 0x1A
#define TXDATA6 0x1B
#define TXDATA7 0x1C
#define RXDATA0 0x15
#define RXDATA1 0x16
#define RXDATA2 0x17
#define RXDATA3 0x18
#define RXDATA4 0x19
#define RXDATA5 0x1A
#define RXDATA6 0x1B
#define RXDATA7 0x1C
//////////////////////////
#define RMC 0x1D //RX報文計數器
#define RBSA 0x1E //RX緩沖器起始地址寄存器
#define CDR 0x1F //時鐘分頻寄存器
//////////////////////////////////////////////////////////////////////
uchar *sja_address=(uchar *)startadd;
uchar read_sja(uchar addr) //讀SJA1000狀態寄存器子程序
{
sja_address=(uchar *)startadd;
sja_address=sja_address+addr;
return (*(sja_address));
}
void write_sja(uchar addr,uchar val) //寫SJA1000控制寄存器子程序
{
sja_address=(uchar *)startadd;
sja_address=sja_address+addr;
*(sja_address)=val;
}
/*************************************************
初始化SJA1000主控制器子函數
*************************************************/
void Init_CAN(void)
{
uchar temp;
uint k ;
CLI();
write_sja(MODE,0x09);
read_sja(IR); //讀取CAN的中斷標識
while(!(read_sja(MODE)&0x01)) //檢測SJA1000是否達到復位工作模式
{
write_sja(MODE,0x01); //進入復位工作模式
}
for(k=0;k<6;k++); //延時約5us
write_sja(CDR,0xC8); //PeliCAN 模式,禁能CLOCKOUT引腳
for(k=0;k<6;k++); //延時約5us
write_sja(BTR0,0x09); //設置時鐘分頻器,50k
write_sja(BTR1,0x1c);
write_sja(OCR,0x1a); //輸出控制
write_sja(RXERR,0x00);
write_sja(TXERR,0x00);
write_sja(ECC,0x00);
write_sja(RBSA,0x00); //緩存器起始地址寄存器設置為0
write_sja(ACR0,0x00); //acceptcode default ffffffff
write_sja(ACR1,0x00);
write_sja(ACR2,0x00);
write_sja(ACR3,0x00);
write_sja(AMR0,0xff); //acceptmask default ffffffff
write_sja(AMR0,0xff);
write_sja(AMR0,0xff);
write_sja(AMR0,0xff);
write_sja(IER,0x01); //開放接收中斷
write_sja(CMR,0x0c); //清除數據溢出和釋放接收緩沖器;
do
{
write_sja(MODE,0x08); //設置SJA1000 工作模式,單濾波接收工作模式
}
while((read_sja(MODE)&0x01)); //確認復位標志是否被刪除
SEI();
}
/*************************************************
SJA1000發送子函數
*************************************************/
void CanTransmit(void)
{
uchar status;
CLI(); //關中斷
TransBuffer[0]=0x88;
TransBuffer[1]=0x00;
TransBuffer[2]=0x00;
TransBuffer[3]=0x00;
TransBuffer[4]=0x00;
TransBuffer[5]=0x01;
TransBuffer[6]=0x02;
TransBuffer[7]=0x03;
TransBuffer[8]=0x04;
TransBuffer[9]=0x05;
TransBuffer[10]=0x06;
TransBuffer[11]=0x07;
TransBuffer[12]=0xaa;
while(!(read_sja(SR)&0x04)); //wait until reg2^2==1 ,即判斷發送緩沖器的狀態
write_sja(TXEFF,TransBuffer[0]); //擴展幀,數據長度為8個字節
write_sja(TXID0,TransBuffer[1]);
write_sja(TXID1,TransBuffer[2]);
write_sja(TXID2,TransBuffer[3]);
write_sja(TXID3,TransBuffer[4]);
write_sja(TXDATA0,TransBuffer[5]);
write_sja(TXDATA1,TransBuffer[6]);
write_sja(TXDATA2,TransBuffer[7]);
write_sja(TXDATA3,TransBuffer[8]);
write_sja(TXDATA4,TransBuffer[9]);
write_sja(TXDATA5,TransBuffer[10]);
write_sja(TXDATA6,TransBuffer[11]);
write_sja(TXDATA7,TransBuffer[12]);
write_sja(CMR,0x01); //發送請求命令
while(!(read_sja(SR) & 0x08));//檢測SR.3位,判斷發送是否完成
SEI(); //開中斷
}
/*
void Search(void) //查詢方式接收
{
uchar SearchStatus=read_sja(SR); //讀取狀態寄存器
if(!(SearchStatus & 0xc3)) //是否存在總線關閉、錯誤狀態、數據溢出、有數據位等狀態
{
if((SearchStatus & 0x80) != 0)//如果總線關閉
{
read_sja(IR); //讀取中斷寄存器,清除中斷位
write_sja(MODE,0x08);
}
else
{
read_sja(IR);
if((read_sja(IR) & 0x08) != 0)//如果有數據溢出
write_sja(CMR,0x0c); //在命令寄存器中清除數據溢出和釋放接收緩沖區
else
{
if((read_sja(IR) & 0x01) != 0)//IR.0=1,接收緩沖區有數據
{
Status_lighting(1);
RevFlag=1;
}
}
}
}
}*/
uchar Receive(void)
{
uchar result=FALSE;
uchar status,number,i,sff;
uchar prbuf;
uchar RxData[13];
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++) //讀取數據
{
RxBuffer[i]=read_sja(prbuf);
prbuf++;
}
result=TRUE; //讀取到正確的數據則返回TRUE
write_sja(CMR,0x04); //最后釋放FXFIFO
}
}
}
return result;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -