/*无线通讯语言模块测试·PAST 2019 12 28 L298 CODE1871**/
               #include     <REG52.H>
               #include     <intrins.H>
               #include     "stdio.h"
               #define      uint unsigned int  
               #define      uchar unsigned char
               uchar        code tab[10]={0X03,0X9F,0X25,0X0D,0X99,0X49,0X41,0X1F,0X01,0X09};
               #define      CMD_IDLE    0         //空闲模式
               #define      CMD_READ    1         //IAP字节读命令
               #define      CMD_PROGRAM 2         //IAP字节编程命令
               #define      CMD_ERASE   3         //IAP扇区擦除命令
               #define      ENABLE_IAP  0x82      //if SYSCLK<20MHz
               #define      IAP_ADDRESS 0x0000    //EEPROM首地址
               typedef      unsigned char BYTE;
               typedef      unsigned int WORD;
               uchar        kcounter,kstatus;     //按键计数标志 按键状态标志
               uchar        v;                    /*从机号*/
               int          count;
               int          time=0;
               sbit         OUT1=P1^3;            /****输出***/
               sbit         CLK=P1^1;
               sbit         SDA=P1^0;
               sbit         KEY_ADD=P3^6;
               sbit         KEY_DEC=P3^7;
               sbit         KEY_SET=P1^4;
               sbit         KEY_ENTER=P3^3;
               sbit         INTPUT=P1^2;
               sbit         MD0MD1=P3^2;
               bit          Warning;
               uchar        Counter;
               void         delay(uint k);        /****延时****/
               uchar        DAT2=0;
               bit           Receive_Flag;
 /*------------------------------------------*/
               void delay(uint t)
               {
               uint i,j;
               for(i=0;i<t;i++)
               for(j=0;j<10;j++);
               }
 /*---------------延时子程序----------------*/
               void delay1 (uint ms)
               {
               uint i,j;
               for(i=0;i<ms;i++)
               for(j=0;j<200;j++)
               ;
               }    
 /*----关闭IAP----------------------------*/
               void IapIdle()
               {
               IAP_CONTR=0;                       //关闭IAP功能
               IAP_CMD=0;                         //清除命令寄存器
               IAP_TRIG=0;                        //清除触发寄存器
               IAP_ADDRH=0X80;                    //将地址设置到非IAP区域
               IAP_ADDRL=0;
               }
 /*-从ISP/IAP/EEPROM区域读取一字节-*/
               BYTE IapReadByte(WORD addr)
               {
               BYTE dat;                          //数据缓冲区
               IAP_CONTR=ENABLE_IAP;              //使能IAP
               IAP_CMD=CMD_READ;                  //设置IAP命令
               IAP_ADDRL=addr;                    //设置IAP低地址
               IAP_ADDRH=addr>>8;                 //设置IAP高地址
               IAP_TRIG=0x5a;                     //写触发命令(0x5a)
               IAP_TRIG=0xa5;                     //写触发命令(0xa5)
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               dat=IAP_DATA;                      //读ISP/IAP/EEPROM数据
               IapIdle();                         //关闭IAP功能
               return dat;                        //返回
               }
 /*-写一字节数据到ISP/IAP/EEPROM区域-*/
               void IapProgramByte(WORD addr, BYTE dat)
               {
               IAP_CONTR=ENABLE_IAP;              //使能IAP
               IAP_CMD=CMD_PROGRAM;               //设置IAP命令
               IAP_ADDRL=addr;                    //设置IAP低地址
               IAP_ADDRH=addr>>8;                 //设置IAP高地址
               IAP_DATA=dat;                      //写ISP/IAP/EEPROM数据
               IAP_TRIG=0x5a;                     //写触发命令(0x5a)
               IAP_TRIG=0xa5;                     //写触发命令(0xa5)
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               IapIdle();
               }
 /*---扇区擦除---------------*/
               void IapEraseSector(WORD addr)
               {
               IAP_CONTR=ENABLE_IAP;              //使能IAP val=IapReadByte(IAP_ADDRESS+1);
               IAP_CMD=CMD_ERASE;                 //设置IAP命令
               IAP_ADDRL=addr;                    //设置IAP低地址
               IAP_ADDRH=addr>>8;                 //设置IAP高地址
               IAP_TRIG=0x5a;                     //写触发命令(0x5a)
               IAP_TRIG=0xa5;                     //写触发命令(0xa5)
               _nop_();                           //等待ISP/IAP/EEPROM操作完成
               IapIdle();
               }
 /*-----------------------------------------*/
               void red_eeprom(void)
               {
               uchar t_data,b_data;    //
               t_data=IapReadByte(IAP_ADDRESS);   //十位
               b_data=IapReadByte(IAP_ADDRESS+1); //个位
               v=t_data*10+b_data;
               }
 /***************************************/              
               void write_eeprom(uchar dat)
               {
               uchar Tdata,Bdata;                 //
               Tdata=dat/10;
               Bdata=dat-Tdata*10;
               IapEraseSector(IAP_ADDRESS);       //扇区擦除      
               IapProgramByte(IAP_ADDRESS,Tdata); /*写入十位*/
               IapProgramByte(IAP_ADDRESS+1,Bdata);/*写入小数*/
               }             
 /*------------------------------------------*/
               void ind_light_disp(uchar buff)    //点亮哪一位就置1
               {
               uchar j,sbuff;
               bit s;
               sbuff=buff;
                for(j=0;j<8;j++)                  //移动8位
                {
                s=sbuff&0x01;                     //位变量等于缓冲区最低位
                 if(s==1)                         //最低位等于1
                 {
                 CLK=0;                           //此处与下面的CLK = 1结合产生一个上升沿
                 SDA=0;
                 CLK=1;
                 }
                 else
                 {
                 CLK=0;
                 SDA=1;
                 CLK=1;
                 }
                 delay(10);
                 sbuff=sbuff>>1;                  //右移一次
                }
                delay(10);
               }
 /*------------------------------------------*/
               void display(uchar val)
               {   
               uchar ss;                          /*缓冲*/
               ss=(tab[(val%100)/10]);            /*十位*/
               ind_light_disp(ss);
               ss=(tab[val%10]);                  /*个位*/
               ind_light_disp(ss);
               }
 /******************************************/
               void key_reset()
               {
               kcounter=0;                        //计数器归零
               kstatus=0;                         //状态计数器归零
               delay1(5);
               }
 /******************************************/
               void Key_ValAdd()
               {
               kcounter++;                        //按键计数器加一
               kstatus++;                         //按键状态标志加一
               delay1(5);
               }
 /******************************************/
               void Key_Clear()
               {
               kcounter++;                        //按键计数器加一
               kstatus=0;                         //按键状态标志归零
               }
 /*------------初始化串口---------------------*/
               void InitUart()
               {
               SCON=0X50;                         //8位数据,可变波特率
               AUXR|=0x01;                        //串口1选择定时器2为波特率发生器
               AUXR|=0X04;                        //定时器2时钟为Fosc,即1T
               T2L=0XE0;                          //设置定时器处置  110592》9600
               T2H=0XFE;                          //设置定时器处置  110592》9600
               AUXR|=0X10;                        //启动定时器2
               TI=1;
               EA=1;
               }
 /*--------UART 中断服务程序----Buff=SBUF---------------*/
               void Uart() interrupt 4 using 1
               {
                if(RI)
                {
                DAT2=SBUF;                        //数组下标位置的数据等于j
                RI=0;                             //
                Receive_Flag=1;                     //接收数据标志置一
                }    
               }
 /*------------------主循环程序----------------*/      
               void   main( )                     /*主程序开始*/
               {                                  /**加一**/
               AUXR=0X80;                         //STC系列的1T 设置
               TMOD=0X01;
               InitUart();                        //初始化串口
               ES=1;
               Receive_Flag=0;                     //接收到数据标志置零
               P1=255;
               red_eeprom();
               display(v);
               MD0MD1=0;                             //
               Warning=0;                         //报警标志等于0
               Counter=0;                         //报警计数器等于0
               //    printf("报警标志");
               printf("<Z>5");
               printf("<V>2");
               printf("<S>3");
               while(1)
               {
                key_reset();
                if(!KEY_ADD)                      //从机编号加
                {
                 for(;kcounter<5;)                //按键循环5次
                 {
                  if(!KEY_ADD)                    //按键低电平
                  {
                  Key_ValAdd();                   //按键低电平 计数器加一状态标志加一
                  }
                  else if(~!KEY_ADD)              //按键高电平
                  {
                  Key_Clear();                    //按键计数器加一    状态标志归零
                  }
                 }
                if(kstatus>=3)                    /*按键状态标志大于等于3为有效值*/
                {  
                v++;   
                if(v>99)
                v=0;
                write_eeprom(v);
                display(v);
                delay1(10);
                }
               }
 
               key_reset();
               if(!KEY_DEC)                       //从机编号减
                {
                 for(;kcounter<5;)                //按键循环5次
                 {
                  if(!KEY_DEC)                    //按键低电平
                  {
                  Key_ValAdd();                   //按键低电平 计数器加一状态标志加一
                  }
                  else if(~!KEY_DEC)              //按键高电平
                  {
                  Key_Clear();                    //按键计数器加一    状态标志归零
                  }
                 }
                 if(kstatus>=3)                   /*按键状态标志大于等于3为有效值*/
                 {  
                 v-=1;   
                 if(v<1)
                 v=99;
                 write_eeprom(v);
                 display(v);
                 delay1(10);
                 }
                }
 
                key_reset();
                if(!KEY_SET)                      //数据发送
                {
                 for(;kcounter<5;)                //按键循环5次
                 {
                  if(!KEY_SET)                    //按键低电平
                  {
                  Key_ValAdd();                   //按键低电平 计数器加一状态标志加一
                  }
                  else if(~!KEY_SET)              //按键高电平
                  {
                  Key_Clear();                    //按键计数器加一    状态标志归零
                  }
                 }
                 if(kstatus>=3)                   /*按键状态标志大于等于3为有效值*/
                 {  
                 display(2);
                 printf("不喝酒就没得朋友可是只要偶一喝酒就喝倒一代朋友人生真的很矛盾");
                // printf("Please input up,dowm,high:\r\n");
                 OUT1=0;
                 delay1(2000);
                 delay1(2000);
                 OUT1=1;
                 display(9);
                 }
                }
 
               }
              }