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

📄 can.c

📁 51单片机基于CAN总线通信程序
💻 C
字号:

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//描述: sja1000can总线处理函数
//      CAN主要参数:       PeliCAN模式,扩展帧EFF模式                          &
//      29位标示码结构:                                                       &
//      本节点的地址: 0x11,0x22,0x33,0x00;可以接收全部节点的数据               &
//      目的节点地址:0x01,0x02,0x03,0x00;可以被能接收全部节点数据的节点接收   &

//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&

#include <reg52.h>
#include <intrins.h>
#include <inc/can.h>
#include "inc/timer_pwm.h"
#include "inc/CPUIO_DEF.H"
#include "inc/EXT_PUBLIC_VARIABLE.H"
#include "inc/candul.H"

/**************************************************************************************
;;函数原型: void CAN_RXD( void ) interrupt 0
;;函数功能: CAN中断处理函数,包括接收中断和发送中断
;;函数输入: 无
;;函数输出: 无
;;函数返回值: 无
***************************************************************************************/
void CAN_RXD( void ) interrupt 0 using 3
{
    uchar data Judge,tmpbuf[5];

  //  EA = 0;//关CPU中断

    Judge = IR;
    if( Judge & 0x01)
    {//IR.0 = 1 接收中断
        tmpbuf[0] =  RBSR0;                     //标示
        tmpbuf[1] =  RBSR1;                     //id  --地址

        if( ((tmpbuf[0]&0xc0) == 0x80)&&(tmpbuf[1] == ADDRESS) ) 
        {  //是扩展帧和数据帧并且是本机地址
             if( CanRx.farmeSta ==NULL )
             {
                CanRx.farmeSta = FULL;
                CanRx.farmeType = RBSR3;                     //命令类型           
                CanRx.farmeSubType = RBSR4;                  //子命令
                CanRx.farmeLong = tmpbuf[0]&0x0f;            //数据长度

                CanRx.farmeData[0]  = RBSR5;//数据
                CanRx.farmeData[1]  = RBSR6;//数据
                CanRx.farmeData[2]  = RBSR7;//数据
                CanRx.farmeData[3]  = RBSR8;//数据
                CanRx.farmeData[4]  = RBSR9;//数据
                CanRx.farmeData[5]  = RBSR10;//数据
                CanRx.farmeData[6]  = RBSR11;//数据
                CanRx.farmeData[7]  = RBSR12;//数据
                CanRx.farmeData[8]  = RBSR2;    //帧计数
 
             }
        }
        CMR = 0X04;     //释放接收缓冲器      
        Judge = ECC;    //释放错误代码捕捉寄存器
    }
    else if(Judge & 0x02)
    { //IR.1 = 1 发送中断

    }
    else if(Judge & 0x04)
    { //IR.2 = 1 错误报警中断
    
    }
    else if(Judge & 0x08)
    {//IR.3 = 1 数据溢出中断
    CMR = 0X10;  //清楚数据溢出位
    }
    else if(Judge & 0x10)
    {//IR.4 = 1 唤醒中断
    }
    else if(Judge & 0x20)
    {//IR.5 = 1 错误消极中断
    }
    else if(Judge & 0x40)
    {//IR.6 = 1 仲裁丢失中断
       Judge = ALC;//释放仲裁随时捕捉寄存器
    }
    else
    {//IR.7 = 1 总线错误中断
    }
    IER = 0x01;// .0=1--接收中断使能;
  //  EA = 1;//打开CPU中断
}


/**************************************************************************************
;;函数原型: void Rxd_deal(void)
;;函数功能: CAN接收处理函数
;;函数输入: 无
;;函数输出: 无
;;函数返回值: 无
;;主循环调用
***************************************************************************************/

void Rxd_deal(void)
{//////// 接收处理程序//////////////
	uchar ucTxdBuf[8];
    if( CanRx.farmeSta == FULL )
    {      
        CanRx.farmeSta = NULL;
        if( (CanRx.farmeType == MS_REST_STOP_CAR)|| (CanRx.farmeType == MS_STOP_CAR50_SLOW)||(CanRx.farmeType == MS_STOP_CAR100_SLOW)||
        (CanRx.farmeType == MS_REST_STOP_CAR)||(CanRx.farmeType == MS_STOP_CAR50_FAST)||(CanRx.farmeType == MS_STOP_CAR100_FAST)||
        (CanRx.farmeType == MS_ALLOW_IN_UPDATE_STA))
        {
            //数据接收正确应答 
            ucTxdBuf[0] = 0x00;//000000回复相应结果
            CAN_TXD( MADDRESS,SM_RECEV_OK,UN_ACK,1,ucTxdBuf );
            StopCar.sta = START;
            StopCar.cmd = CanRx.farmeType;
        }
        else
        {
            switch( CanRx.farmeType )
            {
                case MS_SYS_SEELP://系统睡眠
                break;
                case MS_ALLOW_IN_UPDATE_STA://允许进入升级状态
                break;
                case MS_UPDATA_DATAS://升级数据帧
                break;
                case MS_VERIFY_DATAS://校验数据
                break;
    
            }
        }
    }
}//////// 接收处理程序//////////////
/**************************************************************************************
;;函数原型: void CAN_init( void )
;;函数功能: CAN初始化函数can2.0b
;;函数输入: 无
;;函数输出: 无
;;函数返回值: 无
***************************************************************************************/
void CAN_init( void )
{//SJA1000 的初始化
    uchar bdata Judge;

    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 ,.2-.0 为000,2分频时钟频率为fosc/2

//10k   
//  BTR0 = 0x1d;        //波特率为fosc=12m时brp.5-brp.0 = 011101,波特率为1m,tscl = 5us,tsjw=2*3=0us
//  BTR1 = 0xdc;		  //10总线波特率设定 tseg1=1011(11),tseg2=100(4)位速率=tscl*(tseg1+tseg2+3)=5*20=100us(10k)
    
    // 100K
    BTR0 = 0x05;        //波特率为fosc=12m时brp.5-brp.0 = 000101,波特率为1m,tscl = 1us,tsjw=2*3=0us
    BTR1 = 0x25;		//高速BTR1.7 =SAM=0;总线波特率设定 tseg1=0110(6),tseg2=011(3)位速率=tscl*(tseg1+tseg2+3)=1*10=10us(100k)
// 500k   
//   BTR0 = 0x00;      //波特率为fosc=12m时brp.5-brp.0 = 000001,tscl = 1/6us,tsjw=2*3=0us
//   BTR1 = 0x36;		//10总线波特率设定 tseg1=0101(6),tseg2=010(3)位速率=tscl*(tseg1+tseg2+1)=1*10=10us(500k)

    
    IER  = 0x01;		//.0=1--接收中断使能;  .1=0--关闭发送中断使能
    OCR  = 0xaa;		// 配置输出控制寄存器
    CMR  = 0x04;		//释放接收缓冲器

    ACR  = ADDRESS;     //本节点地址0x04
    ACR1 = 0;
    ACR2 = 0;
    ACR3 = 0;		//初始化标示码

    AMR  = 0;
    AMR1 = 0xff;
    AMR2 = 0xff;
    AMR3 = 0xff;		//初始化掩码
    do
    {//确保退出复位模式
	MODR   = 0x08;		//单滤波
	Judge  = MODR ;
     }
    while( Judge & 0x01 );
}

/**************************************************************************************
;;函数原型: void CAN_TXD( uchar ucAddress,uchar ucCmd,uchar ucSubCmd,uchar ucLong,uchar *PData )
;;函数功能: CAN发送函数
;;函数输入: ucAddress地址,,ucCmd命令,ucSubCmd子命令,ucLong长度,*PData数据指针
;;函数输出: 无
;;函数返回值: 无
***************************************************************************************/
void CAN_TXD( uchar ucAddress,uchar ucCmd,uchar ucSubCmd,uchar ucLong,uchar *PData )
{
    uchar data Judge;
    //初始化数据信息
    //   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;//灯闪烁
    TBSR0  = 0x80|(ucLong&0x0f); //.7=0扩展帧;.6=0数据帧; .3.2.1.0=数据长度8
    TBSR1  = ucAddress;         //目的节点地址
    TBSR2  = 0;                //
    TBSR3  = ucCmd;             //
    TBSR4  = ucSubCmd;          //

    TBSR5  = *PData++;
    TBSR6  = *PData++;
    TBSR7  = *PData++;
    TBSR8  = *PData++;
    TBSR9  = *PData++;
    TBSR10 = *PData++;
    TBSR11 = *PData++;
    TBSR12 = *PData++;
    
    CMR = 0x01;//置位发送请求
 //   EA  = 1;
}

⌨️ 快捷键说明

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