关于SJA1000的初始化问题

jeasonlsn 2010-03-11 07:28:30
本人在CAN节点,之前在BASI模式下,SJA1000是可以正常初始化的;但我现在要用到PELI模式下的自检功能去检测单个节点硬件电路是否正常,但是在PELI模式下SJA1000无法正常读写,导致初始化不成功,请高人指点

#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;
}

...全文
1381 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
echodongmei 2011-05-15
  • 打赏
  • 举报
回复
楼主啊,能不能加我QQ呀,好多问题想问哈哦 805582568
beyondhcy0216 2011-04-22
  • 打赏
  • 举报
回复
楼主呀,你怎么只初始化呢,,后面的发送接收的有没做呀,我的这个用basicCAN初始化没问题,peliCAN没试,因为初学,没有看那块,要复杂点,呵呵。
我这接收发送总是不能产生中断,不知道咋回事,如果能帮帮忙了,谢谢!!
bg2bkk 2011-03-27
  • 打赏
  • 举报
回复
楼主,确实不行啊,我初始化AMR和ACR后,再读他们,发现读出来的是ACR ACR1 ACR2 ACR3为10h,11h,12h,13h,AMR AMR1 AMR2 AMR3为14h 15h 16h 17h,这些数字好像是ACR和AMR在sja1000中的地址,而且我在读TBSR和RBSR时候也读出的是10h,11h,12h,13h等,这些都是TBSR或者ACR在sja中的地址,请问可以给些提示吗
mtogz 2010-03-16
  • 打赏
  • 举报
回复
不行了,还是调试不通,LZ给个意见
mtogz 2010-03-15
  • 打赏
  • 举报
回复
按照你说的方法,我将ACR, AMR分别写入0x00, 0x00, 和分别写入0x05,0x05时都可以;但是当我在ACR中写入0xaa,AMR写入0xff时,我读出的ACR的值是随机的,有0xaa, 0x21, 0x41, AMR的值有0x41, 0x21。 其他的寄存器的初始话都正确,仅有这两个有问题。
jeasonlsn 2010-03-15
  • 打赏
  • 举报
回复
我也是AMR不能写0xff,写了读出来就是乱码了,具体原因我上面已经有说了哦
mtogz 2010-03-15
  • 打赏
  • 举报
回复
朋友,我的QQ是21919094,如果你方便的话,能不能在上面指点下
jeasonlsn 2010-03-14
  • 打赏
  • 举报
回复
那你的ACR初始化后读出来是什么值呢,在BASIC模式下其它寄存器读写有没有问题呢?
mtogz 2010-03-13
  • 打赏
  • 举报
回复
我在BASIC模式下为什么也不行呢? 我的ACR写的0xaa, AMR写的0xff。现在我把AMR按照你说的改成0x00可以了,但是ACR还是初始化不正确,求解~~~
jeasonlsn 2010-03-12
  • 打赏
  • 举报
回复
帶CAN的單片機贵啊;今天早上又调试了一下,发现有时ACR,AMR可以正常初始化,有时不可以,。但是在BASIC模式下就一直没问题,真是晕啊
eagle109 2010-03-12
  • 打赏
  • 举报
回复
SJA1000沒有用過
但是目前帶CAN的單片機很多啊,而且調試也比外掛的方便
我們公司現在選用的都是帶CAN的單片機
jeasonlsn 2010-03-12
  • 打赏
  • 举报
回复
哈哈,又过了一天,终于把这个搞定了,现把我的经验分享一下;

下面为问题所在的程序

/*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,也就是要校验地址,一上电,初始化成功,终于解决问题了!!!!!!!
hallowwar 2010-03-12
  • 打赏
  • 举报
回复
freescale的单片机自己有控制器,不知道你到发送器是不是独立到控制器控制的。
yunqian09 2010-03-11
  • 打赏
  • 举报
回复
PELI模式 出错了 建议 看一下 错误计数器 之类的 查错的寄存器 看看到底错误出在哪里?

建议去 END can助学小组 参考下人家的程序
kyzf 2010-03-11
  • 打赏
  • 举报
回复
没有具体弄过SJA1000,

MARK.

27,516

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 单片机/工控
社区管理员
  • 单片机/工控社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