打印
[CAN-bus/DeviceNet]

can总线BASIC模式求助啊

[复制链接]
1939|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
401968875|  楼主 | 2012-5-12 16:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我一个用的PCA82c200,一个用的SJA1000的,可是两个不能通信啊,下面贴出我的程序
#include <reg52.h>
#include <intrins.h>
#include <can_selfdef.h>
void INT0_Counter( void ) interrupt 0 using 1
{//INT0按键为计数按键
    EA = 0;
    Txd_data++; //存储计数结果,并为待发送的数据
    TXD_flag = 1;//要发送数据标志位
    EA = 1;
}

void CAN_TX( void ) interrupt 2
{//发送数据函数,在中断服务程序中调用
    uchar data Judge;
    EA = 0;//关CPU中断
    IE1 = 0;
Rxd_data++;
    Judge = IR;
    if( Judge & 0x02)
    {
       CMR = 0X04;
    }
    CR = 0x04;// .1=1--发送中断使能;
    EA = 1;//打开CPU中断
}
void main(void)
{
CPU_init(  ); //CPU初始化
    CAN_init(  ); //SJA1000初始化,对 SJA1000寄存器的读写是采用外部寄存器寻址方式,所以不需要程序单独控制片选有效无效
    _nop_();
    _nop_();
    while(1)
    {
        _nop_();
        _nop_();
  Txd_deal();//发送处理程序
        led_seg7(1,Txd_data);
  led_seg7(3,Rxd_data);
        
    }
}
//*********************CPU初始化函数********************************
void CPU_init(void)
{//初始化CPU
    SJA_RST = 0;//CAN总线复位管脚有效
Delay( 20 );
    SJA_RST = 1;//CAN总线复位管脚无效
    SJA_CS = 0;//CAN总线片选有效
    EX1 = 1;
    IT1 = 0;//CAN总线接收中断
    IT0 = 1;//外部中断0负边沿触发
    EX0 = 1;//打开外部中断0
    EA = 1; //打开总中断
    SJA_CS = 1;//CAN总线片选无效,使对数据总线的操作不会影响SJA1000。
}
void Txd_deal(void)
{//发送处理函数,主要是准备数据,并且调用发送函数
    if( TXD_flag == 1 )
    {
        _nop_();
        TXD_flag = 0;
        TX_buffer[2]  = Txd_data;//
        CAN_TXD();
        _nop_();
        _nop_();
     }
}
//*********************处理函数********************************

//*********************CAN子函数***********************
void CAN_init( void )
{//SJA1000 的初始化
    uchar bdata Judge;
    do
    {//  .0=1---reset MODRe,进入复位模式,以便设置相应的寄存器
     //防止未进入复位模式,重复写入
        CR   = 0x05;
Judge = CR ;
    }
    while( !(Judge & 0x01) );
    CDR  = 0x04;// CDR.3=1--时钟关闭, .7=0---basic CAN, .7=1---Peli CAN
BTR0 = 0xcf;
    BTR1 = 0xff;//总线波特率设定
    OCR  = 0xaa;// 配置输出控制寄存器
    CMR  = 0x04;//释放接收缓冲器
    ACR  = 0xaa;
    AMR  = 0xff;   
do
    {
CR   = 0x04;
Judge  = CR;
     }
    while( !(Judge & 0x04) );
}//SJA1000 的初始化

void CAN_TXD( void )
{
    uchar data Judge;
    uchar data TX_buffer[3];
//初始化标识符头信息
    TX_buffer[0] = 0xab;//报文信息;.7=1扩展帧;.6=0数据帧; .3~0=1数据长度
    TX_buffer[1] = 0x01;//报文标识符
//初始化标识符头信息
//初始化发送数据单元
    TX_buffer[2]  = Txd_data;
//  Judge=IR ;
//初始化数据信息
    EA = 0; //关中断
//    do
//    {
//        Judge = SR;
//        LED_RED = 0;//
//    }
//    while( Judge & 0x10 );  //SR.4=1 正在接收,等待
    do//第二次发送不成功,死循环
    {
        Judge = SR;
        LED_RED = 0;//
    }
    while(!(Judge & 0x08)); //SR.3=0,发送请求未处理完,等待
LED_GRE = !LED_GRE;
    do
    {
        Judge = SR;
        LED_RED = 0;//
    }
    while(!(Judge & 0x04)); //SR.2=0,发送缓冲器被锁。等待
    LED_RED = !LED_RED;
NOP5;
NOP5;
    LED_GRE = !LED_GRE;//灯闪烁
    TBSR   = TX_buffer[0];
    TBSR1  = TX_buffer[1];
    TBSR2  = TX_buffer[2];
//CR=0X04;
EA  = 1;
CMR = 0x03;//
   
}
void Delay(uchar delay_time)
{//延时程序
    while(delay_time--)
    {}
}
//*********************CAN子函数*************************

