求助: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")
} 听说可以把SJA1000当做一个外部存储器,用直接寻址的方式读写SJA1000的寄存器,有高人解惑吗 http://www.amobbs.com/forum.php?mod=viewthread&tid=5461865 ersha4877 发表于 2015-8-13 13:47
http://www.amobbs.com/forum.php?mod=viewthread&tid=5461865
这个代码的收发函数、初始化函数在lib库里…… 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? 也不知道楼主调通没有,我说一个应该是硬件的问题:
对楼主贴出的图上RX1引脚的处理问题:现在是下拉接地。
官方资料:(PCA82C250 pdf)12页:
SJA1000的基址的问题要看单片机的手册,外挂flash,会有一个地址选择位(高于这个地址对外部flash,对应这里就是sja1000)。可以配成外部无块选择模式,只用低八位。 SJA1000的基址的问题要看单片机的手册,外挂flash,会有一个地址选择位(高于这个地址对外部flash,对应这里就是sja1000)。可以配成外部无块选择模式,只用低八位。 归结出来的问题:1、按照目前原理图的SJA1000的接法,SJA1000的基址是多少?
基址的问题在单片机的手册里应该有个寄存器控制,选择一个基址,高于这个基址就读外部,可以配成无块选择的片内外同时用
2、这样的接法,SJA1000的基址会不会和MEGA64的内部SRAM地址重合?
见上
3、若重合,怎样能只读写SJA1000的寄存器,而不误操作MEGA64的内部SRAM?
见上,配好后,先试一试一个寄存器读写,用示波器看看就知道了
我只是偶尔当当雷锋
页:
[1]