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

📄 yxktvtest.c

📁 C51环境下的KTV用的娱乐投票器
💻 C
📖 第 1 页 / 共 3 页
字号:
              }
           }
     }
     else
     {//读出记录
       iPos=iPos&0x0f;
       ReadKey(iPos);
       ShowNums();
       bEnter=1;
     }

          EA=0;SerN=0;TR=0;//send..
          PushSendBuf(0xAA);
          PushSendBuf(0x55);
          PushSendBuf(0);
          PushSendBuf(AddH);
          PushSendBuf(0);
          PushSendBuf(AddL);

      switch (iMode)
      {
        case 0:
          SerData[2]=0x0B;
          SerData[4]=0x50;
          PushSendBuf(02);
          PushSendBuf(AddH);
          PushSendBuf(AddL );
          PushSendBuf(PwrT);
          PushSendBuf(Config1);
          PushSendBuf(Config2);
          PushSendBuf(Config3);
          break;
        case 1: //多键
          SerData[2]=0x0C;
          if (bEnter) SerData[4]=0x52;else SerData[4]=0x51;
          PushSendBuf(LcdBuf[0]);
          PushSendBuf(LcdBuf[1]);
          PushSendBuf(LcdBuf[2]);
          PushSendBuf(LcdBuf[3]);
          PushSendBuf(LcdBuf[4]);
          PushSendBuf(LcdBuf[5]);
          PushSendBuf(TimerA /256 );
          PushSendBuf(TimerA);
          break;
        case 2://单键
          SerData[2]=0x05;
          SerData[4]=0x53;
          PushSendBuf(LcdBuf[5]);
          break;
        case 3://多人投票
          SerData[2]=0x0E;
          SerData[4]=0x56;
          for (i=0;i<10;i++) PushSendBuf(IcBuf[i]);
          break;

        case 0x0f://ack...
          SerData[2]=0x06;
          SerData[4]=0x50;
          PushSendBuf(01);//status
          PushSendBuf(InputMode);
          break;

       }

          Crc=0;
          for (i=1;i<SerData[2];i++)
              Crc=Crc^SerData[i+2];

          PushSendBuf(Crc);
          EA=1;
          StartSendBuf();

}

void SendIni()
{
   SendInfo(0,0);
}

void SendAck() using 1//BANK_SERI
{  uchar Crc ;

   bSendAck=1;TR=0;bSendOk=0;

   switch (SerN)
   {
      case 0:
         SBUF=0xAA;
         break;
      case 1:
         SBUF=0x55;
         break;
      case 2:
         SBUF=6;
         break;
      case 3:
         SBUF=AddH;
         break;
      case 4:
         SBUF=0x50;
         break;
      case 5:
         SBUF=AddL;
         break;
      case 6:
         SBUF=1; //status
         break;
      case 7:
         SBUF=InputMode;
         break;
      case 8:
          Crc=0;
          Crc=Crc^AddH;
          Crc=Crc^AddL;
          Crc=Crc^0x50;
          Crc=Crc^1;
          Crc=Crc^InputMode;
          SBUF=Crc;
          break;
      default:
           bSendAck=0;
           bSendOk=1;
           SerN=0;
           TR=1;//
           return;
    }
    SerN++;
}

/*处理系统命令*/
void ReadCmd50()
{    uchar data i;
     switch (SerData[6])  /*子命令码*/
     {  case 0x1:/*显示编号*/
             IniPos=1;
             ShowIni();
             break;
        case 0x2: /*读配置*/
             if (KeyNo!=KOK) break;

             SendIni();

             IniPos=1;
             ShowIni();

             break;
        case 0x3:  /*写配置*/
             if (KeyNo!=KOK) break;

             AddH=SerData[7];
             AddL=SerData[8];
             PwrT=SerData[9];
             Config1=SerData[10];
             Config2=SerData[11];
             Config3=SerData[12];
             WriteIni();
             ReadIni();
             IniPos=1;
             ShowIni();
             SendIni();
             break;
        case 0x4: /*延时关机*/
             //PwrTimer=SerData[7]*256 + SerData[8];
             break;
        default: //认为是按模式扫描启动
             InputClr();
             ShowNums();
             break;

      }
}

