znxy141w1 发表于 2015-8-13 11:41:32

求助:MEGA64+SJA1000,写SJA寄存器不成功,SJA初始化不成功

本帖最后由 znxy141w1 于 2015-8-13 11:41 编辑



我初学CAN-BUS,之前从未用过。原理图如上,我对着时序图模拟时序想读写SJA1000的寄存器,发现可以读SJA寄存器(读不同寄存器得到的值不同),求高人帮忙!
代码如下:

#define ucharunsigned char
#define uint   unsigned int

#define SET_ALE   PORTD.4=1//SJA1000的ALE信号线PD4            
#define CLR_ALE   PORTD.4=0      
#define SET_RST   PORTD.5=1//SJA1000的RST信号线PD5      
#define CLR_RST   PORTD.5=0
#define CAN_INT   PIND.3//SJA1000的INT信号线PD3
#define SET_CS    PORTD.2=1//SJA1000的CS信号线PD2
#define CLR_CS    PORTD.2=0
#define SET_RD    PORTD.1=1//SJA1000的RE信号线PD1
#define CLR_RD    PORTD.1=0
#define SET_WR    PORTD.0=1//SJA1000的WR信号线PD0
#define CLR_WR    PORTD.0=0
#define PC_OUT    DDRC=0xFF//SJA1000地址\数据线PC
#define PC_IN   DDRC=0x00
#define DATA_OUTPORTC
#define DATA_IN   PINC

//*******************CAN寄存器地址**************************//
#define CAN_MOD   0      //模式寄存器
#define CAN_CMR   1      //命令寄存器 只写
#define CAN_SR      2      //状态寄存器 只读
#define CAN_IR      3      //中断寄存器 只读
#define CAN_IER   4      //中断使能寄存器
#define CAN_BTR0    6      //总线定时寄存器0
#define CAN_BTR1    7      //总线定时寄存器1
#define CAN_OCR   8      //输出控制寄存器
#define CAN_TEST    9      //测试寄存器
#define CAN_ALC   11   //仲裁丢失寄存器
#define CAN_ECC   12   //错误代码捕捉寄存器
#define CAN_EWLR    13   //错误报警限制寄存器
#define CAN_EXERR   14   //RX错误计数寄存器
#define CAN_TXERR   15   //TX错误计数寄存器
#define CAN_ACR0    16   //验收码寄存器0
#define CAN_ACR1    17   //验收码寄存器1
#define CAN_ACR2    18   //验收码寄存器2
#define CAN_ACR3    19   //验收码寄存器3
#define CAN_AMR0    20   //验收屏蔽寄存器0
#define CAN_AMR1    21   //验收屏蔽寄存器1
#define CAN_AMR2    22   //验收屏蔽寄存器2
#define CAN_AMR3    23   //验收屏蔽寄存器3
#define CAN_TXB   16   //发送缓冲区首地址(工作模式)
#define CAN_RXB   16   //接收缓冲区首地址(工作模式)
#define CAN_RMC   29   //RX信息计数器
#define CAN_RBSA    30   //RX缓冲区起始地址寄存器
#define CAN_CDR   31   //时钟分频器
#define ID3         00      //ID3

uchar RX_buffer; //接收的数据
uchar TX_buffer; //接收的数据
uchar AMR,ACR;

uchar ReadSJA(uchar address) //读SJA
{
   uchar data;
   SET_CS;
   SET_RD;
   SET_WR;
   CLR_ALE;
   delay_ms(1);
   SET_ALE;
   delay_ms(5);
   PC_OUT;//令PC口为输出
   delay_ms(1);
   DATA_OUT=address;    //输出数据地址
   delay_ms(1);
   CLR_ALE;
   delay_ms(1);
   PC_IN;   //令PC口为输入
   CLR_CS;
   CLR_RD;//使能RD
   delay_ms(1);
   data=DATA_IN;//读回数据
   SET_RD;
   delay_ms(1);
   SET_CS;
   return data;
}

void WriteSJA(uchar address,uchar data)//写SJA
{
   SET_CS;
   SET_RD;
   SET_WR;
   CLR_ALE;
   delay_ms(1);
   SET_ALE;
   delay_ms(5);
   PC_OUT;//令PC口为输出
   delay_ms(1);
   DATA_OUT=address;    //输出数据地址
   delay_ms(1);
   CLR_ALE;
   delay_ms(1);
   CLR_CS;
   CLR_WR;
   delay_ms(1);
   DATA_OUT=data; //输出数据
   delay_ms(5);
   SET_WR;
   delay_ms(1);
   SET_CS;
}

