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

📄 can.c

📁 一整套电梯控制器源程序
💻 C
字号:
#include "public.h"

void can_init(void)
{
    P2_7=0;
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();
    _nop_();

    P2_7=1;

    do{XBYTE[((P2&0xe0)|0x0F)*256]=0x09;}							  //进入复位状态,为单滤波方式
    while(XBYTE[((P2&0xe0)|0x0F)*256]&0x01==0);                       //复位信号的查询和置位
    //定义时钟分配器,CLKOUT没有使用,则clock off为1,RXINTEN为0,CBP置位,CAN 模式为Pelican,为1;
    XBYTE[((P2&0xe0)|0x0F)*256+31]=0xc8;
    XBYTE[((P2&0xe0)|0x0F)*256+3]=0;                                //禁止SJA1000所有的中断
    XBYTE[((P2&0xe0)|0x0F)*256+16]=0x2c;                            //代码为:00101100,101:内选标识符+1+内选标识符
    XBYTE[((P2&0xe0)|0x0F)*256+17]=0xa0;
    XBYTE[((P2&0xe0)|0x0F)*256+18]=0x00;
    XBYTE[((P2&0xe0)|0x0F)*256+19]=0x00;
    XBYTE[((P2&0xe0)|0x0F)*256+20]=0x00;
    XBYTE[((P2&0xe0)|0x0F)*256+21]=0x00;
    XBYTE[((P2&0xe0)|0x0F)*256+22]=0xff;
    XBYTE[((P2&0xe0)|0x0F)*256+23]=0xff;
    // 定义总线定时器:波特率为:125kbit,采样点为:87。5%
    XBYTE[((P2&0xe0)|0x0F)*256+6]=0x02;                              //此时为12兆晶振。
    XBYTE[((P2&0xe0)|0x0F)*256+7]=0x1c;
    //当为8兆晶振时,应该为:XBYTE[0x06]=0x01;XBYTE[0x07]=0x1c;
    //定义CAN输出:TX1悬空,TX0为推拉方式,输出为Normal方式
    //当为16兆晶振时,应该为:XBYTE[0x06]=0x03;XBYTE[0x07]=0x1c;
    
    
    //定义CAN输出:TX1悬空,TX0为推拉方式,输出为Normal方式
    XBYTE[((P2&0xe0)|0x0F)*256+8]=0x1a;
    //定义RX buffer start address RBSA(由于每个数据帧为11个字节)
    
    do                                                    //置位复位状态
    {XBYTE[((P2&0xe0)|0x0F)*256]=0x08;}                                  //运行状态,单滤波
    while((XBYTE[((P2&0xe0)|0x0F)*256]&0x01)!=0x00);

}