//*********************显示子函数*************************
void led_seg7(uchar from,uchar number)  //from(1_4):数码管显示起始位置(从右到左),number:显示的数(数码管上采用10进制显示)
{
    uchar digit,temp_l;
    uchar temp_h=0x7f;
    temp_h = _cror_(temp_h,from-1);   //确定从哪一位开始显示,即确定高四位
    temp_h = temp_h & 0xf0;           //取高四位
    temp_l = P2 & 0x0f;               //取P2的低四位
    P2 = temp_h | temp_l;             //设定P2口
    if(number==0)
    {
        P0 = led[0];
        Delay(10);
        P0 = 0xff;
    }        
    else
    {
        while(number)
        {
          digit = number%10 ;
          number /= 10;
             P0 = led[digit] ;
          Delay(10);
             temp_h = P2 & 0xf0;               //取P2的高四位
             temp_h = temp_h | 0x0f;           //拼装 temp_h,进行位选
          temp_h = _cror_(temp_h,1);
          temp_h = temp_h & 0xf0;           //取高四位
       temp_l = P2 & 0x0f;               //取P2的低四位
             P0 = 0xff;
             P2 = temp_h | temp_l;             //设定P2口
        }
    }

}
上面是发送的


#include <reg52.h>
#include <intrins.h>
#include <can_selfdef.h>
void CAN_RXD( void ) interrupt 2
{//接收数据函数,在中断服务程序中调用
    uchar data Judge;
    EA = 0;//关CPU中断
    IE1 = 0;
Rxd_data=2;
    Judge = IR;
       if( Judge & 0x01)
    {//IR.0 = 1 接收中断
        RXD_flag = 1;//置有接收标志
        RX_buffer[5]=RBSR2;  
     //CMR = 0X04;
    }
    CR = 0x02;// .1=1--接受中断使能;
    EA = 1;//打开CPU中断
}
void main(void)
{

CPU_init(  ); //CPU初始化
    CAN_init(  ); //SJA1000初始化,对 SJA1000寄存器的读写是采用外部寄存器寻址方式,所以不需要程序单独控制片选有效无效
    _nop_();
    _nop_();
    while(1)
    {
        _nop_();
        _nop_();
  Rxd_deal();//接收处理程序      
        led_seg7(3,Rxd_data);
  led_seg7(1,d);
    }
}
//*********************CPU初始化函数********************************
void CPU_init(void)
{//初始化CPU
    SJA_RST = 0;//CAN总线复位管脚有效
Delay( 20 );
    SJA_RST = 1;//CAN总线复位管脚无效
    SJA_CS = 0;//CAN总线片选有效
    EX1 = 1;
    IT1 = 0;//CAN总线接收中断
//    IT0 = 1;//外部中断0负边沿触发
//    EX0 = 1;//打开外部中断0
    EA = 1; //打开总中断
    SJA_CS = 1;//CAN总线片选无效,使对数据总线的操作不会影响SJA1000。
}

void Rxd_deal(void)
{//////// 接收处理程序//////////////
    if( RXD_flag )
    {
        EA = 0;//关闭CPU中断
        RXD_flag = 0;
        Rxd_data = RX_buffer[5];
        EA = 1;
     }
}//////// 接收处理程序//////////////
//*********************处理函数********************************

//*********************CAN子函数***********************
void CAN_init( void )
{//SJA1000 的初始化
    uchar bdata Judge;
    do
    {
    TEST   = 0xAA;
Judge = TEST ;
    }
    while( !(Judge & 0xAA) );
d=4;

do
    {//  .0=1---reset MODRe,进入复位模式,以便设置相应的寄存器
     //防止未进入复位模式,重复写入
    CR   = 0x01;
Judge = CR ;
    }
    while( !(Judge & 0x01) );
    CDR  = 0x04;// CDR.3=1--时钟关闭, .7=0---basic CAN, .7=1---Peli CAN
BTR0 = 0xcf;
    BTR1 = 0xff;//总线波特率设定
    OCR  = 0xaa;// 配置输出控制寄存器
    CMR  = 0x04;//释放接收缓冲器
    ACR  = 0xab;
    AMR  = 0xff;
do
    {
CR   = 0x02;
Judge  = CR;
     }
    while( !(Judge & 0x02) );
}//SJA1000 的初始化
void Delay(uchar delay_time)
{//延时程序
    while(delay_time--)
    {}
}
//*********************CAN子函数*************************

//*********************显示子函数*************************
void led_seg7(uchar from,uchar number)  //from(1_4):数码管显示起始位置(从右到左),number:显示的数(数码管上采用10进制显示)
{
    uchar digit,temp_l;
    uchar temp_h=0x7f;
    temp_h = _cror_(temp_h,from-1);   //确定从哪一位开始显示,即确定高四位
    temp_h = temp_h & 0xf0;           //取高四位
    temp_l = P2 & 0x0f;               //取P2的低四位
    P2 = temp_h | temp_l;             //设定P2口
    if(number==0)
    {
        P0 = led[0];
        Delay(10);
        P0 = 0xff;
    }        
    else
    {
        while(number)
        {
          digit = number%10 ;
          number /= 10;
             P0 = led[digit] ;
          Delay(10);
             temp_h = P2 & 0xf0;               //取P2的高四位
             temp_h = temp_h | 0x0f;           //拼装 temp_h,进行位选
          temp_h = _cror_(temp_h,1);
          temp_h = temp_h & 0xf0;           //取高四位
       temp_l = P2 & 0x0f;               //取P2的低四位
             P0 = 0xff;
             P2 = temp_h | temp_l;             //设定P2口
        }
    }

}

