打印
[CAN-bus/DeviceNet]

关于基于SJA1000的can节点之间通信

[复制链接]
3022|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jeasonlsn|  楼主 | 2010-3-14 10:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本人做了两个基于SJA1000的can节点,每个节点在PELI模式下都能实现自发自收,但连在总线上时不能通信。
当一个节点发送数据时,查了SR的状态标志位0x08,一直为1,说明上次的发送还未处理完,应该是没有收到另外一个节点的应答信号吧。我查了资料,要收到另外一个节点的应答信号,只要另外一个节点的波特率和初始化都正确的话就可以了,但是两个节点的初始化都是没问题的,至于波特率我换了好多个都是不行。
我的收发器用的是82c251,斜率电阻用47k
望哪个高手能解答一下

相关帖子

沙发
lnskngdc| | 2010-3-15 09:33 | 只看该作者
1.波特率要一致,82251的话建议用100kbps
2.CAN_H与CAN_H连接,CAN_L与CAN_L连接。
3,设置节点发送间隔时间长点,不要一直连续不断的发,另一个只收不发。
4,检查硬件连接环境,电缆是否短路,终端电阻是否接上。

先按上面四步检查

使用特权

评论回复
板凳
jeasonlsn|  楼主 | 2010-3-15 22:03 | 只看该作者
还是不行,上面4步我都检查了,还是一样的问题,一个节点收不到另外一个节点的应答信号,发送标志位一直为1,我查了另外一个节点的接入点(82c251的RX),有波形输入啊,那硬件应该没问题啊,自检也可以啊,程序我找了好多个,难道是程序的问题?
#include "SJA_BCANCONF.H"
#include <string.h>


/* 初始化SJA1000                       */
unsigned char SJA1000_Config_Normal()
{
if(BCAN_CREATE_COMMUNATION()) return 1;//读写测试寄存器失败

if(BCAN_ENTER_RETMODEL()) return 2; //复位失败

if(BCAN_SET_OUTCLK (0x1a,0x88)) return 4;//设置OCR=0X1A,T0推挽输出         CDR=0X00,peli模式,输入没有启用旁路功能 时钟输出为 fOSC/2                          失败

if(BCAN_SET_BANDRATE(0x00)) return 3; //设置波特率通信          失败


if(BCAN_SET_OBJECT(0x44,0x55,0x66,0x00,0x00,0x00,0x00,0x0f)) return 5;

if(BCAN_MODE_COMMUNATION(0x08)) return 8;//设置单滤波模式          包括恢复到工作模式

return 0;//初始化成功
}

#include "regx52.h"                         //创作时间2009-03-04
#include <intrins.h>
#include "lcd1602.c"
#include "key.c"
#include"SJA_BCANCONF.c"
bit SuccessFlag=1;
unsigned test=1;
unsigned temp;
//
void main()
{
SJA1000_RST=1;

delay1ms(200); //启动等待,等LCD讲入工作状态
LCDInit(); //LCD初始化

SJA1000_RST=0;//SJA1000硬件复位
delay1ms(2);

SJA1000_RST=1;       
delay1ms(5);


DisplayOneChar(5,0,SJA1000_Config_Normal()+'0');//SJA1000 initial


                                 SuccessFlag=BCAN_DATA_WRITE(SendData);//发数据
                                 
                                 if(!SuccessFlag)
                                 {
                                 DisplayOneChar(10, 0, '0');
                                 BCAN_CMD_PRG(TR_CMD); //启动发送命令
                                 }
                                 else         DisplayOneChar(10, 0, '1');
       
                                 

                                SJA_BCANAdr = REG_STATUS; //访问地址指向状态寄存器
                                 temp=*SJA_BCANAdr;

                                 DisplayOneChar(4, 1, temp/100+'0');//显示SR的值
                                DisplayOneChar(5, 1,(temp/10)%10+'0');
                               DisplayOneChar(6, 1,temp%10+'0');
                                temp&=0x20;
                                 while(temp == 0x20)            //检查是否发送完成
                                  {
                                         DisplayOneChar(11, 0, '1');
                                  temp=*SJA_BCANAdr;
                                 DisplayOneChar(4, 1, temp/100+'0');
                                 DisplayOneChar(5, 1,(temp/10)%10+'0');
                                 DisplayOneChar(6, 1,temp%10+'0');
                                temp&=0x20;
                                   }

                                 DisplayOneChar(11, 0, '0');
       
               
                                  test^=1;
                                 led3=test;//test跟踪按键的变化
                               
                                 }break;

       
                                   SJA_BCANAdr= REG_Receive_Counter;//查看接收缓冲区中信息的个数
                                  temp=*SJA_BCANAdr;
                                   DisplayOneChar(14, 1, temp/10+'0');
                                    DisplayOneChar(15, 1, temp%10+'0');

                                 
                                  SuccessFlag=BCAN_DATA_RECEIVE(ReceiveData);//接收数据
                                 if(!SuccessFlag)
                                   {
                                 
                                 DisplayOneChar(15, 0, '0');
                                  for(k=0;k<13;k++)//显示数据
                                     {
                                  DisplayOneChar(k, 1, ReceiveData[k]+'0');
                                      }
                                        }
                               else         DisplayOneChar(15, 0, '1');       
                                  
                              
while(1);
}

code unsigned char SendData[13]={0x88,0x44,0x55,0x66,0x00,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x02};  //扩展帧,长度为8
unsigned char ReceiveData[13]={0,0,0,0,0,0,0,0,0,0,0,0,0}; //存放接收数据

使用特权

评论回复
地板
jeasonlsn|  楼主 | 2010-3-15 22:10 | 只看该作者
我用普通的线连起来的,大概有30cm长而已,有接终端电阻

使用特权

评论回复
5
lnskngdc| | 2010-3-15 22:30 | 只看该作者
发送的时候用示波器看82250向外发送的CAN_H和CAN_L引脚是否有波形,如果没有,说明你的电路可能有问题.

使用特权

评论回复
6
lnskngdc| | 2010-3-15 22:31 | 只看该作者
接收节点要设置可以接收所有报文,不要滤波.

使用特权

评论回复
7
jeasonlsn|  楼主 | 2010-3-16 12:33 | 只看该作者
CAN_H和CAN_L有波形啊,当发送数据后我查了SR寄存器,值为0x30,说明又在传输数据又在接受数据,可我设置的是正常工作模式,不是自检模式啊,自检模式之前调过了说明硬件电路没问题吧,真是晕啊,

使用特权

评论回复
8
lnskngdc| | 2010-3-16 21:39 | 只看该作者
两个节点地址如何设置的?初始化的时候要把两个节点地址分别设置

使用特权

评论回复
9
jeasonlsn|  楼主 | 2010-3-17 10:18 | 只看该作者
这个我知道啊,在两块板上的地址是不一样的,

使用特权

评论回复
10
jeasonlsn|  楼主 | 2010-3-18 18:31 | 只看该作者
今天终于实现了两个点的通信了,原来是板上的晶振引脚虚焊了,但是奇怪的是居然自检成功了,CAN_H和CAN_L上有波形,真是郁闷,不过总算搞定了。。

使用特权

评论回复
11
lnskngdc| | 2010-3-19 15:32 | 只看该作者
晕啊,其实我忘了说一点关于晶振的事情,哈哈。
那就是:cpu不要和sja1000公用一个16M的晶振。这完完全全是血的教训啊。

使用特权

评论回复
12
ppsen| | 2010-3-25 21:47 | 只看该作者
可以,加个反相器就行了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

25

帖子

1

粉丝