void senddata(void)
{   
    uchar i=0,j=0;
    uchar cTemp=0;
	 uchar cTempOrg=0;
	 uchar cTemp5State=0;
    uchar cIdx=0;

    //5状态发送条件: 1.变化时发送; 2.500ms定时发送
    if(time_5sta_flg==1){              // 100ms计时到                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      
        if((sum_state1==0)||(sum_state1>=TIMER_FILTER_NUM)){    //司机上状态
			if(temp_state1==1){
				cTemp5State=0;
			}else if(temp_state1==0){
				cTemp5State=1;
			}
            if(m_state1!=temp_state1){    //变化
//第二块内选板不发送5状态  2005.03.03
//                dispose_sendata(49,cTemp5State);
                _nop_();
                _nop_();
            }
            m_state1=cTemp5State;
        }else{
            //不做处理
        }
        if((sum_state2==0)||(sum_state2>=TIMER_FILTER_NUM)){    //司机下状态
			if(temp_state2==1){
				cTemp5State=0;
			}else if(temp_state2==0){
				cTemp5State=1;
			}
            if(m_state2!=temp_state2){    //变化
//第二块内选板不发送5状态  2005.03.03
//                dispose_sendata(50,cTemp5State);
                _nop_();
                _nop_();
            }
            m_state2=cTemp5State;
        }else{
            //不做处理
        }
        if((sum_state3==0)||(sum_state3>=TIMER_FILTER_NUM)){    //司机状态 
			if(temp_state3==1){
				cTemp5State=0;
			}else if(temp_state3==0){
				cTemp5State=1;
			}
            if(m_state3!=temp_state3){    //变化
//第二块内选板不发送5状态  2005.03.03
//                dispose_sendata(51,cTemp5State);
                _nop_();
                _nop_();
            }
            m_state3=cTemp5State;
        }else{
            //不做处理
        }
        if((sum_state4==0)||(sum_state4>=TIMER_FILTER_NUM)){    //直驶状态 
			if(temp_state4==1){
				cTemp5State=0;
			}else if(temp_state4==0){
				cTemp5State=1;
			}
            if(m_state4!=temp_state4){    //变化
//第二块内选板不发送5状态  2005.03.03
//                dispose_sendata(52,cTemp5State);
                _nop_();
                _nop_();
            }
            m_state4=cTemp5State;
        }else{
            //不做处理
        }
        if((sum_state5==0)||(sum_state5>=TIMER_FILTER_NUM)){    //保留状态
			if(temp_state5==1){
				cTemp5State=0;
			}else if(temp_state5==0){
				cTemp5State=1;
			}
            if(m_state5!=temp_state5){    //变化
//第二块内选板不发送5状态  2005.03.03
//              dispose_sendata(53,cTemp5State);
                _nop_();
                _nop_();
            }
            m_state5=cTemp5State;
        }else{
            //不做处理
        }
        sum_state1=0;
        sum_state2=0;
        sum_state3=0;
        sum_state4=0;
        sum_state5=0;
      

        time_5sta_flg=0;
        time_5sta_count=TIMER_FILTER_NUM;
    }

	 if(time_insel_flg==1){
        //内选数据发送(注意点:由于硬件的限制,内选按钮数组只能使用前3个字节)
		keyboardorg[0]=keyboard[0];
		keyboardorg[1]=keyboard[1];
		keyboardorg[2]=keyboard[2];
        keyboard[0]=array0[0]|array1[0]|array2[0]|array3[0]|array4[0];
        keyboard[1]=array0[1]|array1[1]|array2[1]|array3[1]|array4[1];
        keyboard[2]=array0[2]|array1[2]|array2[2]|array3[2]|array4[2];

        //(1.此处简化逻辑,提高效率 2.对应24-48层)
        //2004.01.28 LHM 
        for(i=0; i<3; i++){
            for(j=0; j<8; j++){
			    cTempOrg = (keyboardorg[i]>>j)&0x01;
                cTemp = (keyboard[i]>>j)&0x01;
                if((cTempOrg==1)&&(cTemp==0)){   //按钮被按下
                    cIdx=24+i*8+j;		//based 0
					if((cIdx>=24)&&(cIdx<=(m_cMaxFloorCnt-1)))
	                    SendInSelData(cIdx);
                }
            }
        }
		  time_insel_flg=0;
		  time_insel_count=TIMER_100ms;
	 }

    //500ms发送5状态,读最大楼层数
    if(time_500ms_flg==1){
//第二块内选板不发送5状态  2005.03.03
/*
        dispose_sendata(49,m_state1);   //司机上
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        dispose_sendata(50,m_state2);   //司机下
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        dispose_sendata(51,m_state3);   //司机
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        dispose_sendata(52,m_state4);   //直驶
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        dispose_sendata(53,m_state5);   //保留
        _nop_();
        _nop_();
        _nop_();
        _nop_();
*/
        if((m_cMaxFloorCnt<2)||(m_cMaxFloorCnt>48)){
            dispose_sendata(57,1);   //读楼层数
            _nop_();
            _nop_();
            _nop_();
            _nop_();
        }
        time_500ms_flg=0;
        time_500ms_count=TIMER_500ms;
    }

}

void dispose_sendata(uchar data1,uchar data2)                                            //发送数据,每次发送两个数据
{     do {}
      while((XBYTE[((P2&0xe0)|0x0F)*256+2]&0x04)!=0x04);   //判断发送缓冲区是否释放   
      XBYTE[((P2&0xe0)|0x0F)*256+16]=0x02;                 //数据长度为2;
      XBYTE[((P2&0xe0)|0x0F)*256+17]=0xac;                 //发送标识符为:10101+1+00101:控制器标识符+内选标识符
      XBYTE[((P2&0xe0)|0x0F)*256+18]=0xa0;
      XBYTE[((P2&0xe0)|0x0F)*256+19]=data1;
      XBYTE[((P2&0xe0)|0x0F)*256+20]=data2;
      XBYTE[((P2&0xe0)|0x0F)*256+1]=0x01;
}

