sja1000.c

来自「测试CAN接口(sja1000) ,每接收到一帧数据,就 原样 回发 一帧!!!」· C语言 代码 · 共 339 行 · 第 1/2 页

C
339
字号

    if(overtime_value == 0)                  //上次发送 超时 , 发送错误
    {
        #ifdef    DEBUG        //调试用
            printf("!!!!!!!!The last CAN send OverTime ERR!!!!!!!!\n");
        #endif
        
        temp = read_sja_reg(REG_COMMAND);    //读出命令寄存器状态
        write_sja_reg(REG_COMMAND,(temp | Bit_AT));    //写命令寄存器,执行中止发送命令
        delay_ms(10);    //延时,使命令顺利执行
        
        error(CAN_SENDOVERTIME_ERR);    //转到错误处理,SJA1000 上次发送超时错误
    }
/*
    if((REG_STATUS & Bit_TBS) == 0)        //判断发送缓冲区是否锁定
    {
        #ifdef    DEBUG        //调试用
            printf("CAN Send Buffer locked!!!!!!!!\n");
        #endif
        
        return -1;                           //发送缓冲区锁定 , 返回
    }
*/
    //写 SJA1000内部发送缓冲区(13字节)
    write_sja_reg(REG_Information,EFF_data_inf);                   //扩展帧帧头
    write_sja_reg(REG_Buffer1,get_SwitchState());                  //柜号和板号(也即 拨码开关 的值)
    
    write_sja_reg(REG_Buffer2,CAN_SendBuffer.FrameType_append);    //通道号
    write_sja_reg(REG_Buffer3,CAN_SendBuffer.FrameType_append);    //帧类型附加
    write_sja_reg(REG_Buffer4,(CAN_SendBuffer.FrameType << 3));    //帧类型
    write_sja_reg(REG_Buffer5,CAN_SendBuffer.FrameSignal1);        //帧信号1
    write_sja_reg(REG_Buffer6,CAN_SendBuffer.FrameSignal2);        //帧信号2
    write_sja_reg(REG_Buffer7,CAN_SendBuffer.FrameSignal3);        //帧信号3
    write_sja_reg(REG_Buffer8,CAN_SendBuffer.FrameSignal4);        //帧信号4
    write_sja_reg(REG_Buffer9,CAN_SendBuffer.FrameSignal5);        //帧信号5
    write_sja_reg(REG_Buffer10,CAN_SendBuffer.FrameSignal6);       //帧信号6
    write_sja_reg(REG_Buffer11,CAN_SendBuffer.FrameSignal7);       //帧信号7
    write_sja_reg(REG_Buffer12,CAN_SendBuffer.FrameSignal8);       //帧信号8
    
    //执行 sja1000 发送命令                      
    temp = read_sja_reg(REG_COMMAND);//读出命令寄存器状态
    write_sja_reg(REG_COMMAND,(temp | Bit_TR));    //写令寄存器,执行发送命令

    return 0;
}

