⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 can

📁 can通信源码
💻
字号:
//此函数作用:当节点得到远程帧后,向另外的节点发送Txd = 4 作为返回值

#include <reg52.h>
#include <intrins.h>
#include <can_showdef.h>

void CAN_RXD( void ) interrupt 2
{//接收数据函数,在中断服务程序中调用

    uchar data Judge;
    EA = 0;//关CPU中断
    IE0 = 0;

    Judge = IR;
    if( Judge & 0x01)
    {//IR.0 = 1 接收中断
        RX_buffer[0] =  RBSR;
        RX_buffer[1] =  RBSR1;
        RX_buffer[2] =  RBSR2;
        RX_buffer[3] =  RBSR3;
        RX_buffer[4] =  RBSR4;
        RX_buffer[5] =  RBSR5;
        RX_buffer[6] =   RBSR6;
        RX_buffer[7] =  RBSR7;
        RX_buffer[8] =  RBSR8;
        RX_buffer[9] =  RBSR9;
        RX_buffer[10] =  RBSR10;
        RX_buffer[11] =  RBSR11;
        RX_buffer[12] =  RBSR12;
        RXD_flag = 1;//置有接收标志
        CMR = 0X04;
        Judge = ALC;//释放仲裁随时捕捉寄存器
        Judge = ECC;//释放错误代码捕捉寄存器
    }
    IER = 0x01;// .0=1--接收中断使能;
    EA = 1;//打开CPU中断
}

//////// 接收处理程序//////////////
void Rxd_deal(void)
{
    if( RXD_flag )
    {
        EA = 0;//关闭CPU中断
        RXD_flag = 0;
		if(RX_buffer[0]==0xc8)
		Txd = 4;
	 	CAN_TXD();
        EA = 1;
     }
}


//发送处理函数,主要是准备数据,并且调用发送函数
void Txd_deal(void)
{
        CAN_TXD();
        _nop_();
        _nop_();
}



void CAN_TXD( void )
{
    uchar data Judge;
    uchar data TX_buffer[ N_can ] ;

//初始化标示码头信息
    TX_buffer[0] = 0x88;//.7=0扩展帧;.6=0数据帧; .3=1数据长度
    TX_buffer[1] = 0x01;//本节点地址
    TX_buffer[2] = 0x02;//
    TX_buffer[3] = 0x03;//
    TX_buffer[4] = 0x00;//
//初始化标示码头信息

//初始化发送数据单元
    TX_buffer[5]  = Txd;
    TX_buffer[6]  = 0x22;
    TX_buffer[7]  = 0x33;
    TX_buffer[8]  = 0x44;//
    TX_buffer[9]  = 0x55;//
    TX_buffer[10] = 0x66;//
    TX_buffer[11] = 0x77;//
    TX_buffer[12] = 0x88;//


//初始化数据信息
    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,发送请求未处理完,等待
    
    do
    {
        Judge = SR;
        LED_RED = 0;//
    }
    while(!(Judge & 0x04)); //SR.2=0,发送缓冲器被锁。等待

    LED_RED = !LED_RED;
    LED_GRE = !LED_GRE;//灯闪烁

    TBSR   = TX_buffer[0];
    TBSR1  = TX_buffer[1];
    TBSR2  = TX_buffer[2];
    TBSR3  = TX_buffer[3];
    TBSR4  = TX_buffer[4];
    TBSR5  = TX_buffer[5];
    TBSR6  = TX_buffer[6];
    TBSR7  = TX_buffer[7];
    TBSR8  = TX_buffer[8];
    TBSR9  = TX_buffer[9];
    TBSR10 = TX_buffer[10];
    TBSR11 = TX_buffer[11];
    TBSR12  = TX_buffer[12];

    CMR = 0x01;//置位发送请求
    EA  = 1;

}

void main(void)
{
//CPU初始化
    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
//CPU初始化

    CAN_init(  ); //SJA1000初始化,对 SJA1000寄存器的读写是采用外部寄存器寻址方式,所以不需要程序单独控制片选有效无效
    _nop_();
    _nop_();
    while(1)
    {
        _nop_();
        _nop_();
        Rxd_deal();//接收处理程序
	}

}


//SJA1000 的初始化
void CAN_init( void )
{
    uchar bdata Judge;
    uchar ACRR[4];
    uchar AMRR[4];
    ACRR[0] = 0x11;
    ACRR[1] = 0x22;
    ACRR[2] = 0x33;
    ACRR[3] = 0x44;//接收代码寄存器,节点1
    AMRR[0] = 0xff;
    AMRR[1] = 0xff;
    AMRR[2] = 0xff;
    AMRR[3] = 0xff;//接收屏蔽寄存器。 只接收主机发送的信息
    do
    {//  .0=1---reset MODRe,进入复位模式,以便设置相应的寄存器
     //防止未进入复位模式,重复写入
        MODR   = 0x09;
	Judge = MODR ;
    }
    while( !(Judge & 0x01) );
    CDR  = 0x88;// CDR.3=1--时钟关闭, .7=0---basic CAN, .7=1---Peli CAN
    BTR0 = 0x31;
    BTR1 = 0x1c;//总线波特率设定
    IER  = 0x01;// .0=1--接收中断使能;  .1=0--关闭发送中断使能
    OCR  = 0xaa;// 配置输出控制寄存器
    CMR  = 0x04;//释放接收缓冲器

    ACR  = ACRR[0];
    ACR1 = ACRR[1];
    ACR2 = ACRR[2];
    ACR3 = ACRR[3];//初始化标示码

    AMR  = AMRR[0];
    AMR1 = AMRR[1];
    AMR2 = AMRR[2];
    AMR3 = AMRR[3];//初始化掩码
    do
    {//确保退出复位模式
	MODR   = 0x08;
	Judge  = MODR ;
     }
    while( Judge & 0x01 );

}


void Delay(uchar delay_time)
{//延时程序
    while(delay_time--)
    {}
}


//数码管显示函数
 void led_seg7(uchar from,uchar number)  //from(1_4):数码管显示起始位置(从右到左),number:显示的数
{
    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(5);
        P0 = 0xff;
    }
    else
    {
        while(number)
	{
            digit = number%10 ;
	    number /= 10;
            P0 = led[digit] ;
	    Delay(5);
            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口
        }//while结束
    }//else结束
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -