打印
[CAN-bus/DeviceNet]

关于SJA1000初始化

[复制链接]
3682|3
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jeasonlsn|  楼主 | 2010-3-11 21:03 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人在CAN节点,之前在BASI模式下,SJA1000是可以正常初始化的;但我现在要用到PELI模式下的自检功能去检测单个节点硬件电路是否正常,但是在PELI模式下SJA1000中的ACR,AMR无**常读写,导致初始化不成功,请高人指点
#define SJA_BaseAdr 0xFF00 //定义sja1000 的片选基址   p1.0接SJA1000的CS口    sbit SJA1000_RST=P1^1;

#define REG_MODE SJA_BaseAdr+0x00 //内部控制寄存器
#define REG_COMMAND SJA_BaseAdr+0x01 //命令寄存器
#define REG_STATUS SJA_BaseAdr+0x02 //状态寄存器
#define REG_IR SJA_BaseAdr+0x03 //中断寄存器
#define REG_IR_ABLE SJA_BaseAdr+0x04 //中断使能控制器
#define REG_BTR0 SJA_BaseAdr+0x06 //总线定时寄存器0
#define REG_BTR1 SJA_BaseAdr+0x07 //总线定时寄存器1
#define REG_OCR SJA_BaseAdr+0x08 //输出控制寄存器
#define REG_TEST SJA_BaseAdr+0x09 //测试寄存器
#define REG_ALC        SJA_BaseAdr + 0x0b   //0a保留
#define REG_ECC        SJA_BaseAdr + 0x0c
#define REG_EMLR    SJA_BaseAdr + 0x0d
#define REG_RXERR    SJA_BaseAdr + 0x0e
#define REG_TXERR    SJA_BaseAdr + 0x0f

#define REG_ACR0    SJA_BaseAdr + 0x10 //验收代码寄存器
#define REG_ACR1    SJA_BaseAdr + 0x11
#define REG_ACR2    SJA_BaseAdr + 0x12
#define REG_ACR3    SJA_BaseAdr + 0x13
#define REG_AMR0    SJA_BaseAdr + 0x14 //验收屏蔽寄存器
#define REG_AMR1    SJA_BaseAdr + 0x15
#define REG_AMR2    SJA_BaseAdr + 0x16
#define REG_AMR3    SJA_BaseAdr + 0x17
//以下为发送缓冲区寄存器定义
#define REG_RxBuffer0    SJA_BaseAdr + 0x10
#define REG_RxBuffer1    SJA_BaseAdr + 0x11
#define REG_RxBuffer2    SJA_BaseAdr + 0x12
#define REG_RxBuffer3    SJA_BaseAdr + 0x13
#define REG_RxBuffer4    SJA_BaseAdr + 0x14
//以下为接收缓冲区寄存器定义
#define REG_TxBuffer0    SJA_BaseAdr + 0x10
#define REG_TxBuffer1    SJA_BaseAdr + 0x11
#define REG_TxBuffer2    SJA_BaseAdr + 0x12
#define REG_TxBuffer3    SJA_BaseAdr + 0x13
#define REG_TxBuffer4    SJA_BaseAdr + 0x14
#define REG_DataBuffer1 SJA_BaseAdr + 0x15
#define REG_DataBuffer2 SJA_BaseAdr + 0x16
#define REG_DataBuffer3 SJA_BaseAdr + 0x17
#define REG_DataBuffer4 SJA_BaseAdr + 0x18
#define REG_DataBuffer5 SJA_BaseAdr + 0x19
#define REG_DataBuffer6 SJA_BaseAdr + 0x1a
#define REG_DataBuffer7 SJA_BaseAdr + 0x1b
#define REG_DataBuffer8 SJA_BaseAdr + 0x1c

/*
*******************************************************************************************
** 内部地址 01EH 备用
********************************************************************************************
*/
/*
*******************************************************************************************
** 时钟分频寄存器(内部地址01FH)
********************************************************************************************
*/
#define REG_CDR SJA_BaseAdr+0x1F //时钟分频寄存器
#define REG_RBSA  SJA_BaseAdr + 0x1e  //接收缓冲区首地址
#define REG_Receive_Counter    SJA_BaseAdr + 0x1d//RX信息计数器
/*

*******************************************************************************************
** 定义系统指针 利用该地址指针访问sja1000
********************************************************************************************
*/
unsigned char xdata *SJA_BCANAdr;
/*
*******************************************************************************************
** 定义命令字
********************************************************************************************
*/
#define TR_CMD 0x01 //发送请求命令
#define AT_CMD 0x02 //夭折发送命令
#define RRB_CMD 0x04 //释放接收缓冲区
#define COS_CMD 0x08 //清除超载状态
#define SRR_CMD 0x10 //进入自接收模式
/*
*******************************************************************************************
** 定义16M 的晶体下CAN 总线波特率
********************************************************************************************
*/
#define ByteRate_5k 0x00 //波特率5kbps
#define ByteRate_10k 0x01 //波特率10kbps
#define ByteRate_20k 0x02 //波特率20kbps
#define ByteRate_40k 0x03 //波特率40kbps
#define ByteRate_50k 0x04 //波特率50kbps
#define ByteRate_80k 0x05 //波特率80kbps
#define ByteRate_100k 0x06 //波特率100kbps
#define ByteRate_160k 0x07 //波特率200kbps
#define ByteRate_250k 0x08 //波特率250kbps
#define ByteRate_320k 0x09 //波特率300kbps
#define ByteRate_500k 0x0a //波特率500kbps
#define ByteRate_800k 0x0b //波特率600kbps
#define ByteRate_1000k 0x0c //波特率1000kbps
/*


/* 初始化SJA1000    返回1说明读写寄存器失败                   */
unsigned char SJA1000_Config_Normal()
{
if(BCAN_CREATE_COMMUNATION()) return 1;//读写测试寄存器失败

if(BCAN_ENTER_RETMODEL()) return 2; //复位失败
if(BCAN_SET_BANDRATE(0x04)) return 3; //设置为100k波特率通信   失败

if(BCAN_SET_OUTCLK (0x1a,0x80)) return 4;//设置OCR=0X1A,T0推挽输出  CDR=0X00,peli模式,输入没有启用旁路功能 时钟输出为 fOSC/2   

if(BCAN_SET_OBJECT0(0x11,0xff)) return 5;//设置ACR0和AMR0
if(BCAN_SET_OBJECT1(0x22,0xff)) return 5;//设置ACR1和AMR1
if(BCAN_SET_OBJECT2(0x33,0xff)) return 5;//设置ACR1和AMR1
if(BCAN_SET_OBJECT3(0x44,0xff)) return 5;//设置ACR1和AMR1   

if(BCAN_QUIT_RETMODEL()) return 6; //退出复位模式,进入工作模式   
if(BCAN_MODE_COMMUNATION(0x0c)) return 7;//设置自检测模式和单滤波模式
return 0;//初始化成功
}

每次运行初始化函数都返回5,说明ACR,AMR没有读写成功
以下为ACR,AMR的读写函数
bit BCAN_SET_OBJECT0(unsigned char BCAN_ACR,unsigned char BCAN_AMR)
{
SJA_BCANAdr=REG_ACR0; //访问地址指向验收代码寄存器(ACR0)
*SJA_BCANAdr=BCAN_ACR; //写入参数
if(*SJA_BCANAdr != BCAN_ACR) { //校验写入值
return 1;
}
SJA_BCANAdr=REG_AMR0; //访问地址指向验收屏蔽寄存器(AMR0)
*SJA_BCANAdr=BCAN_AMR; //写入参数
if(*SJA_BCANAdr != BCAN_AMR) { //校验写入值
return 1;
}
return 0;
}

