找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2703|回复: 10
收起左侧

谁有空帮忙解释下这个程序可否。。实在看不懂

[复制链接]
ID:125710 发表于 2016-11-1 10:23 | 显示全部楼层 |阅读模式
sbit  Send_EN  =  P5^5;

bit  Busy;//设置单次发送完成标志
bit  uart1_rec_ok; //命令到达标志
bit  uart1_rec_ok1;
bit  uart1_rec_ok2;


unsigned char Rec_data[5];
unsigned char Send_data[7];
unsigned char rec_addr;  //拨码开关
unsigned char Rec_point;//字节数
/*********************************************************************************/
void delay_ms(unsigned int time)   // //@11.0592MHz
{
unsigned char i, j;

do
   {
           _nop_();
        _nop_();
        _nop_();
        i = 11;
        j = 190;
        do
        {
                while (--j);
        } while (--i);
   }
while(time--);
}
/*********************************************************************************/
void uart1_init(void)
{
        SCON = 0x50;                  //8位数据,可变波特率
        AUXR |= 0x04;              //定时器2时钟为Fosc,即1T
        T2L = 0xE0;                     //设定定时初值
        T2H = 0xFE;                     //设定定时初值
        AUXR |= 0x01;                //串口1选择定时器2为波特率发生器
        AUXR |= 0x10;                //启动定时器2
        ES = 1;
        EA = 1;
}
/*********************************************************************************/

void system_init(void)
{

XD_74hc595_init();
XD_74hc165_init();
uart1_init();
}

/*********************************************************************************/
void Uart1sendData(unsigned char send_data)//写发送串口数据
{
  while(Busy);      //检测是否发送
  Busy=1;          //设置单次发送标志
  SBUF=send_data;  //把需要发送的数据给SBUF
}
/*********************************************************************************/
void  serial_send(unsigned char *send_str)//发送数据
{
unsigned char i;

Send_EN = 1;    //RS485设置为发送方向
for(i=0;i<6;i++)//发送6个字节
  {
   Uart1sendData(*send_str);
   send_str++;
  }       
Send_EN = 0;//RS485设置为接收方向
}
/*********************************************************************************/
void main(void)
{
unsigned char read_time;
// unsigned char i,j;
// unsigned char ceshi_data;

system_init();

while(1)
  {
  read_time++;
  if(read_time>=50)//延时
     {
          read_time = 0;
          XD_74hc165_Readdata();//读取165
          rec_addr = P1&0X0F;//设置拨码开关
         }
/*-------------------------------------------------*/   
   if(uart1_rec_ok)
     {
          uart1_rec_ok = 0;
          if(Rec_data[0]==rec_addr)
            {
                 if(Rec_data[1]==0x01)
                    {
                          XD_write_74hc595(Rec_data[2],Rec_data[3],Rec_data[4]);
                          delay_ms(120);
                          HC595_SRCLK = 0;
                          HC595_EN_A = 1 ;
                          HC595_EN_B = 1 ;
                          HC595_EN_C = 1 ;
                        }
                 if(Rec_data[1]==0x00)
                    {
                         XD_74hc165_Readdata();
                         Send_data[0]=XD_74hc165_DATA[0];
                         Send_data[1]=0x00;
                         Send_data[2]=XD_74hc165_DATA[1];
                         Send_data[3]=0x00;
                         Send_data[4]=XD_74hc165_DATA[2];
                         Send_data[5]=0x00;
                         serial_send(Send_data);
                        }
                }
         }
/*-------------------------------------------------*/           
  }

}

/*********************************************************************************/
void Uart1_int()   interrupt 4
{
unsigned char uart1_rec_data;
  if(RI)
   {
    RI=0;     //发生串口中断
    uart1_rec_data = SBUF; //把收到的数据给uart1_rec_data


        if(uart1_rec_ok2)      //检测帧头
          {          
           Rec_data[Rec_point] = SBUF; //保存接收字节,并递增计数器
           Rec_point++;                //继续接收字节
           if(Rec_point>=5)            //空闲时间超过4个字节传输时间即认为一帧命令接收完毕
             {
                  Rec_point = 0;             //字节清0
                  uart1_rec_ok2 = 0;
                  uart1_rec_ok = 1;         //命令到达标志
                 }          
          }
        else
          {
           if(uart1_rec_ok1)
             {
                  if(uart1_rec_data==0x55)
                    {
                         uart1_rec_ok1 = 0;
                         uart1_rec_ok2 = 1;
                         Rec_point = 0;
                        }
                  else
                    {
                         uart1_rec_ok1 = 0;
                         Rec_point = 0;
                    }
                 }
           else
            {
                 if(uart1_rec_data==0xaa)
                  {
                   uart1_rec_ok1 = 1;
                  }
                }
          }        
   }
if(TI)   //字节发送完毕
   {
           TI=0;  //手动清零发送中断标志位
        Busy=0;//设置单次发送完成标志
   }
}




