|
本帖最后由 microsky 于 2012-7-31 00:05 编辑
借鉴了一下别人的程序,加上自己之前做的串口程序,读取了一下SJA1000从复位模式,到工作模式,各个寄存器数据的情况。
初始化函数如下:
void 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_ACR0,0x00);
write_char_sja1000(CAN_ACR1,0x00); //配置验收代码ACR1=0:广播
write_char_sja1000(CAN_ACR2,0x00);
write_char_sja1000(CAN_ACR3,0x55); //配置验收代码ACR3=地址
write_char_sja1000(CAN_BTR0,0x03); //设置时钟分频器,125k
write_char_sja1000(CAN_BTR1,0x1C);
write_char_sja1000(CAN_OCR,0x1A); //输出控制
write_char_sja1000(CAN_EWLR,0xFF); // 配置错误报警限制为255
write_char_sja1000(CAN_MOD,0x01); //进入复位工作模式
scan();
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中断-错误报警/发送/接收中断
scan();
}
说明一下,scan()子函数是我自己写的一个检测各个寄存器的输出的数据情况,可以直观的观察到各个寄存器的数据,我在初始化里面添加了两个scan子函数,一个在复位状态的时候,一个在工作状态的时候。
输出的各个寄存器的顺序如下面这个函数所示:
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);
}
情况如图所示:
前面检测各个寄存器的状态,还是正常的,问题就出自后面这五个0x20的数据了。发送子函数如下:
void CanTransmit(void) //CAN发送
{
unsigned char status;
cli(); //关中断
TransBuffer[0]=0x88;
TransBuffer[1]=0x00;
TransBuffer[2]=0x00;
TransBuffer[3]=0x00;
TransBuffer[4]=0x00;
TransBuffer[5]=0x01;
TransBuffer[6]=0x02;
TransBuffer[7]=0x03;
TransBuffer[8]=0x04;
TransBuffer[9]=0x05;
TransBuffer[10]=0x06;
TransBuffer[11]=0x07;
TransBuffer[12]=0xaa;
while(!(read_char_sja1000(CAN_SR)&0x04)); //wait until reg2^2==1 ,即判断发送缓冲器的状态
write_char_sja1000(CAN_TXD_FID,TransBuffer[0]); //扩展帧,数据长度为8个字节
write_char_sja1000(CAN_TXD_ID1,TransBuffer[1]);
write_char_sja1000(CAN_TXD_ID2,TransBuffer[2]);
write_char_sja1000(CAN_TXD_ID3,TransBuffer[3]);
write_char_sja1000(CAN_TXD_ID4,TransBuffer[4]);
write_char_sja1000(CAN_TXBuffer1,TransBuffer[5]);
write_char_sja1000(CAN_TXBuffer2,TransBuffer[6]);
write_char_sja1000(CAN_TXBuffer3,TransBuffer[7]);
write_char_sja1000(CAN_TXBuffer4,TransBuffer[8]);
write_char_sja1000(CAN_TXBuffer5,TransBuffer[9]);
write_char_sja1000(CAN_TXBuffer6,TransBuffer[10]);
write_char_sja1000(CAN_TXBuffer7,TransBuffer[11]);
write_char_sja1000(CAN_TXBuffer8,TransBuffer[12]);
write_char_sja1000(CAN_CMR,0x01); //发送请求命令
delay_ms(50);
read_sja_DATA(CAN_SR);
delay_ms(50);
read_sja_DATA(CAN_SR);
delay_ms(50);
read_sja_DATA(CAN_SR);
delay_ms(50);
read_sja_DATA(CAN_SR);
delay_ms(50);
read_sja_DATA(CAN_SR);
delay_ms(50);
while(!(read_char_sja1000(CAN_SR) & 0x08));//检测SR.3位,判断发送是否完成
// read_sja_DATA(CAN_SR);
delay_ms(200); // 延时200ms
sei(); //开中断
}
说明一下,后面那五个0x20的数据,是我在发送子函数那里添加的五个读取SR寄存器所得出的数据,目的是为了检测是否已经发送成功,但是结果还是0x20,也就是说一直在“发送中”的状态,这个也是我百思不得其解的地方,而且有个地方请各位高手能解解惑,因为卡在这里有一段时间了···谢谢。
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
阿莫论坛20周年了!感谢大家的支持与爱护!!
知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)
|