bit BCAN_SET_OBJECT1(unsigned char BCAN_ACR,unsigned char BCAN_AMR)
{
SJA_BCANAdr=REG_ACR1; //访问地址指向验收代码寄存器(ACR1)
*SJA_BCANAdr=BCAN_ACR; //写入参数
if(*SJA_BCANAdr != BCAN_ACR) { //校验写入值
return 1;
}
SJA_BCANAdr=REG_AMR1; //访问地址指向验收屏蔽寄存器(AMR1)
*SJA_BCANAdr=BCAN_AMR; //写入参数
if(*SJA_BCANAdr != BCAN_AMR) { //校验写入值

return 1;
}
return 0;
}

bit BCAN_SET_OBJECT2(unsigned char BCAN_ACR,unsigned char BCAN_AMR)
{
SJA_BCANAdr=REG_ACR2; //访问地址指向验收代码寄存器(ACR2)
*SJA_BCANAdr=BCAN_ACR; //写入参数
if(*SJA_BCANAdr != BCAN_ACR) { //校验写入值
return 1;
}
SJA_BCANAdr=REG_AMR2; //访问地址指向验收屏蔽寄存器(AMR2)
*SJA_BCANAdr=BCAN_AMR; //写入参数
if(*SJA_BCANAdr != BCAN_AMR) { //校验写入值

return 1;
}
return 0;
}


bit BCAN_SET_OBJECT3(unsigned char BCAN_ACR,unsigned char BCAN_AMR)
{
SJA_BCANAdr=REG_ACR3; //访问地址指向验收代码寄存器(ACR2)
*SJA_BCANAdr=BCAN_ACR; //写入参数
if(*SJA_BCANAdr != BCAN_ACR) { //校验写入值

return 1;
}
SJA_BCANAdr=REG_AMR3; //访问地址指向验收屏蔽寄存器(AMR2)
*SJA_BCANAdr=BCAN_AMR; //写入参数
if(*SJA_BCANAdr != BCAN_AMR) { //校验写入值

return 1;
}
return 0;
}

相关帖子

沙发
jeasonlsn|  楼主 | 2010-3-12 22:21 | 只看该作者
哈哈,又过了一天,终于把这个搞定了,现把我的经验分享一下;

下面为问题所在的程序

/*if(BCAN_SET_OBJECT0(0x11,0xff)) return 5;//设置ACR0和AMR0
if(BCAN_SET_OBJECT1(0x22,0xff)) return 5;//设置ACR1和AMR1
if(BCAN_SET_OBJECT2(0x33,0xff)) return 5;//设置ACR1和AMR1
if(BCAN_SET_OBJECT3(0x44,0xff)) return 5;//设置ACR1和AMR1   

if(BCAN_QUIT_RETMODEL()) return 6; //退出复位模式,进入工作模式   

if(BCAN_MODE_COMMUNATION(0x0c)) return 7;//设置自检测模式和单滤波模式

return 0;//初始化成功
}

每次运行初始化函数都返回5,说明ACR,AMR没有读写成功*/

为什么ACR,AMR,没有读写成功呢,请注意到一个问题,就是在初始化中把AMR设置为0xff,什么意思呢,就是从外部进入SJA1000的任何信息都可以接收,不用校验地址。而一上电,RXD0就会输入电平;另一个问题就是在PELI模式下,接收缓冲区地址是和ACR,AMR重复的(BASIC模式是不重复的,所以在BASIC模式下不会出现初始化问题)所以当AMR设置为0xff后,从RXD0进入SJA1000的信息就写入了接收缓冲区,这导致从ACR,AMR所在地址读出来的数据和写入的不一样,初始化失败。而且,在上电后我观察了RX信息计数器,发现一上电怎么会有几十条信息呢,而且数量是随机的,这也刚好印证了我前面的想法。于是我在初始化AMR时都改成了0x00,也就是要校验地址,一上电,初始化成功,终于解决问题了!!!!!!!

使用特权

评论回复
板凳
weixiaomin| | 2011-3-8 21:06 | 只看该作者
正在学习中

使用特权

评论回复
地板
neaphy| | 2011-3-13 23:14 | 只看该作者
我就不知道了,为什么还有人在弄这个SJA1000
放着这么多已经集成CAN控制器的MCU不用

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

25

帖子

1

粉丝