/*解读串口命令*/
void ReadCmd()
{    register uchar i,Crc;

    if (bRcvChar==0)//是显示字符时不效验Crc
    {
     Crc=0;
     for (i=0;i<SerN-4;i++) Crc=Crc^SerData[i+3]; /*计算CRC,Len后Crc前的XOR值*/
     if(Crc!=SerData[SerN-1]) /*CRC效验不正确*/
        {  goto ReadClear;

        }
     }

     LED=~LED;

     if (!((SerData[3]==AddH) && (SerData[5]==AddL)))
       if (!((SerData[3]==0)&&(SerData[5]==0)))
          goto ReadClear1;

     /*地址相同或00*/
     SerN=0; //!bug 有不发送应答的处理
             //所以先清除SerN,否则后继第一条指令丢失
     SleepTimer=PwrT*120;

     switch (SerData[4])  /*命令码*/
     {
        case 0x50:
          ReadCmd50();
          //InputN=6; //按键不能再输入 no 会影响启动扫描命令的InputClr
          bRcvOk=0;
          return;

        case 0x51://多键
        case 0x52://单键
        case 0x53://定额
          InputMode=SerData[4]-0x50;
          SendInfo(SerData[6],1);//带DataPos

          bRcvOk=0;
          return;/*不用break,保证SERN不改写为0*/

        case 0x5A:
           for (i=0;i<6;i++) LcdBuf[i]=SerData[6+i];
           ShowNums();
           InputN=0;
           bEnter=0;
           break;

        case 0x5C://循环显示效果
           bRcvOk=0;
           bRcvChar=0;
           SendAck();//开始启动应答
           CharN=SerData[2]-6;
           LcdClr(0);
           LCDLED=0;
           LedTimer=C_LED; //亮
           bLoopShow=1;
           LoopPos=0;
           return;//!!

        case 0x5D://全屏显示效果
           bRcvOk=0;
           bRcvChar=0;
           SendAck();
           bLoopShow=0;//!!
           CharN=SerData[2]-6;
           LcdClr(0);
           Prints(CharData[0],CharData[1],&CharData[2],CharN);
           LCDLED=0;
           LedTimer=C_LED; //亮
           return;//!!

        case 0x5E://写缺省显示数据
           bRcvOk=0;
           bRcvChar=0;
           SendAck();//开始启动应答
           CharN=SerData[2]-6;
           if (CharN>0)
           {
             CharData[0]=CharN;
             CharData[1]=0;
             WrBytes(0x80,&CharData[0],CharN+2);
           };
           ShowEprom();
           return;//!!

        case 0x55://停止输入
           InputMode=0;
           if (SerData[6]==2) LcdClr(4);
           break;
       default:
              break;
     };

ReadClear:
     bRcvOk=0;
     SerN=0;
     return;

ReadClear1:
     switch (SerData[4])  /*命令码*/
     {

        case 0x51:/*多键带计时*/
        case 0x52:
        case 0x53: /*单键带计时,包含抢答*/
          InputMode=SerData[4]-0x50;
          i=SerData[6];
          if ((SerData[2]==5)&&(i<0x80))
           {  i=i&0x0f;
              if (i!=DataPos)
              { //收到不同的DataPos时表示已经启动新的扫描
              DataPos=i;
              InputClr();
              ShowNums();
              }
            }
     }
     goto ReadClear;
}

void InputClr()
{  uchar i;
   for (i=0;i<6;i++) LcdBuf[i]=0x0f;
   InputN=0;
   bDot=0;bEnter=0;
   TimerA=0;
   Money=0;
}

void SystemIni()
{       register uchar i;

        TMOD=0x21;              /*定时器0工作于方式1,定时器1工作于方式0*/
        PCON=0x80;              /*波特率19200*/
        SCON=0x50;              /*串行口为方式1,10位异步收发模式*/

        TH0=C_T0H;
        TL0=C_T0L;

        TH1=0xFD;
        TL1=0xFD;

        IT0=1;                  /*外中断为下降沿触发*/
        IP=0;                   /*中断优先级全部设为低优先级*/
        //PS=1;/*串口设为高优先级 No!除非使用不同的BankRam否则影响其他中断的@R0等操作*/
        ET0=1;ES=1;             /*开定时器0中断和串行口中断*/
        ET1=0;     //串口定时器1关
        EX0=0;     //INT0关

        P1=0xff;
        P2=0xff;
        InputClr();

        if (InitOkNum!=0xA5)
        {  ReadIni();
           InitOkNum=0xA5;
           InitOkNum1=0x5A;
           //LcdAll();DelayMs(200);DelayMs(200);//复位测试
        }

        LcdInit();

        TimerN=C_TIMERN;
        LoopT=C_LOOPT;
        SerN=0;
        bRcvOk=0;bSendOk=1;
        InputMode=1;
        SleepTimer=10;//PwrT*120;
        SleepN=3;

        P3=0xff; //S52有开机RXD=0的情况
        REN=1;
        TR0=1;TR1=1;            /*启动定时器0和定时器1*/
        EA=1;

}