以上中文字都是自己加进去的不知道是否正确 接收格式AA 55  01 00 XX  XX XX         AA 55代表头帧 01代表地址  00代表数据类型  XX XX XX任意值
0x00表示读LED的状态,0x01表示打开继电器
后面三个字节可为任意值,单片机收到该条命令后,会返回3个字节,这3个字节共有24个进制位,分别代表24个LED的状态,LED点亮相应的位为0,否则为1。

我现在不明白的地方有几个希望指点指点
bit  uart1_rec_ok1;
bit  uart1_rec_ok2;
分别定义的什么标识符 如uart1_rec_ok1=0代表什么  =1代表什么


if(Rec_data[1]==0x00)
                    {
                         XD_74hc165_Readdata();
                         Send_data[0]=XD_74hc165_DATA[0];
                         Send_data[1]=0x00;
                         Send_data[2]=XD_74hc165_DATA[1];
                         Send_data[3]=0x00;
                         Send_data[4]=XD_74hc165_DATA[2];
                         Send_data[5]=0x00;
                         serial_send(Send_data);
                        }

返回的是3个字节,这3个字节共有24个进制位 加0X00是什么意思。
就以上问题特求大神指点




回复

使用道具 举报

ID:125710 发表于 2016-11-1 10:32 | 显示全部楼层
if(uart1_rec_ok1)
             {
                  if(uart1_rec_data==0x55)
                    {
                         uart1_rec_ok1 = 0;
                         uart1_rec_ok2 = 1;
                         Rec_point = 0;
                        }
                  else
                    {
                         uart1_rec_ok1 = 0;
                         Rec_point = 0;
                    }
                 }
           else
            {
                 if(uart1_rec_data==0xaa)
                  {
                   uart1_rec_ok1 = 1;
                  }
                }
          }         

格式明明是AA 55 为什么要先检测55而不是AA
回复

使用道具 举报

ID:138155 发表于 2016-11-1 13:51 | 显示全部楼层

回帖奖励 +10

AA应该是校验数 如果是正确的就过 不正确就不过
回复

使用道具 举报

ID:145514 发表于 2016-11-1 14:20 | 显示全部楼层
校验字为 0xaa55...校验的实质是把这个字运算器 XRL运算,所以,先AA还是先55其实要看CPU是大端的还是小端的,如果是大端和小端的区别在于 一个两个字节的字传送时候是先高字节还是低字节:
小端的是低字节在前高字节在后,同样 字的传送也是这个道理,
你这个CPU如果是大端的,而且那么传送一个字(2个字节),就会是先传 高字节 0xaa,再传0x55,也就是先aa 再55
否则,小端的CPU是先 55 再aa
回复

使用道具 举报

ID:111634 发表于 2016-11-1 18:16 | 显示全部楼层
看不懂,就去找看得懂的程序,对照着看。
回复

使用道具 举报

ID:111634 发表于 2016-11-1 18:16 | 显示全部楼层
老是找看不懂的程序,自找麻烦。
回复

使用道具 举报

ID:111634 发表于 2016-11-1 18:19 | 显示全部楼层
你看不懂,别人即使看懂,也许化很多时间去揣摩。不要再找这些无厘头的程序让所谓“大神”诊断!
回复

使用道具 举报

ID:61840 发表于 2016-11-2 22:36 | 显示全部楼层
if(Rec_data[1]==0x00)
                    {
                         XD_74hc165_Readdata();
                         Send_data[0]=XD_74hc165_DATA[0];
                         Send_data[1]=0x00;
                         Send_data[2]=XD_74hc165_DATA[1];
                         Send_data[3]=0x00;
                         Send_data[4]=XD_74hc165_DATA[2];
                         Send_data[5]=0x00;
                         serial_send(Send_data);
                        }

多发一个0X00是为了消除前面数据对串并转换过程中移位留存影响。

回复

使用道具 举报

ID:125710 发表于 2016-11-2 22:52 | 显示全部楼层
mercizy999 发表于 2016-11-1 14:20
校验字为 0xaa55...校验的实质是把这个字运算器 XRL运算,所以,先AA还是先55其实要看CPU是大端的还是小端 ...

什么是大端CPU和小端CPU
回复

使用道具 举报

ID:145840 发表于 2016-11-2 23:10 | 显示全部楼层
看不懂,写点注解呀
回复

使用道具 举报

ID:89217 发表于 2016-11-10 09:59 | 显示全部楼层
void Uart1sendData(unsigned char send_data)//写发送串口数据
{
   while(Busy);      //检测是否发送
  Busy=1;          //设置单次发送标志
  SBUF=send_data;  //把需要发送的数据给SBUF
}总觉得这个有点问题,一开始是0 怎么检测的过?
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表