//***************************************************************************************************
//函数原型: INT8S can_data_receive(void)                                                            *
//参数说明: 无                                                                                      *
//返 回 值:  1 ; SJA1000 的 RXFIFO 有有效数据,并接收成功                                            *
//           0 ; SJA1000 的 RXFIFO 无有效数据                                                       *
//          -1 ; SJA1000 出错                                                                       *
//说    明: CAN控制器接收数据,仅限于接收数据,将SJA1000内部接收缓冲器的13个字节的数据,               *
//              存入微处理器保存接收数据的缓冲区(13个字节).                                         *
//***************************************************************************************************
INT8S can_data_receive(void)
{
    INT8U tempdata;
    INT8U symbol_datastate;    //sja1000 数据状态标志
    
    //8.28 注释
    tempdata = read_sja_reg(REG_STATUS);    //读出状态寄存器值
//    tempdata = read_sja_reg(REG_INTERRUPT);    //读出中断寄存器状态

    //状态判断
    
    //8.28 注释
//    if((tempdata & Bit_ES) != 0)                 //出错状态位 有效
//    {
//        #ifdef    DEBUG    //调试用
//            uart1_printf_ch("!!!!!!!!!!!!CAN Bit_ES in Error state!!!!!!!!!!!!\n\r");
//        #endif
//            
//        error(CAN_COUNTERS_ERR);    //转到错误处理,SJA1000 错误计数器 超限错误
//            
//        init_sja1000();                      //重新初始化SJA1000
//
//        return -1;    //SJA1000出错
//    }

    if((tempdata & Bit_RBS) == 0)                //判断 SJA1000 的 RXFIFO 是否有有效数据
    {
//        #ifdef    DEBUG        //调试用
//            uart1_printf_ch("------------ CAN RXFIFO NO DATA ------------\n\r");
//        #endif
        
        return 0;    //没有,返回0
    }
    
//    if((tempdata & Bit_RI) == 0)                //判断 SJA1000 的 RXFIFO 是否有有效数据
//    {
////        #ifdef    DEBUG        //调试用
////            uart1_printf_ch("------------ CAN RXFIFO NO DATA ------------\n\r");
////        #endif
//        
//        return 0;    //没有,返回0
//    }
    
    //判断是否有 溢出
    
        //8.28 注释
    if((tempdata & Bit_DOS) == Bit_DOS)    //判断 SJA1000 的 RXFIFO 是否溢出
//    if((tempdata & Bit_DOI) == Bit_DOI)    //判断 SJA1000 的 RXFIFO 是否溢出(中断方式)
    {
        #ifdef    DEBUG        //调试用
            uart1_printf_ch("!!!!!!!!!!!!CAN RXFIFO OVERFLOW_ERR!!!!!!!!!!!!\n\r");
        #endif
            
        error(CAN_OVERFLOW_ERR);    //转到错误处理,SJA1000接收 RXFIFO 溢出错误
 
        //执行 sja1000 清除数据溢出 命令
        tempdata = read_sja_reg(REG_COMMAND);              //读出命令寄存器状态
        write_sja_reg(REG_COMMAND,(tempdata | Bit_CDO));   //写命令寄存器,执行 清除数据溢出 命令
    }
    
    //接收数据判断(本帧数据本机是否应该接收)
    tempdata = read_sja_reg(REG_Information);
    if(tempdata == EFF_data_inf)                                                   //扩展帧帧头
    {
        tempdata = read_sja_reg(REG_Buffer1);
        if(tempdata == get_SwitchState())                                          //柜号和板号(也即 拨码开关 的值)
        {
            //读 SJA1000内部接收缓冲区(10字节)
            CAN_ReceiveBuffer.FrameType_append = read_sja_reg(REG_Buffer3);     //帧类型附加             
            CAN_ReceiveBuffer.FrameType = ((read_sja_reg(REG_Buffer4)) >> 3);   //帧类型
            CAN_ReceiveBuffer.FrameSignal1     = read_sja_reg(REG_Buffer5);     //帧信号1
            CAN_ReceiveBuffer.FrameSignal2     = read_sja_reg(REG_Buffer6);     //帧信号2
            CAN_ReceiveBuffer.FrameSignal3     = read_sja_reg(REG_Buffer7);     //帧信号3
            CAN_ReceiveBuffer.FrameSignal4     = read_sja_reg(REG_Buffer8);     //帧信号4
            CAN_ReceiveBuffer.FrameSignal5     = read_sja_reg(REG_Buffer9);     //帧信号5
            CAN_ReceiveBuffer.FrameSignal6     = read_sja_reg(REG_Buffer10);    //帧信号6
            CAN_ReceiveBuffer.FrameSignal7     = read_sja_reg(REG_Buffer11);    //帧信号7
            CAN_ReceiveBuffer.FrameSignal8     = read_sja_reg(REG_Buffer12);    //帧信号8
            
            symbol_datastate = 0;    //接收成功
        }
        else
        {
            #ifdef    DEBUG        //调试用
                uart1_printf_ch("!!!! CAN data NO send Me !!!!\n\r");
            #endif
            
            symbol_datastate = 1;    //数据不是发给本机的,不应该接收,也算没有接收到数据
        }
    }
    else
    {
        #ifdef    DEBUG        //调试用
            uart1_printf_ch("!!!! NO Extended data frame format !!!!\n\r");
        #endif
                
        symbol_datastate = 1;    //非扩展帧的数据帧,也不应该接收,也算没有接收到数据
    }

    //执行 sja1000 释放接收缓冲器命令
    tempdata = read_sja_reg(REG_COMMAND);              //读出命令寄存器状态
    write_sja_reg(REG_COMMAND,(tempdata | Bit_RRB));   //写令寄存器,执行释放接收缓冲器命令

    //返回判断
    if(symbol_datastate == 0)    //接收到发给本机的有效数据
    {
        return 1;    //  有有效数据
    }
    else                        //数据不是发给本机
    {
        return 0;    //没有有效数据
    }
}

⌨️ 快捷键说明

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