上面是接受的

两者共用一个头文件
# define uchar unsigned char
# define uint  unsigned int

# define NOP5  {_nop_();_nop_();_nop_();_nop_();_nop_();}/*延时5us*/
#define     N_can      10//一帧字节数
bit         TXD_flag = 0;// 若为1,要求发送处理
bit         RXD_flag = 0;
uint d;

uchar code led[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92, // 0, 1, 2, 3, 4, 5
               0x82,0xf8,0x80,0x90, 0xff};    //  6, 7, 8, 9, off
                                //编码规则是gfedcba ,其中g为小数点,控制dp,这里都设为1,不亮
uchar       RX_buffer[13];  //接收的数据
uchar       TX_buffer[13];  //接收的数据
uchar       Txd_data = 0;//CAN总线要发送的数据,也是要在数码管1-2位置显示的数据
uchar       Rxd_data= 0;//CAN总线要接收的数据,也是要在数码管3-4位置显示的数据

/*P2 口分配*/
sbit    LED_RED = P2^1;
sbit    LED_GRE = P2^2;
sbit    SJA_RST = P2^3;//SJA1000复位管脚
sbit    SJA_CS  = P2^0;//SJA1000片选管脚
/*CAN总线SJA1000寄存器地址定义(用的是PeliCAN模式,扩展帧EFF模式)*/
#define CR      (*(unsigned char volatile xdata *)0xFE00) // 控制寄存器
#define CMR  (*(unsigned char volatile xdata *)0xFE01) // 命令寄存器
#define SR   (*(unsigned char volatile xdata *)0xFE02) // 状态寄存器
#define IR   (*(unsigned char volatile xdata *)0xFE03) // 中断寄存器
#define ACR  (*(unsigned char volatile xdata *)0xFE04) // 验收代码
#define AMR  (*(unsigned char volatile xdata *)0xFE05) // 验收屏蔽
#define BTR0  (*(unsigned char volatile xdata *)0xFE06) // 总线定时寄存器0 ;总线波特率的选择
#define BTR1  (*(unsigned char volatile xdata *)0xFE07) // 总线定时寄存器1 ;总线波特率的选择
#define OCR  (*(unsigned char volatile xdata *)0xFE08) // 输出控制寄存器
#define TEST  (*(unsigned char volatile xdata *)0xFE09)
#define CDR  (*(unsigned char volatile xdata *)0xFE1F) // 时钟分频
#define TBSR  (*(unsigned char volatile xdata *)0xFE0A) //发送缓冲器地址(0x0A_0x13)
#define TBSR1  (*(unsigned char volatile xdata *)0xFE0B) //
#define TBSR2  (*(unsigned char volatile xdata *)0xFE0C) //
#define TBSR3  (*(unsigned char volatile xdata *)0xFE0D) //
#define TBSR4  (*(unsigned char volatile xdata *)0xFE0E) //
#define TBSR5  (*(unsigned char volatile xdata *)0xFE0F) //
#define TBSR6  (*(unsigned char volatile xdata *)0xFE10) //
#define TBSR7  (*(unsigned char volatile xdata *)0xFE11) //
#define TBSR8  (*(unsigned char volatile xdata *)0xFE12) //
#define TBSR9  (*(unsigned char volatile xdata *)0xFE13) //

#define RBSR  (*(unsigned char volatile xdata *)0xFE14) //接收缓冲器首地址(0x14_0x1D)
#define RBSR1  (*(unsigned char volatile xdata *)0xFE15) //
#define RBSR2  (*(unsigned char volatile xdata *)0xFE16) //
#define RBSR3  (*(unsigned char volatile xdata *)0xFE17) //
#define RBSR4  (*(unsigned char volatile xdata *)0xFE18) //
#define RBSR5  (*(unsigned char volatile xdata *)0xFE19) //
#define RBSR6  (*(unsigned char volatile xdata *)0xFE1A) //
#define RBSR7  (*(unsigned char volatile xdata *)0xFE1B) //
#define RBSR8  (*(unsigned char volatile xdata *)0xFE1C) //
#define RBSR9  (*(unsigned char volatile xdata *)0xFE1D) //

void CPU_init(void); //CPU初始化子函数
void CAN_init( void );  //初始化CAN总线芯片
void CAN_TXD( void );   //CAN发送子函数
void Rxd_deal(void); //接收处理函数
void Txd_deal(void); //发送处理函数
void Delay(uchar delay_time);//延时子函数
void led_seg7(uchar from,uchar number);//显示子函数


对了,有一个想不通的问题,当我把发送程序下到2快板子是,发现SJA1000的不能进入发送中断,而PCA82C200是可以的,好奇怪啊

相关帖子

沙发
401968875|  楼主 | 2012-5-12 17:44 | 只看该作者
不能沉啊啊啊啊啊

使用特权

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

本版积分规则

1

主题

12

帖子

1

粉丝