//仅对应24层以上,cIdx from 24 to 47
void SendInSelData(uchar cIdx)
{
    uchar cLamp=0;
    uchar cGrpIdx, cSurplus;
    cGrpIdx = (cIdx)/GRP_UNIT_NUM;
    cSurplus= (cIdx)%GRP_UNIT_NUM;
    cLamp = (m_cInSelLamp[cGrpIdx]>>cSurplus)&0x01;

    if(m_cDirect==1){             //上
        if(cLamp==1){       //亮
            dispose_sendata((cIdx+1),0);
        }else if(cLamp==0){ //暗
//            if(cIdx>(m_cCurFloorNum-1))
                dispose_sendata((cIdx+1),1);
        }
    }else if(m_cDirect==0){       //下
        if(cLamp==1){       //亮
            dispose_sendata((cIdx+1),0);
        }else if(cLamp==0){ //暗
//            if(cIdx<(m_cCurFloorNum-1)){
                dispose_sendata((cIdx+1),1);
/*					 if(cIdx==3){//for test
					 		reg_insellamp(9,1);
					 }
					 if(m_cCurFloorNum==5){//for test
					 		reg_insellamp(10,1);
					 }*/
//				}
        }    
    }else if(m_cDirect==0xFF){    //无
        if(cLamp==1){       //亮
            dispose_sendata((cIdx+1),0);
        }else if(cLamp==0){ //暗
            dispose_sendata((cIdx+1),1);
        }    
    }
}

/*
uchar getsenddata(void)
{
    uchar cTest;
    return(cTest);

}
*/

void receivedata(void)
{
    uchar /*c0id1,c0id2,*/c0command,c0data;
    if((XBYTE[((P2&0xe0)|0x0F)*256+2]&1)==1){
//         c0id1=XBYTE[((P2&0xe0)|0x0F)*256+17];     //接收的数据id1
//         c0id2=XBYTE[((P2&0xe0)|0x0F)*256+18];     //接收的数据id2
       	 c0command=XBYTE[((P2&0xe0)|0x0F)*256+19]; //接收的命令  
         c0data=XBYTE[((P2&0xe0)|0x0F)*256+20];    //接收的参数
         XBYTE[((P2&0xe0)|0x0F)*256+1]=0xc;
         
         dispose_recdata(/*c0id1,c0id2,*/c0command,c0data);/*调用数据处理*/

		 time_nocan_count=TIMER_5s;
		 time_nocan_flg=0;
    }
}

void dispose_recdata(/*uchar c0id1,uchar c0id2,*/uchar c0command,uchar c0data)
{

//  uchar cTemp;
    //2005.03.07
    if((c0command>=25)&&(c0command<=m_cMaxFloorCnt)){    //内选灯(仅接收25-48层内选灯)
        reg_insellamp(c0command,c0data);		
    }else if(c0command==49){          // 超载
        if(c0data==1){
            m_cOverLoadLampFlg=1;
        }else if(c0data==0){
            m_cOverLoadLampFlg=0;
        }
    }else if(c0command==50){          // 蜂鸣器
        if(c0data==1){
            m_cBingFlg=1;
        }else if(c0data==0){
            m_cBingFlg=0;
        }
    }else if(c0command==51){          // 到站钟(只有确认,没有取消)
        if(c0data==1){
            m_cArriveRingFlg=1;
        }else if(c0data==0){
            m_cArriveRingFlg=0;         
        }
    }else if(c0command==0xCC){        // 灯全灭
        m_cInSelAllOffFlg=1;
    }else if(c0command==0xAA){        // 最大楼层数
        if(m_cMaxFloorCnt!=c0data)
		if((c0data>=1)&&(c0data<=48)){
            m_cMaxFloorCnt=c0data;
            m_set5045flg=0;
        }
    }else if(c0command==0x5A){        // 方向
        if(c0data==0x55){
            m_cDirect=1;
        }else if(c0data==0xAA){
            m_cDirect=0;
        }else if(c0data==0x00){
            m_cDirect=0xFF;
        }
    }

}

void reg_insellamp(uchar c0command,uchar c0data)
{
    uchar cGrpIdx, cSurplus;
    uchar cUp24Idx;
    //2005.01.27 LHM
    cUp24Idx= c0command;
    cGrpIdx = (cUp24Idx-1)/GRP_UNIT_NUM;
    cSurplus= (cUp24Idx-1)%GRP_UNIT_NUM;
    //!!!24层以上lamp登记在灯数组的后3字符
    if(c0data==1){
        m_cInSelLamp[cGrpIdx]=m_cInSelLamp[cGrpIdx]|(0x01<<cSurplus);
    }else if(c0data==0){
        m_cInSelLamp[cGrpIdx]=m_cInSelLamp[cGrpIdx]&(~(0x01<<cSurplus));
    }else if(c0data==0xAA){     //当前楼层数
        m_cCurFloorNum=cUp24Idx;
    }
}

⌨️ 快捷键说明

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