|
本帖最后由 znxy141w1 于 2015-8-13 11:41 编辑
我初学CAN-BUS,之前从未用过。原理图如上,我对着时序图模拟时序想读写SJA1000的寄存器,发现可以读SJA寄存器(读不同寄存器得到的值不同),求高人帮忙!
代码如下:
#define uchar unsigned 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_OUT PORTC
#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[13]; //接收的数据
uchar TX_buffer[13]; //接收的数据
uchar AMR[4],ACR[4];
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[0]); //配置验收屏蔽AMR0=0FFH
WriteSJA(CAN_AMR1,AMR[1]); //配置验收屏蔽AMR1=000H
WriteSJA(CAN_AMR2,AMR[2]); //配置验收屏蔽AMR2=0FFH
WriteSJA(CAN_AMR3,AMR[3]); //配置验收屏蔽AMR3=000H
WriteSJA(CAN_ACR0,ACR[0]); //配置验收代码ACR1=0:广播
WriteSJA(CAN_ACR1,ACR[1]);
WriteSJA(CAN_ACR2,ACR[2]);
WriteSJA(CAN_ACR3,ACR[3]); //配置验收代码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")
} |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|