|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2009-12-8 23:01:08
|
显示全部楼层
/*******************************************************************************功能说明: 计算SJA1000在电路中的实际地址:基址+内部寄存器地址
其它说明: 以下的定义为SJA1000的内部寄存器的地址,不可修改
各寄存器的具体功能清参阅sja1000的数据手册
*******************************************************************************/
#define startadd 0x7F00 //SJA1000的首地址
// 控制寄存器
#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 RESVER1 0x0A //保留1
#define ALC 0x0B //仲裁丢失捕捉
#define ECC 0x0C //错误代码捕捉
#define EWLR 0x0D //错误报警限额
#define RXERR 0x0E //接收错误计数器
#define TXERR 0x0F //发送错误计数器
#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 TXD_FID 0x10 //发送缓冲区1
#define TXD_ID1 0x11 //发送缓冲区2
#define TXD_ID2 0x12 //发送缓冲区3
#define TXD_ID3 0x13 //发送缓冲区4
#define TXD_ID4 0x14 //发送缓冲区5
#define TXBuffer1 0x15 //发送缓冲区6
#define TXBuffer2 0x16 //发送缓冲区7
#define TXBuffer3 0x17 //发送缓冲区8
#define TXBuffer4 0x18 //发送缓冲区9
#define TXBuffer5 0x19 //发送缓冲区10
#define TXBuffer6 0x1A //发送缓冲区11
#define TXBuffer7 0x1B //发送缓冲区12
#define TXBuffer8 0x1C //发送缓冲区13
// 接收缓冲区寄存器
#define RXD_FID 0x10 //接收缓冲区1
#define RXD_ID1 0x11 //接收缓冲区2
#define RXD_ID2 0x12 //接收缓冲区3
#define RXD_ID3 0x13 //接收缓冲区4
#define RXD_ID4 0x14 //接收缓冲区5
#define RXBuffer1 0x15 //接收缓冲区6
#define RXBuffer2 0x16 //接收缓冲区7
#define RXBuffer3 0x17 //接收缓冲区8
#define RXBuffer4 0x18 //接收缓冲区9
#define RXBuffer5 0x19 //接收缓冲区10
#define RXBuffer6 0x1A //接收缓冲区11
#define RXBuffer7 0x1B //接收缓冲区12
#define RXBuffer8 0x1C //接收缓冲区13
#define RMC 0x1D //RX报文计数器
#define RBSA 0x1E //接收缓冲区起始地址
#define CDR 0x1F //时钟分频寄存器
/*******************************************************************************
功能说明: CAN控制器SJA1000通讯波特率.SJA1000的晶振为必须为16MHZ
其它说明:
*******************************************************************************/
#define BTR0_Rate_20k 0x53 //20KBPS的预设值
#define BTR1_Rate_20k 0x2F //20KBPS的预设值
#define BTR0_Rate_40k 0x87 //40KBPS的预设值
#define BTR1_Rate_40k 0xFF //40KBPS的预设值
#define BTR0_Rate_50k 0x47 //50KBPS的预设值
#define BTR1_Rate_50k 0x2F //50KBPS的预设值
#define BTR0_Rate_80k 0x83 //80KBPS的预设值
#define BTR1_Rate_80k 0xFF //80KBPS的预设值
#define BTR0_Rate_100k 0x43 //100KBPS的预设值
#define BTR1_Rate_100k 0x2f //100KBPS的预设值
#define BTR0_Rate_125k 0x03 //125KBPS的预设值
#define BTR1_Rate_125k 0x1c //125KBPS的预设值
#define BTR0_Rate_200k 0x81 //200KBPS的预设值
#define BTR1_Rate_200k 0xFA //200KBPS的预设值
#define BTR0_Rate_250k 0x01 //250KBPS的预设值
#define BTR1_Rate_250k 0x1c //250KBPS的预设值
#define BTR0_Rate_400k 0x80 //400KBPS的预设值
#define BTR1_Rate_400k 0xfa //400KBPS的预设值
#define BTR0_Rate_500k 0x00 //500KBPS的预设值
#define BTR1_Rate_500k 0x1c //500KBPS的预设值
#define BTR0_Rate_666k 0x80 //666KBPS的预设值
#define BTR1_Rate_666k 0xb6 //666KBPS的预设值
#define BTR0_Rate_800k 0x00 //800KBPS的预设值
#define BTR1_Rate_800k 0x16 //800KBPS的预设值
#define BTR0_Rate_1000k 0x00 //1000KBPS的预设值
#define BTR1_Rate_1000k 0x14 //1000KBPS的预设值
/*******************************************************************************
功能说明: 定义系统参数
其它说明: 无
*******************************************************************************/
// 本地的IP地址
#define Local_IP1 1 // IP地址最高位
#define Local_IP2 2
#define Local_IP3 3
#define Local_IP4 4 // IP地址最低位
// 本地的CAN标识
#define REG_ACR1_FID Local_IP4 // 滤波器的标识符最高位
#define REG_ACR2_FID Local_IP3
#define REG_ACR3_FID Local_IP2
#define REG_ACR4_FID Local_IP1 // 滤波器的标识符最低位
#define REG_AMR1_FID 0x00 // 滤波器的屏蔽符最高位
#define REG_AMR2_FID 0x00
#define REG_AMR3_FID 0x03
#define REG_AMR4_FID 0x07 // 滤波器的屏蔽符最低位
// 发往目标CAN标识
#define SEND_ACR1_FID Local_IP4 // 滤波器的最高位
#define SEND_ACR2_FID Local_IP3
#define SEND_ACR3_FID Local_IP2
#define SEND_ACR4_FID Local_IP1 // 滤波器的最低位
// 模式参数
#define REG_MODE_DATA 0x0C // 模式控制器: 单滤波器、自检测模式
#define REG_TEST_DATA 0xAA // 测试值
#define REG_CDR_DATA 0x88 // 时分控制的值: PeilCAN模式、CLOCK无效
#define REG_INTENABLE_DATA 0x83 // 中断使能控制的值: 总线错误中断、发送中断、接收中断
#define REG_OCR_DATA 0x1A // 输出控制的值:
// 定义命令字
#define TXD_ONE_CMD 0x03 // 产生一次报文发送,当错误时不再生发(单次发送)
#define TXD_CMD 0x01 // 发送请求命令,当错误时可重发
#define T_R_CMD 0x12 // 产生一次自接收性质的报文发送,发送错误时不会重发
#define AT_CMD 0x02 // 中止发送命令
#define RRB_CMD 0x04 // 释放接收缓冲区
#define COS_CMD 0x08 // 数据溢出清除命令
unsigned char TransBuffer[13];
unsigned char RxBuffer[];
unsigned char *sja_address=(unsigned char *)startadd;
unsigned char read_sja(unsigned char addr) //读SJA1000状态寄存器子程序
{
sja_address=(unsigned char *)startadd;
sja_address=sja_address+addr;
return (*(sja_address));
}
void write_sja(unsigned char addr,unsigned char val) //写SJA1000控制寄存器子程序
{
sja_address=(unsigned char *)startadd;
sja_address=sja_address+addr;
*(sja_address)=val;
}
void SJA1000_init(void)
{
//CLI();
write_sja(MODE,0x01);
read_sja(IR); //读取CAN的中断标识
while(!(read_sja(MODE)&0x01)) //检测SJA1000是否达到复位工作模式
{
write_sja(MODE,0x01); //进入复位工作模式
}
delay_us(5); //延时约5us
write_sja(CDR,0xC8); //PeliCAN 模式,禁能CLOCKOUT引脚
delay_us(5); //延时约5us
write_sja(BTR0,0x53); //设置时钟分频器,20k
write_sja(BTR1,0x2F);
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); //配置验收代码ACR3地址
write_sja(AMR0,0xff); //acceptmask default ffffffff
write_sja(AMR1,0xff);
write_sja(AMR2,0xff);
write_sja(AMR3,0xff);
write_sja(IER,0x01); //接收中断使能
write_sja(CMR,0x0c); //清除数据溢出和释放接收缓冲器;
do
{
write_sja(MODE,0x00); //设置SJA1000工作模式,双滤波接收工作模式
}
while((read_sja(MODE)&0x01)); //确认复位标志是否被删除
//SEI();
}
void CanTransmit(void)
{
unsigned char 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(TXD_FID,TransBuffer[0]); //扩展帧,数据长度为8个字节
write_sja(TXD_ID1,TransBuffer[1]);
write_sja(TXD_ID2,TransBuffer[2]);
write_sja(TXD_ID3,TransBuffer[3]);
write_sja(TXD_ID4,TransBuffer[4]);
write_sja(TXBuffer1,TransBuffer[5]);
write_sja(TXBuffer2,TransBuffer[6]);
write_sja(TXBuffer3,TransBuffer[7]);
write_sja(TXBuffer4,TransBuffer[8]);
write_sja(TXBuffer5,TransBuffer[9]);
write_sja(TXBuffer6,TransBuffer[10]);
write_sja(TXBuffer7,TransBuffer[11]);
write_sja(TXBuffer8,TransBuffer[12]);
write_sja(CMR,0x01); //发送请求命令
while(!(read_sja(SR) & 0x08));//检测SR.3位,判断发送是否完成
SEI(); //开中断
}
unsigned char Receive(void)
{
unsigned char result=0;
unsigned char status,number,sff,j;
unsigned char mp=RXD_FID;
status=read_sja(SR);
if((status&0xc3)!=0) //读取总线脱离、错误状态、接收溢出、有数据等位
{
if((status&0x80)==0x80)
{
write_sja(MODE,0x00);
return 0;
}
if((status&0x02)==0x02)
{
write_sja(CMR,0x0c);
return 0;
}
if((status&0x01)==0x01)
{
if((read_sja(RXD_FID)&0x40)==0x40) //如果RTR=1,为远程帧
{
write_sja(CMR,0x04); //则释放FXFIFO
}
else //为0,则是数据帧
{
sff=read_sja(RXD_FID)&0x80; //取第一个字节的最高位
number=(read_sja(RXD_FID)&0x0f);//取第一个字节的低四位,即数据长度
if ((sff&0x80)==0x80) //判断是标准帧还是扩展帧
number=number+5; //扩展帧,则帧的总长度加5(13字节)
else
number=number+3; //标准帧,则帧的总长度加3(11字节)
for(j=0;j<number;j++) //读取数据
{
RxBuffer[j]=read_sja(RXD_FID);
mp++;
}
result=1; //读取到正确的数据则返回TRUE
write_sja(CMR,0x04); //最后释放FXFIFO
}
}
}
return result;
}
以上是“SJA1000.h”部分 |
|