久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 2236|回復: 0
打印 上一主題 下一主題
收起左側

求大神幫忙分析一段程序 后面main函數的邏輯看不懂

[復制鏈接]
跳轉到指定樓層
樓主
ID:170137 發表于 2017-3-16 08:32 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
這是一個簡易數字示波器的程序  前面的程序都不用 主要是后面main函數的邏輯看不懂 求大神幫忙看看

#include <AT89X52.h>
#include <intrins.h>
//12864控制引腳定義
sbit DI = P2 ^ 2; //數據D\指令I選擇引腳
sbit RW = P2 ^ 1; //讀R\寫W選擇引腳
sbit E= P2 ^ 0;   //讀\寫使能引腳
sbit CS1 = P2 ^ 4;    //片選1引腳
sbit CS2 = P2 ^ 3;    //片選2引腳
sbit BUSY= P1 ^ 7;    //忙標志位
//按鍵控制定義
sbit Y1 = P3 ^ 0;
sbit Y2 = P3 ^ 1;
sbit X1 = P3 ^ 3;
sbit X2 = P3 ^ 7;
//ADC0832控制引腳
sbit START=P3^4;
sbit OE=P3^6;
sbit EOC=P3^5;
unsigned int ADdata;    //AD采集值
unsigned int Ldata;     //控制命令
unsigned char ye,lei,shu;     //頁 列 數
unsigned char ADViewdata[91]; //AD顯示數據存儲區  存儲AD值
char code FrameData[]={              //提示字符存儲區                  
0x00,0x00,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFE,0x01,0x00,
0x01,0x00,0x11,0x10,0x11,0x08,0x21,0x04,0x41,0x02,0x81,0x02,0x05,0x00,0x02,0x00,    //示
0x00,0x20,0x20,0x20,0x10,0x20,0x13,0xFE,0x82,0x22,0x42,0x24,0x4A,0x20,0x0B,0xFC,
0x12,0x84,0x12,0x88,0xE2,0x48,0x22,0x50,0x22,0x20,0x24,0x50,0x24,0x88,0x09,0x06,  //波  
0x00,0x00,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,0x01,0x20,0x01,0x10,0xFF,0xFE,
0x02,0x80,0x0C,0x60,0x30,0x18,0xC0,0x06,0x3E,0x7C,0x22,0x44,0x22,0x44,0x3E,0x7C,    //器
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,    //" "
};
//AD轉換軟件
void ADCChage()
{
  START=1;
  START=0;
  while(EOC==0)  //等待轉換完成
{
   OE=1;
}
  ADdata = P0;   //讀取AD數據
OE=0;
}
//檢查12864液晶狀態                 
void CheckState()
{
  DI=0;
RW=1;
do
{
   E=1;
   E=0;
   //僅當第7位為0時才可操作(判別busy信號)
}while(BUSY==1);
}
//向12864寫入一個字節的命令
void WriteCommand(unsigned char cmd)  
{
CheckState();         //檢查當前的12864狀態
DI = 0;
RW = 0;
P1 = cmd;             //送出相應的命令
E = 1;
E = 0;
}  
//向12864寫入一個字節的數據
void WriteData(unsigned char dat)  
{
   CheckState();   //檢查當前的12864狀態
   DI = 1;
   RW = 0;
   P1 = dat;       //送出相應的數據
   E = 1;
   E = 0;
}
//12864液晶的選擇控制引腳   選擇左屏 還是右屏幕 CS1=0,CS2=0 全屏  CS=1,CS2=0 右屏
void LCMCSControl(unsigned int csl)
{
  if(csl==1)    //根據參數不同判斷當前的12864控制引腳狀態  選擇左邊
  {
    CS1=0,
    CS2=1;
  }
  if(csl==2)     //選擇右邊
  {
    CS1=1,
    CS2=0;
  }
  if(csl==3)  //全選
  {
    CS1=0,
    CS2=0;
  }
}
//12864顯示函數
void LCMView()
{
  LCMCSControl(Ldata);     //先發送控制命令
  WriteCommand(ye);    //選頁  10111xxx(頁地址) 0xB(不定)
  WriteCommand(lei);     //選列   01xxxxxx(列地址) 0x(不)(定)
  WriteData(shu);         //然后發送數據
}
//12864的清屏函數
void CleanScreen()      
{
unsigned char page,i;
LCMCSControl(3);    //左右屏幕選擇 3全選
for(page=0xb8;page<=0xbf;page++)    //0xb8 10111 000-10111 111 8頁全部掃描一遍
{   
  WriteCommand(page);
  WriteCommand(0x40);      //0x40 0100 0000  第0列
  for(i=0;i<64;i++)
    {
    WriteData(0x00);       //清零
    }
}
LCMCSControl(1);     // 左半屏
  lei=0x40;        //列 0100 0000
for(ye=0xb8;ye<0xbf;ye++)   // 10111 000 第0頁 -10111 111 第7頁
{
  shu=0xff;         //全1
  LCMView();        //顯示
}
ye=0xb8;
for(lei=0x40;lei<=0x7f;lei++)
{
   shu=0x80;
   LCMView();
}
ye=0xbf;
for(lei=0x40;lei<=0x7f;lei++)
{
   shu=0x01;
   LCMView();
}
  LCMCSControl(2);
  ye=0xb8;
for(lei=0x40;lei<=0x5b;lei++)
  {
   shu=0x80;
   LCMView();
}
ye=0xbf;
for(lei=0x40;lei<=0x5b;lei++)
{
   shu=0x01;
   LCMView();
}
lei=0x5b;
for(ye=0xb9;ye<=0xbe;ye++)
{
  shu=0xff;
  LCMView();
}
}
//12864的初始化函數
void InitLCM(void)   
{
  WriteCommand(0xc0);    // 1100 0000  啟始行
WriteCommand(0x3f);       // 0011 1111   屏幕開
}
//50us的延時函數
void Delay50us(unsigned int t)
{
unsigned char j;  
for(;t>0;t--)   
  for(j=19;j>0;j--);
}
//刷新12864液晶
void RefreshLCM()
{
  unsigned char i;
  for(i=0xb9;i<=0xbe;i++)
  {
    ye=i;
   shu=0x00;
   LCMView();
}
}
//主函數
void main()
{
    unsigned int r,j,q,k;
    unsigned int Xaxis =0;
    unsigned int Yaxis = 1;
    unsigned char l;
    unsigned char d1,d2,d3,d4,d5;
    CleanScreen(); //清屏
    InitLCM();     //初始化 開屏幕 設置初始行第0行
   LCMCSControl(2);   // 選擇右屏幕
   l=0xb8;       //啥玩意啊
   for(k=0;k<4;k++,l=l+0x02)         //首先顯示右側的提示 顯示“示波器 ”
   {
     ye=l;
     lei=0x70;      // 01(標識) 110000    第48列
     for(r=0;r<16;r++)
      {
        shu=FrameData[2*r+1+32*k];
       LCMView();
       lei++;
     }
     ye=l+0x01;     //第二頁
     lei=0x70;
     for(r=0;r<16;r++)
      {
        shu=FrameData[2*r+32*k];
       LCMView();
       lei++;
     }
}
  while(1)       //重頭戲來了
  {
    while(X2==0)      //調節X軸  外部按鍵控制X軸    +是延遲橫向掃描時間
    {
      while(X2==0);       //放開后才加
      Xaxis = Xaxis + 1;     //X軸
    }
    while(X1==0)
    {
      while(X1==0);
      if(Xaxis!=0)
      {
        Xaxis = Xaxis - 1;       //  縮短橫向掃描時間
      }
    }
    while(Y1==0)     //調節Y軸
    {
      while(Y1==0);
      Yaxis = Yaxis + 1;
    }
    while(Y2==0)
    {
      while(Y2==0);
      if(Yaxis!=1)         //調整顯示幅度DIV
      {
        Yaxis=Yaxis-1;
      }
    }
    for(j=0;j<90;j++) //AD采樣最大值     只是為了得到最大值
    {
      ADCChage();        //開啟轉換
      ADViewdata[j]=ADdata;      //采集的數據存入數表
      if(ADViewdata[j]>ADViewdata[91])     //選擇最大值
      {
        ADViewdata[91]=ADViewdata[j];      //選到的最大值存到91的位置
      }
      Delay50us(Xaxis);
    }
    while(ADdata!=ADViewdata[91])    //如果采集值不相等,則繼續  直至掃到最大值
    {
      ADCChage();
    }
    for(j=0;j<90;j++)      //連續采樣90次  要準備用來顯示了
    {
       ADCChage();
       ADViewdata[j]=ADdata;         //注意 只存到89 。91千萬不能碰
       Delay50us(Xaxis);
    }
    lei=0x41;         //01(標識) 000001     第1列
    for(r=0,j=0;r<90;r++,j++)    // 一個特別醒目的問題   一起加1
   {      //這個括號直接到整個程序結束的
      if(j<63)          //  如果是前64個數 則用左屏幕顯示
      {
        Ldata=1;
      }
     if(j==63)         //第64個數 用中間行顯示
      {
        lei=0x40;
      }
     if(j>=63)           //后面的數 用右屏幕顯示
      {
        Ldata=2;
      }
     RefreshLCM();     //刷新當前顯示
     if(ADViewdata[j>=127])//正電壓
     {                             
        ADdata=(ADViewdata[j]-127)*0.196/Yaxis;  //計算電壓值  0.196什么意思?
        if(ADdata<=7)          //小于7 沒超過
        {
          ye=0xbb;         //      10111(標識) 011 第A3頁 從上往下數是第四頁
          shu=(0x80>>ADdata);         // 1000 0000 右移
        }
       else if(ADdata<=15)      // 大于7小于15
        {
          ye=0xba;          // 10111(標識) 010 第A2頁 從上往下第三頁
          shu=(0x80>>(ADdata-8));
        }
        else if(ADdata<=23)      // 小于23  
        {
          ye=0xb9;       // 10111 001 第A1頁  從上往下第二頁
          shu=(0x80>>(ADdata-16));
         }
        else if(ADdata<=31)
        {
          ye=0xb9;          //還是A1頁
          shu=(0x80>>(ADdata-24));
        }
     }
     if(ADViewdata[j]<127)     //負電壓
     {
         ADdata=(127-ADViewdata[j])*0.196/Yaxis;    //計算電壓值
          if(ADdata<=7)
          {
              ye=0xbc;       //      10111 100 第A4頁
              shu=(0x01<<(ADdata));
          }
          else if(ADdata<=15)
          {
              ye=0xbd;         //A5頁
              shu=(0x01<<(ADdata-8));
          }
          else if(ADdata<=23)
          {
              ye=0xbe;           //A6頁
              shu=(0x01<<(ADdata-16));
          }
         else if(ADdata<=31)
          {
              ye=0xbe;            //A7頁
              shu=(0x01<<(ADdata-24));
          }
     }
      if(r==0)//判斷正負 上面一大串 其實只是為了得到一個顯示的點應該放在哪個位置     
     {
       d1=shu;
       d2=ye;    //存放位置信號 而且r==0 是啟始點
      }
      if(r!=0)  //不是第一個點     
     {   // 這個括號到快結束   
       d3=shu;            
       d4=ye;
       if(ye==d2)  //如果相等,則判斷是否顯示完成    跟第一個數是同一頁嗎
       {
         if(shu>d1)      //是同一頁的話 如果數比第一個數大  PS:同一位 位移的數越多 越大
         {
           d5=shu;       //確實比較大的話 給d5
           d5=d5>>1;         // 右移一位 除以2
           while(d5!=d1)      //跟初始值比 一樣的話沒事 不一樣的話 再除以2
           {
              d5=d5>>1;
             shu=shu|(shu>>1);
            }
         }
         if(shu<d1)      //同頁 但比較小
         {
           d5=shu;
           d5=d5<<1;
           while(d5!=d1)
          {
              d5=d5<<1;
              shu=shu|(shu<<1);
           }
         }
       }
        if(ye<d2)
       {  
         for(q=0;q<7;q++)
         {
          shu=shu|(shu<<1);
        }
      LCMView();
       ye++;
      while(ye<d2)
        {
          shu=0xff;
          LCMView();
          ye++;
        }
      if(ye==d2)
        {
          shu=0x01;
       if(shu<d1)
           {
             d5=shu;
             d5=d5<<1;
             while(d5!=d1)
             {
                d5=d5<<1;
                shu=shu|(shu<<1);
               }
            }
       }
        }
       if(ye>d2)
       {
         for(q=0;q<7;q++)
         {
          shu=shu|(shu>>1);
        }
      LCMView();
       ye--;
      while(ye>d2) {shu=0xff,LCMView(),ye--;}
      if(ye==d2)
        {
          shu=0x80;
       if(shu>d1)
           {
             d5=shu;
             d5=d5>>1;
             while(d5!=d1)
             {
                d5=d5>>1;
                shu=shu|(shu>>1);
               }
            }
    }
      }
   }
   if(r!=0)
   {
     d1=d3;
     d2=d4;
   }
    LCMView();
    if(lei!=0x7f)  //000 11111 最后一列
    {
      lei++;
    }
   }
}
}
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩欧美在线一区 | 一区二区三区视频在线观看 | 久久一日本道色综合久久 | 三区在线观看 | 国产精品777一区二区 | 国产日韩精品久久 | 在线观看国产精品一区二区 | 亚洲精品乱码久久久久v最新版 | 久久精品国产亚洲一区二区 | 亚洲欧美中文日韩在线v日本 | 久久久91 | 怡红院免费的全部视频 | 中文天堂网| 国产精品亚洲精品久久 | 看毛片网站| 精品成人 | 伊人久久大香线 | 欧美精产国品一二三区 | 羞羞视频网站免费观看 | 午夜激情视频 | 91国内外精品自在线播放 | www.玖玖玖| 成年人免费在线视频 | 久久久久国产一区二区三区 | 污视频在线免费观看 | 鸡毛片 | 成人国产精品色哟哟 | 久久久久一区二区三区 | 色婷婷综合网 | 国内自拍视频在线观看 | 99久久精品国产一区二区三区 | 五月激情婷婷六月 | 亚洲天堂二区 | 国产午夜精品一区二区三区嫩草 | 天天久久 | 国产久 | 精品在线观看入口 | 久久久久久黄 | 99re视频在线观看 | 亚洲国产成人精品女人久久久 | 国产成人在线播放 |