void InitSJA(void)
{
   uchar temp;
   SET_RST;
   delay_ms(10);
   CLR_RST;
   delay_ms(100);
   SET_RST;
   delay_ms(1000);
   #asm("cli")      
   do
   {
      
      #asm("wdr")
      WriteSJA(CAN_MOD,0x01);
      temp=ReadSJA(CAN_MOD);
   }while(!(temp&0x01));
   //PORTE=0x01;
   WriteSJA(CAN_CDR,0x88);    //时钟分频寄存器-设置PeliCAN 模式,Clock off 无效
   WriteSJA(CAN_BTR0,0x31);   //配置总线定时--10kbps
   WriteSJA(CAN_BTR1,0x1c);
   WriteSJA(CAN_IER,0x01);   //中断使能寄存器-接收中断使能
   WriteSJA(CAN_OCR,0xaa);    //配置输出控制
   WriteSJA(CAN_CMR,0x04);   //命令寄存器-释放RXFIF0
   WriteSJA(CAN_AMR0,AMR);   //配置验收屏蔽AMR0=0FFH
   WriteSJA(CAN_AMR1,AMR);   //配置验收屏蔽AMR1=000H
   WriteSJA(CAN_AMR2,AMR);   //配置验收屏蔽AMR2=0FFH
   WriteSJA(CAN_AMR3,AMR);   //配置验收屏蔽AMR3=000H
   WriteSJA(CAN_ACR0,ACR);   //配置验收代码ACR1=0:广播
   WriteSJA(CAN_ACR1,ACR);
   WriteSJA(CAN_ACR2,ACR);
   WriteSJA(CAN_ACR3,ACR);   //配置验收代码ACR3=地址
   //Write_SJA1000(CAN_EWLR,0xff);   //配置错误报警限制为255
   do
   {
      WriteSJA(CAN_MOD,0x00); //退出复位模式,进入工作模式双滤波   
      #asm("wdr")
   }while((ReadSJA(CAN_MOD))&0x01); // 确认复位标志是否被删除
   WriteSJA(CAN_TXB+4,ID3);//配置发送缓冲区的ID3-
   WriteSJA(CAN_IER,0x07);   //配置SJA10000中断-错误报警/发送/接收中断      
   #asm("sei")
}

znxy141w1 发表于 2015-8-13 11:41:33

听说可以把SJA1000当做一个外部存储器,用直接寻址的方式读写SJA1000的寄存器,有高人解惑吗

ersha4877 发表于 2015-8-13 13:47:03

http://www.amobbs.com/forum.php?mod=viewthread&tid=5461865

znxy141w1 发表于 2015-8-13 18:47:08

ersha4877 发表于 2015-8-13 13:47
http://www.amobbs.com/forum.php?mod=viewthread&tid=5461865

这个代码的收发函数、初始化函数在lib库里……

bbs2009 发表于 2015-8-15 08:04:18

bbs2009 发表于 2015-8-15 08:05:55

znxy141w1 发表于 2015-8-17 08:51:10

bbs2009 发表于 2015-8-15 08:05
把SJA1000当做一个外部存储器,用直接寻址的方式读写SJA1000的寄存器 ,没错啊。
找一个51 , SJA1000...

现在硬件暂时没办法改,只能是用我所发的原理图上的,但是我不会算在这个硬件接法中SJA1000的基址。而按照一些资料的说法,MEGA64的内部SRAM地址是0x0000~0x10FF,我的原理图里面的SJA1000接法,读写SJA1000的寄存器时,地址好像会和MEGA64的内部SRAM地址重合……

归结出来的问题:1、按照目前原理图的SJA1000的接法,SJA1000的基址是多少?
                        2、这样的接法,SJA1000的基址会不会和MEGA64的内部SRAM地址重合?
                        3、若重合,怎样能只读写SJA1000的寄存器,而不误操作MEGA64的内部SRAM?

zyqcome 发表于 2015-8-17 11:40:26

也不知道楼主调通没有,我说一个应该是硬件的问题:

对楼主贴出的图上RX1引脚的处理问题:现在是下拉接地。

官方资料:(PCA82C250 pdf)12页:

zyqcome 发表于 2015-8-17 11:45:57

SJA1000的基址的问题要看单片机的手册,外挂flash,会有一个地址选择位(高于这个地址对外部flash,对应这里就是sja1000)。可以配成外部无块选择模式,只用低八位。

zyqcome 发表于 2015-8-17 11:50:01

SJA1000的基址的问题要看单片机的手册,外挂flash,会有一个地址选择位(高于这个地址对外部flash,对应这里就是sja1000)。可以配成外部无块选择模式,只用低八位。

zyqcome 发表于 2015-8-17 11:50:54

归结出来的问题:1、按照目前原理图的SJA1000的接法,SJA1000的基址是多少?
                                基址的问题在单片机的手册里应该有个寄存器控制,选择一个基址,高于这个基址就读外部,可以配成无块选择的片内外同时用
                        2、这样的接法,SJA1000的基址会不会和MEGA64的内部SRAM地址重合?
                                见上
                        3、若重合,怎样能只读写SJA1000的寄存器,而不误操作MEGA64的内部SRAM?
                                见上,配好后,先试一试一个寄存器读写,用示波器看看就知道了

我只是偶尔当当雷锋
页: [1]
查看完整版本: 求助:MEGA64+SJA1000,写SJA寄存器不成功,SJA初始化不成功