CAN总线方案ATMEGA128+SJA1000T+82C250 调试遇到的问题
最近公司上CAN总线项目,根据网上的一些资料,搭建电路,编写测试程序,发现一个问题,SJA1000进入复位模式后,配置寄存器、读写测试寄存器都正常,但就是无法跳出复位模式(进入工作模式),不知什么原因,请高手不吝赐教.....先行谢过....电路原理图及源代码见附件...
oid SJA1000_init(void)
{
// uint8_t i_temp=0,j_temp=0;
uint8_t *t;
cli();
write_char_sja1000(CAN_MOD,0x01);
while(!(read_char_sja1000(CAN_MOD)&0x01)) //检测SJA1000是否达到复位工作模式
{
write_char_sja1000(CAN_MOD,0x01); //进入复位工作模式
wdt_reset();//喂狗t
}
//读写测试寄存器
write_char_sja1000(CAN_TEST,0x2A);
//_delay_us(5);
*t=read_char_sja1000(CAN_TEST);
write_char_sja1000(CAN_CDR,0xC8);//PeliCAN 模式,禁用CLOCKOUT引脚配置时钟分频寄存器-Pelican,CBP=1,关闭TX1中断与时钟输出
write_char_sja1000(CAN_AMR0,0xF0);//验收屏蔽寄存器 配置验收屏蔽AMR0=0FFH
write_char_sja1000(CAN_AMR1,0x00);//配置验收屏蔽AMR1=000H
write_char_sja1000(CAN_AMR2,0xFF); //配置验收屏蔽AMR2=0FFH
write_char_sja1000(CAN_AMR3,0x00); //配置验收屏蔽AMR3=000H
write_char_sja1000(CAN_ACR1,0x00);//配置验收代码ACR1=0:广播
write_char_sja1000(CAN_ACR3,0x55); //配置验收代码ACR3=地址
write_char_sja1000(CAN_BTR0,0x53);//设置时钟分频器,20k
write_char_sja1000(CAN_BTR1,0x2F);
write_char_sja1000(CAN_OCR,0x1A);//输出控制
write_char_sja1000(CAN_EWLR,0xFF);// 配置错误报警限制为255
write_char_sja1000(CAN_MOD,0x01); //进入复位工作模式
do
{
write_char_sja1000(CAN_MOD,0x00);//设置SJA1000工作模式,单滤波接收工作模式
wdt_reset();//喂狗t
}
while((read_char_sja1000(CAN_MOD))&0x01); // 确认复位标志是否被删除 程序执行到这里就停在这里了,为何??????
write_char_sja1000(CAN_TXB+4,0x00);//配置发送缓冲区的ID3-
write_char_sja1000(CAN_IER,0x07);//配置SJA10000中断-错误报警/发送/接收中断
}
RE: CAN总线方案ATMEGA128+SJA1000T+82C250 调试遇到的问题
上传附件 我也在研究sja1000 留个QQ吧 /*******************************************************************************************函数:CAN1_Init()
参数:void
返回:无
功能:检测第一路CAN的初始化
*******************************************************************************************/
void CAN1_Init(void)
{uchar i_temp=0,j_temp=0;
CAN1_MOD=0x01;
while(!(CAN1_MOD&0x01))//保证进入复位模式,bit0.0不为1,再写CAN_MOD
{
CAN1_MOD=0x01;
}
CAN1_CDR=0xc8; //配置时钟分频寄存器-Pelican,CBP=1,
//关闭TX1中断与时钟输出
CAN1_AMR0=0xff; //配置验收屏蔽AMR0=0FFH
CAN1_AMR1=0xff; //配置验收屏蔽AMR1=000H
CAN1_AMR2=0xff; //配置验收屏蔽AMR2=0FFH
CAN1_AMR3=0xff; //配置验收屏蔽AMR3=000H
CAN1_ACR1=0x00; //配置验收代码ACR1=0:广播
CAN1_ACR3=0x00; //配置验收代码ACR3=地址 =0
CAN1_BTR0=0x7f; //配置总线定时--5kbps
CAN1_BTR1=0xff;
CAN1_OCR=0x1a; //配置输出控制
CAN1_EWLR=0xff; //配置错误报警限制为255
do
{
CAN1_MOD=0x00; //进入工作模式双滤波 //自检模式40
}
while(CAN1_MOD&0x01); // 确认复位标志是否被删除
CAN1_TXB_4=ID3;//配置发送缓冲区的ID3-
CAN1_IER=0x07; //配置SJA10000中断-错误报警/发送/接收中断
}
----------------------------
//==============================第一路CAN内部寄存器宏定义 片选PC0============================================
#define CAN1_9 (*(volatile unsigned char *)0xfe09) //数据地址
//*******************CAN1寄存器地址**************************************************************//
#define CAN1_MOD (*(volatile unsigned char *)0xfe00) //模式寄存器
#define CAN1_CMR (*(volatile unsigned char *)0xfe01) //命令寄存器 只写
#define CAN1_SR (*(volatile unsigned char *)0xfe02) //状态寄存器 只读
#define CAN1_IR (*(volatile unsigned char *)0xfe03) //中断寄存器 只读
#define CAN1_IER (*(volatile unsigned char *)0xfe04) //中断使能寄存器
#define CAN1_BTR0 (*(volatile unsigned char *)0xfe06) //总线定时寄存器0
#define CAN1_BTR1 (*(volatile unsigned char *)0xfe07) //总线定时寄存器1
#define CAN1_OCR (*(volatile unsigned char *)0xfe08) //输出控制寄存器
#define CAN1_TEST (*(volatile unsigned char *)0xfe09) //测试寄存器
#define CAN1_ALC (*(volatile unsigned char *)0xfe0b) //仲裁丢失寄存器
#define CAN1_ECC (*(volatile unsigned char *)0xfe0c) //错误代码捕捉寄存器
#define CAN1_EWLR (*(volatile unsigned char *)0xfe0d) //错误报警限制寄存器
#define CAN1_EXERR (*(volatile unsigned char *)0xfe0e) //RX错误计数寄存器
#define CAN1_TXERR (*(volatile unsigned char *)0xfe0f) //TX错误计数寄存器
#define CAN1_ACR0 (*(volatile unsigned char *)0xfe10) //验收码寄存器0
#define CAN1_ACR1 (*(volatile unsigned char *)0xfe11) //验收码寄存器1
#define CAN1_ACR2 (*(volatile unsigned char *)0xfe12) //验收码寄存器2
#define CAN1_ACR3 (*(volatile unsigned char *)0xfe13) //验收码寄存器3
#define CAN1_AMR0 (*(volatile unsigned char *)0xfe14) //验收屏蔽寄存器0
#define CAN1_AMR1 (*(volatile unsigned char *)0xfe15) //验收屏蔽寄存器1
#define CAN1_AMR2 (*(volatile unsigned char *)0xfe16) //验收屏蔽寄存器2
#define CAN1_AMR3 (*(volatile unsigned char *)0xfe17) //验收屏蔽寄存器3
#define CAN1_TXB_0 (*(volatile unsigned char *)0xfe10) //发送缓冲区首地址(工作模式)
#define CAN1_TXB_1 (*(volatile unsigned char *)0xfe11)
#define CAN1_TXB_2 (*(volatile unsigned char *)0xfe12)
#define CAN1_TXB_3 (*(volatile unsigned char *)0xfe13)
#define CAN1_TXB_4 (*(volatile unsigned char *)0xfe14)
#define CAN1_TXB_5 (*(volatile unsigned char *)0xfe15)
#define CAN1_TXB_6 (*(volatile unsigned char *)0xfe16)
#define CAN1_RXB_0 (*(volatile unsigned char *)0xfe10) //接收缓冲区首地址(工作模式)
#define CAN1_RXB_1 (*(volatile unsigned char *)0xfe11)
#define CAN1_RXB_2 (*(volatile unsigned char *)0xfe12)
#define CAN1_RXB_3 (*(volatile unsigned char *)0xfe13)
#define CAN1_RXB_4 (*(volatile unsigned char *)0xfe14)
#define CAN1_RXB_5 (*(volatile unsigned char *)0xfe15)
#define CAN1_RXB_6 (*(volatile unsigned char *)0xfe16)
#define CAN1_RXB_7 (*(volatile unsigned char *)0xfe17)
#define CAN1_RXB_8 (*(volatile unsigned char *)0xfe18)
#define CAN1_RXB_9 (*(volatile unsigned char *)0xfe19)
#define CAN1_RXB_10(*(volatile unsigned char *)0xfe1a)
#define CAN1_RXB_11(*(volatile unsigned char *)0xfe1b)
#define CAN1_RXB_12(*(volatile unsigned char *)0xfe1c)
#define CAN1_RMC (*(volatile unsigned char *)0xfe1d) //RX信息计数器
#define CAN1_RBSA (*(volatile unsigned char *)0xfe1e) //RX缓冲区起始地址寄存器
#define CAN1_CDR (*(volatile unsigned char *)0xfe1f) //时钟分频器
#define ID3 00 //ID3
#define CAN1BE_C 6 //总线关闭次数设定值
#define CAN1 0xfe09;
#define ext_PORT1 (*(volatile unsigned char *)0xfe09) //SJA1000的测试寄存器
m128外部存储器接口连接SJA1000T erxun 发表于 2012-7-23 16:48 static/image/common/back.gif
/*******************************************************************************************
函数:C ...
孟大侠您好,首先,感谢您的回复!我做的这个项目是在我们公司一款主板上增加CAN总线,该主板上其它部分为两路232,一路485通讯,因为感觉跟这个问题无关,所以原理图上我删掉了相应部分。看了您的回复,不是太理解您的意思,我只有一路CAN,SJA1000是按外部存储器方式访问的,地址为0X7F00应该没问题,因为我读写测试寄存器是正常的....可能是我对CAN认识太浅,还请您多多指教,谢谢...
我现在是在原来的板子上通过飞线搭建的测试电路,跟硬件电路有关?可是读写测试寄存器正常啊....有没有可能是我买的SJA1000有问题呢?26元/片
再次感谢您的关注! 00superman00 发表于 2012-7-23 16:34 static/image/common/back.gif
我也在研究sja1000 留个QQ吧
共同学习,QQ:553923543 读写测试寄存器,没问题,可以排除硬件接口没问题,除了中断引脚。 erxun 发表于 2012-7-23 17:23 static/image/common/back.gif
读写测试寄存器,没问题,可以排除硬件接口没问题,除了中断引脚。
您费心了,在下刚开始这个项目,对SJA1000了解商不深入,请问中断引脚接或不接或高低电平搞反,对SJA1000退出复位模式进入工作模式有影响吗?有没有可能芯片质量有问题导致如此的呢?这个问题拖了我将近一周了,想过先制板出来再调,但感觉飞线搭建的电路不是问题根本所在...
再次感谢您的关注! 中断和进入复位模式无关,
erxun 发表于 2012-7-24 08:28 static/image/common/back.gif
中断和进入复位模式无关,
哦,我打算仔细梳理硬件电路,争取今天解决这个问题。
谢谢您!
调通后我会将源代码跟电路上传共享,一是抛砖引玉,二是希望能帮助新学习者... ;///////////////////////////////////////MEGA64初始化程序 截取于具体项目中,绝对可以///////////////////////////////////////////////////////
;CAN初始化
;io口初始化
CBI DDRD,2 ;通信中断引脚配置;
SBI PORTD,2
LDIR16,$FF ;清除全部外部中断标志
OUTEIFR, R16 ;外部中断写1清0
inr16,EIMSK
ORI R16,0B00000100
OUT EIMSK,R16 ;允许通信中断
ldi r16,0b11000000;使能外部RAM,高地址空余
out mcucr,r16
ldi r16,0b00000111;
sts xmcrb,r16
ldi r16,0b00000010 ;
sts xmcra,r16
sbi ddrd,4 ;通信片选CS为输出口
cbi pORTD,4 ;片选CAN
;初始化CAN芯片
cli;//这里关闭了全局中断,记得在以后的适当的位置打开
ZAIFWEI: ldi r16,0B00000001 ;用软件使SJA1000进入复位状态
sts $8000,r16
LDS R16,$8000
BST R16,0
BRTC ZAIFWEI
LDI R16,$C8
STS $801f,R16 ;写时钟分频,CDR
LDI R16,$00 ;验收屏蔽,不屏蔽,全部为1
STS $8014,R16 ;8014,8015,8016,8017
LDI R16,$FF
STS $8015,R16
LDI R16,$00
STS $8016,R16
LDI R16,$FF
STS $8017,R16
LDI R16,2 ;验收代码,下面是双滤波
STS $8010,R16 ;验收代码R为8010,8011,8012,8013
LDI R16,$00
STS $8011,R16
LDI R16,$00
STS $8012,R16
LDI R16,$00
STS $8013,R16
ldi r16,$09 ;总线定时
sts $8006,r16
LDI R16,$1C
STS $8007,R16
ldi r16,$fd;
sts $800d,r16 ;错误报警限制
ldi r16,$1a;
sts $8008,r16
GONGZUO: ldi r16,$00 ;退出复位,双滤波
sts $8000,r16
LDS R16,$8000
BST R16,0
BRTSGONGZUO
LDI R16,0b00000111;CAN中断使能
STS $8004,R16
;========================CAN初始化结束------------------------------------
;////////////////////////前面关闭了全局中断,以后记得要打开/////////////////////////////// 爱则倾心 发表于 2012-7-23 17:13 static/image/common/back.gif
孟大侠您好,首先,感谢您的回复!我做的这个项目是在我们公司一款主板上增加CAN总线,该主板上其它部分 ...
地址好像是8000吧 avrstm32 发表于 2012-7-24 09:23 static/image/common/back.gif
地址好像是8000吧
SJA1000片选/CS是低电平有效吧? 地址应该是0X7F00,不然的话我怎么能读写测试寄存器呢?
谢谢关注! avrstm32 发表于 2012-7-24 09:18 static/image/common/back.gif
;///////////////////////////////////////MEGA64初始化程序 截取于具体项目中,绝对可以///////////////// ...
谢谢您的关注,在下只是勉强能看懂汇编的水平,不过我感觉我的问题应该是在硬件上,毕竟读写测试寄存器,配置其它寄存器都正常,就是跳不出复位模式... 爱则倾心 发表于 2012-7-24 10:04 static/image/common/back.gif
SJA1000片选/CS是低电平有效吧? 地址应该是0X7F00,不然的话我怎么能读写测试寄存器呢?
谢谢关注! ...
外部RAM地址是从0x8000开始的! avrstm32 发表于 2012-7-24 10:25 static/image/common/back.gif
外部RAM地址是从0x8000开始的!
大侠您好,怪我没说明白,我用的单片机是ATMEGA128,外部RAM是从0x1100开始的,附件图片为datasheet上的数据存储器映像图...
爱则倾心 发表于 2012-7-24 11:21 static/image/common/back.gif
大侠您好,怪我没说明白,我用的单片机是ATMEGA128,外部RAM是从0x1100开始的,附件图片为datasheet上的 ...
ATMEGA64外部RAM是从8000开始的 ,我以前没看过MEAG128的数据手册,刚才粗略看了一下,好像也是从8000开始的哦,你再仔细看看128的中文数据手册30,31页。 请问自测模式txrx相连行不,还是必须收发器
erxun 发表于 2012-7-23 17:23 static/image/common/back.gif
读写测试寄存器,没问题,可以排除硬件接口没问题,除了中断引脚。
请问sja1000自测txrx相连行不,必须要收发器吗? 00superman00 发表于 2012-7-25 09:10 static/image/common/back.gif
请问sja1000自测txrx相连行不,必须要收发器吗?
您好,我的问题还没解决,所以还没能调到那一步,从资料上看,应该不用接收发器,您试试看,
顺便问一下,您用的也是MEGA128吗?您买的SJA1000T多少钱一片?我跟我们采购人员核实了一下,我们买的是14.5元,现在很怀疑买到山寨的了。 avrstm32 发表于 2012-7-24 12:55 static/image/common/back.gif
ATMEGA64外部RAM是从8000开始的 ,我以前没看过MEAG128的数据手册,刚才粗略看了一下,好像也是从8000开 ...
我看了30、31页,没搞明白手册上说的地址映射,但我的电路里SJA1000的地址是0X7F00应该没错,因为换成别的根本就无法访问SJA1000了... 楼主你好,我也是最近开始接触CAN总线的,用的也是M128+SJA1000+82C250的方案,但是一直不得要领。看了你的帖子后按照你的程序利用串口读取了一下相应寄存器的数据。如下图所示:
我是用你的初始化程序,在复位模式时候读取一次,在工作模式读取一次,发现没有出现你所说的情况。也就是说是已经有从复位模式跳回工作模式了。
我的读取的寄存器的顺序如下:
void scan()
{
read_sja_DATA(CAN_MOD);
read_sja_DATA(CAN_CDR);
read_sja_DATA(CAN_BTR0);
read_sja_DATA(CAN_BTR1);
read_sja_DATA(CAN_OCR);
read_sja_DATA(CAN_RXERR);
read_sja_DATA(CAN_TXERR);
read_sja_DATA(CAN_ECC);
read_sja_DATA(CAN_RBSA);
read_sja_DATA(CAN_ACR0);
read_sja_DATA(CAN_ACR1);
read_sja_DATA(CAN_ACR2);
read_sja_DATA(CAN_ACR3);
read_sja_DATA(CAN_AMR0);
read_sja_DATA(CAN_AMR1);
read_sja_DATA(CAN_AMR2);
read_sja_DATA(CAN_AMR3);
read_sja_DATA(CAN_IER);
read_sja_DATA(CAN_SR);
}
不过发现了问题,就是为什么AMR 和ACR在工作模式会变化?是自动匹配生成的号码吗?希望能得到解答,谢谢
PS:我是之前加了你QQ的,有时间的话可以互相交流一下,谢谢。 爱则倾心 发表于 2012-7-25 15:03 static/image/common/back.gif
您好,我的问题还没解决,所以还没能调到那一步,从资料上看,应该不用接收发器,您试试看,
顺便问一下 ...
sja1000单买的25 好使,收发器买了三块两家每一个好使的,还十一块钱一个,貌似82C250赝品比较多 microsky 发表于 2012-7-26 22:29 static/image/common/back.gif
楼主你好,我也是最近开始接触CAN总线的,用的也是M128+SJA1000+82C250的方案,但是一直不得要领。看了你的 ...
抱歉,最近没有上线,我基本上不上QQ。
您说在工作模式ACR\AMR会变?AMR、ACR好像只有在复位模式下能读写吧,在工作模式下相应的地址为发送/接收寄存器吧 爱则倾心 发表于 2012-8-3 20:37 static/image/common/back.gif
抱歉,最近没有上线,我基本上不上QQ。
您说在工作模式ACR\AMR会变?AMR、ACR好像只有在复位模式下能读写 ...
哦哦,那个问题先搁置一下,我现在有个问题,就是我用的是你的例程,其实还是可以在复位模式后退出然后进入工作模式,不过发送一直停在0x20上面,也就是发送中,您现在是进行到哪一步了?
PS:那怎样可以和你交流一下呢? microsky 发表于 2012-8-3 22:25 static/image/common/back.gif
哦哦,那个问题先搁置一下,我现在有个问题,就是我用的是你的例程,其实还是可以在复位模式后退出然后进 ...
我的初始化配置不一定符合你的要求,多看几遍SJA1000的手册(相应模式下的寄存器部分),然后按你的想法(自收发测试、收发测试、发送方式、接收方式等)进行初始化操作...
在这里交流就挺好啊,您要是放心的话可以贴上图和程序,我解决不了的话还有众多大侠啊,呵呵...
我的问题已经解决了...正优化、做全驱动....方便的时候贴上程序...
啥年代了,还这样玩CAn ......NXP....STM32现在CAN都很好用啊。 爱则倾心 发表于 2012-8-4 10:32 static/image/common/back.gif
我的初始化配置不一定符合你的要求,多看几遍SJA1000的手册(相应模式下的寄存器部分),然后按你的想法 ...
http://www.amobbs.com/thread-5489341-1-1.html
这个就是我的帖子,其实我在参考你之前的也看过几个程序了,其实都是差不多,初始化都是这样的,可能就是晶振频率不一样就不一样而已。
有时间的话看看我帖子里面的情况吧···· powerSTM 发表于 2012-8-4 11:24 static/image/common/back.gif
啥年代了,还这样玩CAn ......NXP....STM32现在CAN都很好用啊。
惭愧,见笑,一小公司啥都得考虑成本,二小公司做的东西简单,单片机足够了.... 你好,在吗?我是之前和你讨论过SJA1000的那位,板子做好之后发觉还是发送不出去,有时候还出现总线关闭的现象,不知道是怎么回事 爱则倾心 发表于 2012-8-4 21:48 static/image/common/back.gif
惭愧,见笑,一小公司啥都得考虑成本,二小公司做的东西简单,单片机足够了.... ...
要是可以的话可以发个源代码给我参考一下吗?邮箱是1064844457@qq.com,谢谢。
这个困扰了很久了,芯片资料都看了很多遍···不知是什么问题··· 爱则倾心 发表于 2012-8-4 21:48 static/image/common/back.gif
惭愧,见笑,一小公司啥都得考虑成本,二小公司做的东西简单,单片机足够了.... ...
。。。。。。。。。。。。。。。。。SJA1000正品要十几块啊,哥哥,SJA1000就能买各一个半STM32,开发还麻烦 楼主您的问题得到解决了么?我想问一下您的SJA寄存器访问方式,是根据硬件连接访问的SJA寄存器地址,#define SJA1000_base_addr 0x7F00?
还是M128扩展存储器方式访问SJA寄存器地址0x8000?如果您方便的话,可以发一份您的资料给我吗?邮箱:scorpio_milo2005@163.com maximus811009 发表于 2013-10-9 09:24 static/image/common/back.gif
楼主您的问题得到解决了么?我想问一下您的SJA寄存器访问方式,是根据硬件连接访问的SJA寄存器地址,#defin ...
你好,附件中的电路中有一个小问题,D0--D5颠倒过来就OK了,附件中的程序以及各位大侠贴上来的程序也都没有问题,那个地址之所以是0X7F00而不是0X8000,是因为SJA1000的片选线为低电平有效...你需要再多了解一下单片机外总线及外部存储器方式访问外设等知识... 没有找到重新编辑帖子的选项,再次回复吧,遇到的问题已解决,为马虎大意造成的原理图错误引起,大侠们莫笑。。。。
原理图错误之处已在回帖中说明,更正后即可,现将系统CAN相关代码附上,希望能帮助新手做can的朋友们..... 复位脚是要给高低电平交替的,
CANB_RESET=HIGH;
CANB_RESET=LOW; CANB_RESET=LOW; CANB_RESET=LOW;
CANB_RESET=HIGH; CANB_RESET=HIGH; CANB_RESET=HIGH; 给你我的一段初始化程序(晶振16M):
voidCanBInitialize(unsigned char CanAddress)
{
CANB_RESET=HIGH;
CANB_RESET=LOW; CANB_RESET=LOW; CANB_RESET=LOW;
CANB_RESET=HIGH; CANB_RESET=HIGH; CANB_RESET=HIGH;
ModeControlRegB=0x01;
ClockDivideRegB=0x88;
InterruptEnRegB=0x00;
AcceptCode0RegB=(CanAddress|0xFF);
AcceptCode1RegB=0xff;
AcceptCode2RegB=0xff;
AcceptCode3RegB=0xff;
AcceptMask0RegB=0xff;
AcceptMask1RegB=0xff;
AcceptMask2RegB=0xff;
AcceptMask3RegB=0xff;
BusTiming0RegB =0x7f;
BusTiming1RegB =0xff; //5K
OutControlRegB =0x1a;
RxBufStartAdrB =0x00;
TxErrCountRegB =0x00;
ErrCodeCapRegB =0x00;
ModeControlRegB=0x00;
}
guowanling8061 发表于 2013-10-11 10:02 static/image/common/back.gif
给你我的一段初始化程序(晶振16M):
voidCanBInitialize(unsigned char CanAddress)
{
感谢回复,我的问题是硬件连线错误所致,惭愧...{:shy:} 爱则倾心 发表于 2013-10-15 14:35 static/image/common/back.gif
感谢回复,我的问题是硬件连线错误所致,惭愧...
发现问题就好! 很好的贴子!顶 把楼主的程序当例程看!{:lol:} 把楼主的程序当例程看 把楼主的程序当例程看
页:
[1]