📄 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,0x04); //设置时钟分频器,500k
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 + -