我用的ATmega16单片机,sja1000的ALE、RD、WR、CS、RST分别和单片机的PD7,PD5,PD6,PC7,PC6连接。下面是一部分程序: #define REG_CONTROL 0x00 //内部控制寄存器 #define REG_COMMAND 0x01 //命令寄存器 #define REG_STATUS 0x02 //状态寄存器 #define REG_INTERRUPT 0x03 //中断寄存器 #define REG_ACR 0x04 //验收代码寄存器 #define REG_AMR 0x05 //验收屏蔽寄存器 #define REG_BTR0 0x06 //总线定时寄存器0 #define REG_BTR1 0x07 //总线定时寄存器1 #define REG_OCR 0x08 //输出控制寄存器 //以address为地址,从sja1000中读取一个字节 uchar BYTEREAD(uchar address) { uchar mid; PORTC&=~BIT(7); //片选信号有效 PORTD|=BIT(7); //置ALE为1 DDRA= 0xff; //设置A口为输出 PORTA= address; //A口输出地址 PORTD&=~BIT(7); //置ALE为0 DDRA= 0x00; //设置A口为输入 PORTD&=~BIT(5); //读信号有效 mid = PINA; PORTD|=BIT(5); //读信号置1 PORTC|=BIT(7); //片选信号置1 return mid; }
//以address为地址,向sja1000中写一个字节 void BYTEWRITE(uchar address,uchar x) { uchar mid; PORTC&=~BIT(7); //片选信号有效 PORTD|=BIT(7); //置ALE为1 DDRA= 0xff; //设置A口为输出 PORTA= address; //A口输出地址 PORTD&=~BIT(7); //置ALE为0 PORTD&=~BIT(6); //写信号有效 PORTA = x; //A口输出数据 PORTD|=BIT(6); //写信号置1 PORTC|=BIT(7); //片选信号置1 }
//can总线的复位程序 void CAN_RESET(void) { PORTC&=~BIT(6); //CAN总线复位 PORTC|=BIT(6); CLI();//禁止中断 BYTEWRITE(REG_CONTROL,0x01); while(((BYTEREAD(REG_CONTROL))&0x01)==0) { BYTEWRITE(REG_CONTROL,0x01); } BYTEWRITE(REG_CDR,0x48); BYTEWRITE(REG_COMMAND,0x0E); BYTEWRITE(REG_ACR,0x01); BYTEWRITE(REG_AMR,0x00); BYTEWRITE(REG_OCR,0xaa); BYTEWRITE(REG_BTR0,0x01); BYTEWRITE(REG_BTR1,0x1c); //250kbps BYTEWRITE(REG_CONTROL,0x1F); BYTEWRITE(REG_CONTROL,0x1E); while(((BYTEREAD(REG_CONTROL))&0x01)==1) { PORTC&=~0x04; BYTEWRITE(REG_CONTROL,0x1E);//问题出在这里 } }
请教各位高手,现在我的问题是当我给sja1000的控制器写值0x1E(让它回到操作模式) 却进入了上面程序的“问题出在这里”,而且奇怪的是sja1000的复位脚的电平是高电平,那就说明回到了操作模式,可是又怎么会进入到这个里面去呢?(我怎么觉得好象sja1000的内部控制器的值一直保持为0x01没变)请问这个问题怎么解决啊,谢谢!! |