void int0 (void) interrupt 0 using 1
{
        IE0=0;
}

void timer0 (void) interrupt 1 using 1
{       /*TR0=0;*/
        TH0=C_T0H;
        TL0=TL0+C_T0L;
        if (--TimerN==0 )
           { bTimer=1;
             TimerN=C_TIMERN;}
        if (--LoopT==0 )
           { if (bLoopShow) bLoop=1;
             LoopT=C_LOOPT;}

        /*TR0=1;*/
        TimerA++;
        bKeyScan=1;/*键盘防抖*/
}

void Int1 (void) interrupt 2 using 1
{
    IE1=0;
}

void timer1 (void) interrupt 3 using 1
{
    //TR1=0;//不能关闭Timer1

}

/*串口数据接收*/
void RecvData() using BANK_SERI
{
     if (bRcvOk) return;

     //IconSETUP=1;//test

     switch (SerN)
     {
        case 0:
             if (SBUF==0xAA) {
                SerData[0]=SBUF;
                SerN++;
             }
             break;
        case 1:
             if (SBUF==0x55) {
                SerData[1]=SBUF;
                SerN++;
             } else{
                   SerN=0;
                   }

             break;
        case 2:
             if ((SBUF>3)&&(SBUF<80)) {//长度
                SerData[2]=SBUF;
                SerN++;
             } else{
                   SerN=0;
                   }
             break;

        default:
             if (bRcvChar==0)
             {
               if (SerN < C_SERMAXN   )
               {
                  SerData[SerN]=SBUF;
                  if ((SerN==5)&&(SerData[4]>=0x5C))
                     bRcvChar=1;
                  SerN++;
                }else
                 {  SerN=0;}
             } else
             {//接收显示数据
               CharData[SerN-6]=SBUF;
               SerN++;
             };

             if (SerN == (SerData[2]+3)) {/*[0]=AA [1]=55 [2]=Len*/
                  bRcvOk=1; }
             break;
     }
}


/*发送的数据入串口Buf*/
void PushSendBuf(uchar i)
{
     if (SerN >= C_SERMAXN) return;
     SerData[SerN]=i;
     SerN++;
     SerBufN++;
}

/*开始发送数据包*/
void StartSendBuf()
{
      TR=0;/*切换到发送状态*/
      //DelayMs(2);

      SerHeadN=C_HEADN ;
      SerN=0;
      SBUF=0x55;
      bSendOk=0;
}

/*串口发送中断调用的 串口数据发送*/
void SendData() using BANK_SERI
{
     if (bSendOk) return;
     if (bSendAck)
     {  SendAck();
        return;
     }

     if (SerHeadN>0) /*发送引导数据*/
     {    if (SerHeadN==1) SBUF=0x66 ;
             else
          if (SerHeadN==2) SBUF=0xFF ;
             else SBUF=0x55;
          SerHeadN--;
          return;
     }

     SBUF=SerData[SerN];
     SerN++;
     //if (SerN>=SerBufN)//Bug!漏最后一个字节
     if (SerN>SerBufN)
     {
        TR=1;   /*切换到接收状态*/
        bSendOk=1;
        SerN=0;
        SerBufN=0;
     }
}

void serials(void) interrupt 4 using BANK_SERI
{
        if(RI==1)
        {
           RI=0;
           if (TR==1)
           {  RecvData();/*有发送状态产生接受中断的情况*/
           //不是TR=0影响开机接收不到数据;
           return;
           }
        }
        if(TI==1)
        {
           TI=0;
           SendData();
       }
}


void KeyScan()
{    uchar code KEYTAB[] =
     //{ 0,0x0e,0x0f,0x0c,0x0d,1,4,7,0x0a,2,5,8,0,3,6,9,0x0b,0x10};
    { 0,1,2,3,KOK,4,5,6,KESC,7,8,9,KFUNC1,KDEL,0,KDOT,KFUNC2};

     register uchar i,KeyTemp;

     bKeyScan=0;

     bKeyOk=0;
     for (i=0;i<4;i++)
     {
        if (i==0) K0=0;
        if (i==1) K1=0;
        if (i==2) K2=0;
        if (i==3) K3=0;
        KeyTemp = i*4;

⌨️ 快捷键说明

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