新聞中心

        SJA1000+C51

        作者: 時間:2016-11-13 來源:網絡 收藏
        #include "CANBUS.H"

        //-------------------------------------define variable------------------------------------
        unsigned char receive_counter = 0;
        unsigned char alc = 1;
        unsigned char ecc = 1;

        本文引用地址:http://www.104case.com/article/201611/316526.htm

        /************************************************************************
        *函數原型: bit CAN_CREATE_COMMUNATION(void)
        *參數說明: 無
        *返回值:*
        * 0 ; 表示SJA1000接口正常
        * 1 ; 表示SJA1000與處理器接口不正常
        *
        *說明:該函數用于檢測CAN控制器的接口是否正常
        ************************************************************************/
        bit CAN_CREATE_COMMUNATION(void)
        {
        unsigned char temp_data;
        bit Flag;
        REG_TEST = 0xAA; //寫入測試值
        temp_data = REG_TEST;
        if(temp_data == 0xaa)
        {
        Flag=0; //讀測試正確
        }
        else
        {
        Flag=1;
        }
        if(!Flag)
        {
        REG_TEST = 0x55; //寫入測試值
        temp_data = REG_TEST;
        if(temp_data == 0x55)
        {
        Flag=0; //讀測試正確
        REG_TEST = 0x00;
        }
        else
        {
        Flag=1;
        }
        }
        return (Flag);
        }
        /************************************************************************
        *函數原型: bit CAN_ENTRY_RETMODEL(void) *
        *參數說明: 無 *
        *返回值: *
        * 0 ; 表示成功進入復位工作模式 *
        * 1 ; 表示不能進入復位工作模式 *
        * *
        *說明: CAN控制器進入復位工作模式 *
        ************************************************************************/
        bit CAN_ENTRY_RETMODEL(void)
        {
        bit flag;
        unsigned char ErrorCount=20;
        unsigned char temp_data = REG_MODE;
        while(ErrorCount --)
        {
        REG_MODE = temp_data|RM_MODE;
        temp_data = REG_MODE;
        if( (temp_data & RM_MODE) != 0)
        {
        flag=0;
        break;
        }
        else
        {
        flag=1;
        }
        }
        return(flag);
        }

        /************************************************************************
        *函數原型: bitCAN_QUIT_RETMODEL(void)
        *參數說明: 無
        *返回值:
        * 0 ; 表示成功退出復位工作模式
        * 1 ; 表示不能退出復位工作模式
        *說明: CAN控制器退出復位工作模式
        ***********************************************************************/
        bit CAN_QUIT_RETMODEL(void)
        {
        bit flag;
        unsigned char ErrorCount=20;
        unsigned char temp_data = REG_MODE;
        while(ErrorCount --)
        {
        REG_MODE = temp_data&0xfe;
        temp_data = REG_MODE;
        if((temp_data&0x01) == 0)
        {
        flag=0;
        break;
        }
        else
        {
        flag=1;
        }
        }
        return(flag);
        }

        /*********************************************************************************
        **函數原型: char SJASetBandRateStandard(unsigned char BandRateSize)
        **參數說明: BandRateSize 標準常用波特率(Kbps)
        ** 0 5
        ** 1 10
        ** 2 20
        ** 3 40
        ** 4 50
        ** 5 80
        ** 6 100
        ** 7 125
        ** 8 200
        ** 9 250
        ** 10 400
        ** 11 500
        ** 12 666
        ** 13 800
        ** 14 1000
        **返回值:
        ** 0 ; 設置總線定時器成功
        ** SJA_SETBTR_ERR ; 設置總線定時器錯
        ** SJA_NOBTRSIZE ;波特率不能設為此值
        **
        **說明: 該函數用于設定在系統晶體為16MHZ時,常用的標準波特率的值。
        ** 參數BandRateSize只能為0~14,其它的值會返回SJA_NOBTRSIZE錯誤
        ** 本函數只能用于復位模式
        ***************************************************************************************/
        unsigned char code SJA_BTR_CODETAB[]={
        0xbf,0xff, //;5KBPS的預設值
        0x67,0x2f, //;10KBPS的預設值
        0x53,0x2F, //;20KBPS的預設值
        0x87,0xFF, //;40KBPS的預設值
        0x47,0x2F, //;50KBPS的預設值
        0x83,0xFF, //;80KBPS的預設值
        0x43,0x2f, //;100KBPS的預設值
        0x03,0x1c, //;125KBPS的預設值
        0x81,0xfa, //;200KBPS的預設值
        0x01,0x1c, //;250KBPS的預設值
        0x80,0xfa, //;400KBPS的預設值
        0x00,0x1c, //;500KBPS的預設值
        0x80,0xb6, //;666KBPS的預設值
        0x00,0x16, //;800KBPS的預設值
        0x00,0x14//;1000KBPS的預設值
        };
        bit CAN_SET_BANDRATE(unsigned char CAN_ByteRate)
        {
        bit ErrorFlag =1;
        unsigned char temp_data;
        unsigned char ErrorCount = 0x20; //32次報錯
        if(CAN_ByteRate>14)
        {
        ErrorFlag =1;
        }
        else{
        while(--ErrorCount)
        {
        REG_BTR0 = SJA_BTR_CODETAB[CAN_ByteRate*2];
        REG_BTR1 = SJA_BTR_CODETAB[CAN_ByteRate*2+1];
        temp_data = REG_BTR0;
        if(temp_data != SJA_BTR_CODETAB[CAN_ByteRate*2])
        {
        continue;
        }
        temp_data = REG_BTR1;
        if(temp_data != SJA_BTR_CODETAB[CAN_ByteRate*2+1])
        {
        continue;
        }
        ErrorFlag=0;
        break;
        }//while結束

        }
        return ErrorFlag ;
        }

        /*************************************************************************
        *函數原型:CAN_SET_OBJECT
        *參數說明:
        * CAN_ACR0-3:存放驗收代碼寄存器(ACR)的參數設置
        * CAN_AMR0-3:存放接收屏蔽寄存器(AMR)的參數設置
        *返回值:
        * 0 ;通信對象設置成功
        * 1 ;通信對象設置失敗
        *說明:設置CAN節點的通訊對象,允許接收的報文ID號
        * 允許接收的報文,是由AMR和ACR共同決定的.
        * 滿足以下條件的ID號的報文才可以被接收
        *[(ID.29-ID.0)≡(AC.29-AC.0)]||(AM.29-AM.0)≡11111111
        * 該子程序只能用于復位模式 *
        *************************************************************************/
        bit CAN_SET_OBJECT(unsigned char CAN_ACR0,unsigned char CAN_ACR1,
        unsigned char CAN_ACR2,unsigned char CAN_ACR3,
        unsigned char CAN_AMR0,unsigned char CAN_AMR1,
        unsigned char CAN_AMR2,unsigned char CAN_AMR3)
        {
        bit ErrorFlag =1;
        unsigned char temp_data;
        unsigned char ErrorCount = 0x20; //32次報錯
        while(ErrorCount--)
        {
        REG_ACR0 = CAN_ACR0;
        REG_ACR1 = CAN_ACR1;
        REG_ACR2 = CAN_ACR2;
        REG_ACR3 = CAN_ACR3;
        REG_AMR0 = CAN_AMR0;
        REG_AMR1 = CAN_AMR1;
        REG_AMR2 = CAN_AMR2;
        REG_AMR3 = CAN_AMR3;

        temp_data = REG_ACR0;
        if(temp_data!= CAN_ACR0) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_ACR1;
        if(temp_data!= CAN_ACR1) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_ACR2;
        if(temp_data != CAN_ACR2) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_ACR3;
        if(temp_data != CAN_ACR3) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_AMR0;
        if(temp_data != CAN_AMR0) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_AMR1;
        if(temp_data != CAN_AMR1) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_AMR2;
        if(temp_data != CAN_AMR2) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_AMR3;
        if(temp_data != CAN_AMR3) //校驗寫入值
        {
        continue;
        }
        ErrorFlag =0;
        break;
        }
        return ErrorFlag;
        }
        /************************************************************************
        *函數原型: bit CAN_SET_OUTCLK(unsigned char Out_Control,unsigned char Clock_Out);
        *參數說明:
        * Out_Control:存放輸出控制寄存器 (OCR)的參數設置
        * Clock_Out:存放時鐘分頻寄存器 (CDR) 的參數設置
        *
        *返回值:
        * 0 ;設置成功
        * 1 ;設置失敗
        *
        *說明:設置SJA1000的輸出模式和時鐘分頻 。該子程序只能用于復位模式 *
        ************************************************************************/
        bit CAN_SET_OUTCLK (unsigned char Out_Control,unsigned char Clock_Out)
        {
        bit ErrorFlag =1;
        unsigned char temp_data;
        unsigned char ErrorCount = 0x20; //32次報錯
        while(ErrorCount--)
        {
        REG_OCR = Out_Control;
        REG_CDR = Clock_Out;
        temp_data = REG_OCR;
        if(temp_data != Out_Control) //校驗寫入值
        {
        continue;
        }
        temp_data = REG_CDR;
        if(temp_data != Clock_Out) //校驗寫入值
        {
        continue;
        }
        ErrorFlag =0;
        break;
        }
        return ErrorFlag;
        }
        /************************************************************************
        *函數原型: bitSJA_Init(void)
        *參數說明: 無
        *返回值:
        * 0 ; 表示初始化CAN成功
        * 1 ; 表示不能初始化CAN
        * 不同的要求需要修改
        *說明: 初始化CAN控制器波特率 分頻和輸出方式 ACK AMR等
        ***********************************************************************/
        void SJA_Init(void)
        {
        unsigned char temp_data;
        bit flag;
        delay(125);
        SJARst = 0;
        delay(125);
        SJARst = 1;
        delay(125);

        //write 0xaa 0x55 to REG_TEST
        flag = CAN_CREATE_COMMUNATION();
        if(flag)
        {
        ERR_flag = hard_ERR;
        goto EXIT;
        }

        flag = CAN_ENTRY_RETMODEL();
        if(flag) //復位模式中
        {
        ERR_flag = Init_ERR;
        goto EXIT;
        }

        flag = CAN_SET_BANDRATE(ByteRate_500k);
        if(flag)
        {
        ERR_flag = Init_ERR;
        goto EXIT;
        }
        flag = CAN_SET_OUTCLK(0x1a,0xc8);
        if(flag) //輸出正常模式 推免方式 TX0
        { //CDR.7=1 pelican模式 CDR.6=1只有RX0被激活 關clockout
        ERR_flag = Init_ERR;
        goto EXIT;
        }

        REG_RBSA = 0x00;

        //ACR and AMR
        flag = CAN_SET_OBJECT(0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00);
        if(flag)
        {
        ERR_flag = Init_ERR;
        goto EXIT;
        }

        REG_IR_ABLE = 0x89; //中斷使能


        //REG_MODE = 0x0c; //mod.2=1進入自接收模式 mod.3選擇單個驗收濾波器(32bit)
        REG_MODE = AFM_MODE;
        REG_MODE = AFM_MODE; //mod.2=0正常模式 mod.3選擇單個驗收濾波器(32bit)
        flag = CAN_QUIT_RETMODEL();
        if(flag)
        {
        ERR_flag = Init_ERR;
        goto EXIT;
        }

        delay(100);
        CAN_node_ID();
        Rx_node_Num();
        EXIT: return ;
        }

        /************************************************************************
        *函數原型: bit Rx_node_Num( )
        *參數說明: no
        *返回值:
        * 此函數可以根據用戶需在更改和刪除
        *說明:配置CAN控制器接收緩沖器情況
        ************************************************************************/
        void Rx_node_Num()
        { // 如果RX信息計數器為空則LED0亮
        unsigned char temp_Num;
        temp_Num = REG_Receive_Counter;
        if(temp_Num == 0)
        {
        LED0 = OFF;
        }
        else LED0 = ON;
        return ;
        }

        /************************************************************************
        *函數原型: can_test( )
        *參數說明: no
        *返回值:
        * 此函數可以根據用戶需在更改和刪除
        *說明:只用于硬件測試,全部CAN配置在內,只用此函數只可測試節點情況
        ************************************************************************/
        void can_test(void)
        {
        unsigned char temp_data;
        temp_data = REG_SR;
        if((temp_data & DOS_SR) == DOS_SR) //數據溢出狀態
        {
        REG_CMD |= 0x0c; //clear over status and realve RX_FIFO
        REG_CMD |= 0x0c;
        }
        if((temp_data & TBS_SR) == TBS_SR) //發送緩沖區狀態 1釋放
        {
        REG_RxBuffer0 = 0x88; //EFF 標準幀SFF,長度為8
        // REG_RxBuffer1=0x00;
        // REG_RxBuffer2=0x00;
        // REG_RxBuffer3=0x00;
        // REG_RxBuffer4=0x08; //ID.4-ID.0 and bit2~0 no use

        REG_DataBuffer1 = x;
        REG_DataBuffer2 = i;
        REG_DataBuffer3 = a;
        REG_DataBuffer4 = o;
        REG_DataBuffer5 = z;
        REG_DataBuffer6 = h;
        REG_DataBuffer7 = a;
        REG_DataBuffer8 = o;
        }
        CAN_cmd(TR_CMD); //TX request 請求
        temp_data = REG_SR;
        temp_data &= TBS_SR; //TX buffer status 發送狀態
        while(temp_data == TBS_SR) //檢查是否發送完成
        {
        ecc = REG_ECC;
        temp_data = REG_SR;
        temp_data &= 0X20;
        }
        }
        /************************************************************************
        *函數原型: Rx_Data( )
        *參數說明: no
        *返回值:
        * 設置不同的緩沖區需修改不同的接收緩沖變量
        *說明: 定義了Rx_buffer緩沖區
        ************************************************************************/
        void Rx_Data()
        {
        unsigned char temp_data;
        temp_data = REG_SR;
        F0 = 1;
        if((temp_data & RBS_SR) == 0) //RBS Rx buffer status 1-RXFIFO have message
        {
        goto EXIT1;
        }
        Rx_buffer.dlen = REG_RxBuffer0; //node message
        temp_data = Rx_buffer.dlen;

        Rx_buffer.did1 = REG_RxBuffer1; //node message ID
        Rx_buffer.did2 = REG_RxBuffer2;
        Rx_buffer.did3 = REG_RxBuffer3;
        Rx_buffer.did4 = REG_RxBuffer4;

        temp_data = Rx_buffer.dlen;
        if( (temp_data & 0x40) == 0x00)
        {
        Rx_buffer.ddata[0] = REG_DataBuffer1; //message data
        Rx_buffer.ddata[1] = REG_DataBuffer2;
        Rx_buffer.ddata[2] = REG_DataBuffer3;
        Rx_buffer.ddata[3] = REG_DataBuffer4;
        Rx_buffer.ddata[4] = REG_DataBuffer5;
        Rx_buffer.ddata[5] = REG_DataBuffer6;
        Rx_buffer.ddata[6] = REG_DataBuffer7;
        Rx_buffer.ddata[7] = REG_DataBuffer8;
        F0 = 0;
        }
        //F0 = 0; //realve Rx buffer succefe
        CAN_cmd(RRB_CMD); //send realve commd to SJA1000
        EXIT1: return;
        }
        /************************************************************************
        *函數原型: bit CAN_node_ID( )
        *參數說明: no
        *返回值:
        * 此函數可以根據用戶需在更改
        *說明:配置CAN控制器識別符ID,為了便于測試配置REG_CAN_TXBUF3為開關ID
        ************************************************************************/
        void CAN_node_ID(void)
        {
        unsigned char idata temp_data;
        P1 = 0xf8;
        temp_data = P1;
        temp_data = (temp_data >> 3);
        if( (temp_data & 0x1F) > 0x09 )
        {
        temp_data = (temp_data & 0x1F) + 0x37;
        }
        else temp_data = (temp_data & 0x0F) + 0x30;
        REG_TxBuffer0 = 0x80; //frame is EFF data leng is 0
        REG_TxBuffer1 = 0x00;
        REG_TxBuffer2 = 0x00;
        REG_TxBuffer3 = temp_data;
        REG_TxBuffer4 = 0x00; //ID.4-ID.0 and bit2~0 no use
        }
        /************************************************************************
        *函數原型: Tx_data( )
        *參數說明: no
        *返回值:
        * 此函數可以根據用戶需在更改
        *說明:由全局變量Tx_buffer作緩沖,接收CAN讀出的信息.
        ************************************************************************/
        void Tx_data()
        {
        unsigned char temp_data;
        temp_data = REG_SR;
        F0 = 1;
        if( (temp_data & TCS_SR) == 0)
        {
        ERR_flag = no_TCS;
        goto EXIT2;
        }
        if( (temp_data & TBS_SR)== TBS_SR ) //Tx buffer is empty?
        {
        REG_TxBuffer0 |= (Tx_buffer.dlen & 0x0F); //EFF 標準幀SFF,長度為8

        REG_DataBuffer1 = Tx_buffer.ddata[0];
        REG_DataBuffer2 = Tx_buffer.ddata[1];
        REG_DataBuffer3 = Tx_buffer.ddata[2];
        REG_DataBuffer4 = Tx_buffer.ddata[3];
        REG_DataBuffer5 = Tx_buffer.ddata[4];
        REG_DataBuffer6 = Tx_buffer.ddata[5];
        REG_DataBuffer7 = Tx_buffer.ddata[6];
        REG_DataBuffer8 = Tx_buffer.ddata[7];
        CAN_cmd(TR_CMD); //TR=1
        F0 = 0;
        }
        else ERR_flag = no_TBS;
        EXIT2: return ;
        }

        /************************************************************************
        *函數原型: bit CAN_cmd( )
        *參數說明: no
        *返回值:
        * 此函數可以根據用戶需在更改和刪除
        *說明: 寫命令操作
        ************************************************************************/
        void CAN_cmd(unsigned char cmd)
        {
        REG_CMD = cmd;
        }

        /************************************************************************
        *函數原型: SJA_ERR( )
        *參數說明: no
        *返回值:
        * 此函數可以根據用戶需在更改和刪除
        *說明:仿真時可以知道出象牙在哪里,也呆增加其他顯示作錯誤提示
        ************************************************************************/
        void SJA_ERR(void)
        {
        unsigned char bdata temp_data;
        temp_data = ERR_flag;
        if( (ERR_flag & hard_ERR) == hard_ERR) //硬件錯誤進入死循環
        {
        while(1);
        }
        ERR_flag = temp_data;
        while( (ERR_flag & Init_ERR) == Init_ERR ) //初始化錯誤一直等到初始化完功
        {
        SJA_Init();
        ERR_flag = temp_data;
        }
        }



        關鍵詞: SJA1000C5

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 伊春市| 辽中县| 宽甸| 鄄城县| 曲松县| 兴城市| 阿克| 平顶山市| 永昌县| 鸡西市| 罗甸县| 贵定县| 格尔木市| 宣化县| 博野县| 化德县| 库伦旗| 喀喇沁旗| 稷山县| 凌源市| 察雅县| 治县。| 义马市| 牙克石市| SHOW| 屯昌县| 鹤壁市| 门头沟区| 文昌市| 抚松县| 天水市| 邹平县| 定结县| 方正县| 安阳县| 昭平县| 曲周县| 天镇县| 南陵县| 犍为县| 乡城县|