CAN总线监测到主站已经发送数据,但是从站接收不到数据,从站的状态寄存器SR=0x0c或者0x1c,IE=0x00。

yezi616 2014-07-09 08:12:01
用示波器可以看到数据波形,表明数据从主站发送到从站,用两个串口检测主站和从站的状态,从站状态寄存器SR一直是0x0c偶尔是0x1c,而中断寄存器IE一直是0x00。已经纠结好多天了,希望大家帮忙解答!下面是我的从站的C程序。
uchar idata cansend[6] ={0x81,0x01,0x02,0x00,0x00,0x11};
uchar idata RX_buffer[6];
uchar serilrece;
uchar RxFlag=0;
uchar flag=0;
void delayms(uint ms)
{
uint i, j;
for(i =ms; i >0; i--)
for(j =112; j >0; j--);
}

void Uart_Init(void)
{
TMOD = 0x20;
TH1 = 0xfd;
TL1 = 0xfd;
TR1 = 1;
SCON = 0x58;
PCON = 0x00;
EA = 1;
ES = 1;
}
void Uart_SendCh(unsigned char ch)
{
SBUF = ch;
while(TI == 0);
TI =0;
}
void uart() interrupt 4 using 2
{
if(RI == 1)
{
RI = 0;
serilrece = SBUF;
}
}
void CAN_Init()
{
uchar bdata ack0;
uchar bdata ack1;
do
{
REG_CONTROL = 0x09 ; //模式寄存器 复位模式
ack0 = REG_CONTROL ;
}
while(!(ack0&0x09));

delayms(20);
ack0=REG_CONTROL;
Uart_SendCh(ack0);
ack1=REG_STATUS;
Uart_SendCh(ack1);

REG_ACR1=0x01; //验收代码寄存器
REG_ACR2=0x02;
REG_ACR3=0x01;
REG_ACR4=0x02;
REG_AMR1=0xff; //1屏蔽验收码,0则不屏蔽
REG_AMR2=0xff;
REG_AMR3=0xff;
REG_AMR4=0xff;

REG_BTR0=0x03;
REG_BTR1=0x1c;
REG_OCR=0x1a; //输出控制寄存器 正常模式
REG_CDR=0x88; //时钟分频器,CBP被置位,只有RX0起作用,RX1被连接到一个确定的电平 最高为选择1,pelican模式
REG_INTENABLE=0x1d;
REG_COMMAND=0x04;
do //释放接收缓冲器
{
REG_CONTROL=0x08;
ack0 =REG_CONTROL;
}while(!(ack0&0x08)) ; //复位请求位接受到一个下降沿后,SJA1000回到工作模式

delayms(20);
ack0=REG_CONTROL;
Uart_SendCh(ack0);
ack1=REG_STATUS;
Uart_SendCh(ack1);
}
void CAN_TXD(void)
{
uchar bdata ack2;
ack2 = REG_STATUS;
while(!(ack2 & 0x04))
{
ack2 = REG_STATUS;
} //SR.2=0,发送缓冲器被锁。等待

REG_TXBuffer1 = cansend[0];
REG_TXBuffer2 = cansend[1];
REG_TXBuffer3 = cansend[2];
REG_TXBuffer4 = cansend[3];
REG_TXBuffer5 = cansend[4];
REG_TXBuffer6 = cansend[5];

REG_COMMAND = 0x01; //命令寄存器CMR.0=TR=1,置发送请求位为1

}
void CAN_RXD(void)
{
//接收数据函数,在中断服务程序中调用
uchar bdata ack1,ack2;
ack1 = REG_STATUS; //判断状态寄存器
Uart_SendCh(ack1);
ack2 = REG_INTERRUPT;
Uart_SendCh(ack2);
if( !(ack1 & 0x01)) return;
// if(ack1 & 0x01)
{
RX_buffer[0] = REG_RXBuffer1;
RX_buffer[1] = REG_RXBuffer2;
RX_buffer[2] = REG_RXBuffer3;
RX_buffer[3] = REG_RXBuffer4;
RX_buffer[4] = REG_RXBuffer5;
RX_buffer[5] = REG_RXBuffer6;
flag = 1;
REG_COMMAND = 0x04;
delayms(10);
Uart_SendCh(RX_buffer[0]);
delayms(10);
Uart_SendCh(RX_buffer[1]);
delayms(10);
Uart_SendCh(RX_buffer[2]);
delayms(10);
Uart_SendCh(RX_buffer[3]);
delayms(10);
Uart_SendCh(RX_buffer[4]);
delayms(10);
Uart_SendCh(RX_buffer[5]);
delayms(10);
//ack1 = ALC; //释放仲裁随时捕捉寄存器 CPU读一次时寄存器自动清除
//ack1 = ECC; //释放错误代码捕捉寄存器 CPU读一次时寄存器自动清除
}
}

void check(void)
{
do
{
CAN_RXD();
} while(flag == 0);
delayms(1000);
if(RX_buffer[5] == 0x11)
Uart_SendCh(0xff);
CAN_TXD();
}


void main(void)
{
Uart_Init();
CAN_Init();
while(1)
{
check();
}
}
...全文
784 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

3,881

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 其它技术问题
社区管理员
  • 其它技术问题社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