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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 6240|回復: 5
收起左側

基于PIC16F877單片機的簡易數字電壓表設計及proteus仿真

  [復制鏈接]
ID:697394 發表于 2020-6-9 18:50 | 顯示全部樓層 |閱讀模式
與各位分享我的代碼
1.系統功能
1.1可測0~5V的8路輸入電壓值;
1.2在LED數碼管上輪流顯示;
1.3單路選擇顯示;
2.系統硬件設計
2.1 單片機采用PIC16F877
2.2 鍵盤為4×4行列式鍵盤,按鍵設有10個數字鍵0……9,和5個功能鍵依次是:各通道輪流顯示鍵、單通道顯示鍵、向左滾動顯示鍵、顯示啟動/停止鍵、回車鍵。
2.3有3位LED管,左邊1位用于指示顯示通道,右邊2位顯示電壓值,保留到小數點后面1位。
3系統軟件設計
3.1鍵盤管理程序(包括鍵掃描、鍵處理程序);
3.2LED動態顯示程序;
3.3各通道輪流顯示,共顯示8個通道,每通道顯示1s;
3.4 單通道顯示,僅顯示指定通道電壓,并保持到其他功能鍵按下。

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
@82KKR_003[IEK%OUJ${FSA.png

單片機源程序如下:
  1. //作者:云樹阿云
  2. #include <htc.h>
  3. #include <pic.h>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. __CONFIG(0x3b32);//狀態字
  7. uchar table[]={0x00,0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef};//數碼管顯示字符表
  8. uchar channel[]={0x41,0x49,0x51,0x59,0x61,0x69,0x71,0x79};//代表8個通道被按下的狀態表
  9. uchar key_num;//按鍵標志位
  10. uchar disp_num;//通道標志位
  11. uchar left_num;
  12. uchar loop_num;
  13. uint volval=0;//電壓值
  14. uint enter=0;//回車被按下標志位
  15. uint on_off=0;//開機標志位
  16. uint loop_disp=0;//循環顯示標志位
  17. uint single_disp=0;//單通道顯示標志位
  18. uint left_move=0;//左移顯示標志位
  19. uint a;//用于顯示的換算位
  20. uint b;//用于顯示的換算位
  21. uint c;//用于顯示的換算位
  22. uint d;//用于左移顯示的轉移中間值
  23. uchar e=2;
  24. uchar onkey_num;



  25. void delay(uint x)//延時程序
  26. {uint times,num;
  27.    for(times=x;times>0;times--)
  28.       for(num=110;num>0;num--);
  29. }

  30. void display(uint i,uint j)//顯示程序
  31.    {
  32.      a=i/10;//通過電壓值和通道值算出需要顯示的值
  33.      b=i-a*10;//通過電壓值和通道值算出需要顯示的值
  34.     a=a+10;//為電壓第一位加上小數點
  35.       c=j;
  36.       if(enter==0)
  37.       {a=-1;
  38.          b=-1;
  39.          //c=-1;
  40.          }
  41.     TRISD=0x00;//設置輸出端口
  42.     TRISB=0x00;//設置輸出端口
  43.       delay(1);//延時
  44.          RB0=0;//選擇需要亮起的數碼管
  45.          RB1=1;
  46.          RB2=1;         
  47.         PORTD=table[c+1];//輸出需要顯示的數字
  48.        delay(1);//延時
  49.          RB0=1;//選擇需要亮起的數碼管
  50.          RB1=0;
  51.          RB2=1;   
  52.       PORTD=table[a+1];
  53.          delay(1);//延時
  54.          RB0=1;//選擇需要亮起的數碼管
  55.          RB1=1;
  56.          RB2=0;         
  57.          PORTD=table[b+1];//輸出需要顯示的數字
  58.       }

  59. void getab(uint i,uint j)//左移顯示時獲得當前的a,b,c值
  60. { a=i/10;
  61.    b=i-a*10;
  62.    a=a+10;
  63.    c=j;
  64.    }  

  65. void leftdisplay()//左移顯示模式的顯示程序,類似顯示程序
  66.    {
  67.     TRISD=0x00;
  68.     TRISB=0x00;
  69.       delay(1);
  70.          RB0=0;
  71.          RB1=1;
  72.          RB2=1;         
  73.         PORTD=table[c+1];
  74.        delay(1);
  75.          RB0=1;
  76.          RB1=0;
  77.          RB2=1;   
  78.       PORTD=table[a+1];
  79.          delay(1);
  80.          RB0=1;
  81.          RB1=1;
  82.          RB2=0;         
  83.          PORTD=table[b+1];
  84.       }      
  85.       
  86. void leftmove()//實現左移顯示的程序(交換abc)
  87.       
  88.    {        if(left_num==8)
  89.       {
  90.          left_num=0;
  91.       ADCON0=channel[0];
  92.         uint adval;
  93.         GO=1;
  94.         while(GO)
  95.         adval=ADRESH;
  96.         adval=adval<<8|ADRESL;
  97.         volval=adval/20;        
  98.          a=-1;
  99.         b=volval/10;
  100.         b=b+10;
  101.         c=left_num;
  102.       }
  103.       else{
  104.          //disp_num++;
  105.         ADCON0=channel[left_num];
  106.          
  107.         uint adval;
  108.         GO=1;
  109.         while(GO)
  110.         adval=ADRESH;
  111.         adval=adval<<8|ADRESL;
  112.         volval=adval/20;        
  113.          a=-1;
  114.         b=volval/10;
  115.         b=b+10;
  116.         c=left_num;
  117.      }
  118.       }
  119. void scan()//掃描程序獲得key_num
  120.       {        TRISC=0xf0;//C端口高四位輸出,低四位輸入
  121.          PORTC=0xfe;//首先掃描第一列
  122.          key_num=PORTC;//讀取C端口低四位,獲得key_num
  123.          key_num=key_num&0xf0;//判斷低四位是否有1存在
  124.          if (key_num!=0xf0)//如果低四位有1(第一行有鍵被按下)
  125.          { delay(10);//去抖動
  126.          key_num=PORTC;//重新讀取
  127.          key_num=key_num&0xf0;//得到低四位中為1的位,其他位置0
  128.             if (key_num!=0xf0)
  129.             {
  130.                key_num=key_num|0x0e;//加上高四位中被掃描的值,獲得代表被按下鍵的值:key_num
  131.                }
  132.             }
  133.           else//其他列依次判斷
  134.           {
  135.              PORTC=0xfd;
  136.          key_num=PORTC;
  137.          key_num=key_num&0xf0;
  138.          if (key_num!=0xf0)
  139.          { delay(10);
  140.          key_num=PORTC;
  141.          key_num=key_num&0xf0;
  142.             if (key_num!=0xf0)
  143.             {
  144.                key_num=key_num|0x0d;
  145.                }
  146.             }
  147.             else
  148.             {
  149.              PORTC=0xfb;
  150.          key_num=PORTC;
  151.          key_num=key_num&0xf0;
  152.          if (key_num!=0xf0)
  153.          { delay(10);
  154.          key_num=PORTC;
  155.          key_num=key_num&0xf0;
  156.             if (key_num!=0xf0)
  157.             {
  158.                key_num=key_num|0x0b;
  159.                }
  160.             }
  161.             else
  162.             {
  163.              PORTC=0xf7;
  164.          key_num=PORTC;
  165.          key_num=key_num&0xf0;
  166.          if (key_num!=0xf0)
  167.          { delay(10);
  168.          key_num=PORTC;
  169.          key_num=key_num&0xf0;
  170.             if (key_num!=0xf0)
  171.             {
  172.                key_num=key_num|0x07;
  173.                }
  174.             }
  175.                }
  176.                }
  177.              }
  178.          }
  179. void switched()//根據key_num改變相應標志位
  180.          {
  181.             switch(key_num)
  182.                {case 0xee:disp_num=7;enter=0;break;//通道選擇
  183.                 case 0xed:disp_num=4;enter=0;break;//通道選擇
  184.                 case 0xeb:disp_num=1;enter=0;break;//通道選擇
  185.                 case 0xe7:if(onkey_num!=key_num){on_off=!on_off;enter=0;}break;
  186.                            //on_off=1;                          break;//開機
  187.                 //case 0xde:disp_num=7;enter=0;break;//通道選擇
  188.                 case 0xdd:disp_num=5;enter=0;break;//通道選擇
  189.                   case 0xdb:disp_num=2;enter=0;break;//通道選擇
  190.                 case 0xd7:disp_num=0;enter=0;break;//通道選擇
  191.                 //case 0xbe:disp_num=7;enter=0;break;//通道選擇
  192.                 case 0xbd:disp_num=6;enter=0;break;//通道選擇
  193.                 case 0xbb:disp_num=3;enter=0;break;//通道選擇
  194.                 case 0xb7:enter=1;break;//回車鍵
  195.                 case 0x7e:loop_disp=1;single_disp=0;left_move=0;enter=0;break;//循環顯示功能
  196.                 case 0x7d:loop_disp=0;single_disp=1;left_move=0;enter=0;break;//單通道顯示功能
  197.                 case 0x7b:loop_disp=0;single_disp=0;left_move=1;enter=0;break;//左移顯示功能
  198.                 //case 0x77:on_off=0;break;//關機
  199.                }
  200.             }
  201. void measure()//AD轉化程序&完成相應功能
  202.             {
  203.                TRISA=0xff;
  204.                ADCON0=channel[disp_num];
  205.                ADCON1=0x80;

  206.                if(enter==1&&single_disp==1)
  207.                {
  208.                   uint adval;
  209.                   GO=1;
  210.                   while(GO)
  211.                   adval=ADRESH;
  212.                   adval=adval<<8|ADRESL;
  213.                   volval=adval/20;
  214.                   onkey_num=key_num;  
  215.                   scan();
  216.                    switched();
  217.                  display(volval,disp_num);
  218.                }
  219.               //display(99,disp_num);
  220.                 while(enter==1&&left_move==1&&on_off==1)
  221.                {left_num=disp_num;
  222.                  while(left_move==1&&on_off==1&&left_num!=8)
  223.                {onkey_num=key_num;  
  224.                   scan();
  225.                    switched();
  226.                   //
  227.                   ADCON0=channel[left_num];
  228.                   uint adval;
  229.                   GO=1;
  230.                   while(GO)
  231.                   adval=ADRESH;
  232.                   adval=adval<<8|ADRESL;
  233.                   volval=adval/20;                  
  234.                getab(volval,left_num);

  235.                while(e!=0)
  236.                {
  237.                   uint disp_times=650;         

  238.                   while(disp_times!=0&&left_move==1)
  239.                   {onkey_num=key_num;  
  240.                    scan();
  241.                    switched();        
  242.                   //left_num=disp_num;   
  243.                      leftdisplay();
  244.                      disp_times--;
  245.                   }
  246.                   e--;
  247.                   if(e==1)
  248.                   {
  249.                  left_num++;
  250.                  leftmove();

  251.                   }
  252.                }
  253.                e=2;
  254.                }
  255.                left_num=0;
  256.                }
  257.                
  258.                
  259.                if(enter==1&&loop_disp==1&&on_off==1)
  260.                {loop_num=disp_num;
  261.                while(loop_disp==1&&on_off==1)
  262.                {

  263.                   while(loop_num!=8&&loop_disp==1&&on_off==1)
  264.                   {
  265.                   uint disp_times=525;//循環次數,完成該次數后剛好顯示了一秒鐘         
  266.                   while(disp_times!=0&&loop_disp==1&&on_off==1)//循環顯示程序
  267.                   {onkey_num=key_num;  
  268.                    scan();//掃描
  269.                    switched();//改變狀態字
  270.                   ADCON0=channel[loop_num];//AD轉換
  271.                   uint adval;
  272.                   GO=1;
  273.                   while(GO)
  274.                   adval=ADRESH;
  275.                   adval=adval<<8|ADRESL;
  276.                   volval=adval/20;
  277.                   //getab(volval,loop_num);
  278.                   //leftdisplay;
  279.                   display(volval,loop_num);//顯示
  280.                      disp_times--;//循環次數自減
  281.                   }
  282.                   loop_num++;//顯示了1秒鐘后,通道號加一                  
  283.                   }
  284.                   loop_num=0;//disp_num等于8的時候置0
  285.                }
  286.             }
  287.                while(enter==0&&(loop_disp==1||left_move==1))
  288.                {onkey_num=key_num;  
  289.                   scan();//掃描
  290.                    switched();//改變狀態字
  291.                   display(0,-1);
  292.                   }            
  293.                   }
  294. void main()//主程序
  295. {
  296.     while(1)
  297.     {  onkey_num=key_num;  
  298.        scan();
  299.        switched();
  300.        //display(volval,disp_num);
  301.        while(on_off==1)
  302.        {onkey_num=key_num;  
  303.         scan();
  304.        switched();
  305.           //left_num=disp_num;
  306.         measure();
  307.        display(volval,disp_num);
  308.        }
  309.        c=-1;
  310.        a=-1;
  311.        b=-1;
  312.         leftdisplay();  
  313.     }
  314. }
復制代碼

全部資料51hei下載地址:
電壓表備份 試驗品.rar (35.2 KB, 下載次數: 156)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:712295 發表于 2020-9-18 16:27 | 顯示全部樓層
樓主你好請問PIC這個芯片的AD原理是怎么樣的》能說一下嘛
回復

使用道具 舉報

ID:821033 發表于 2020-9-25 16:54 | 顯示全部樓層
謝謝分享,下載下來學習學習
回復

使用道具 舉報

ID:821033 發表于 2020-9-25 16:56 | 顯示全部樓層
謝謝樓主分享,下載下來學習學習
回復

使用道具 舉報

ID:869201 發表于 2020-12-29 09:26 來自手機 | 顯示全部樓層
十分有用
回復

使用道具 舉報

ID:982749 發表于 2021-11-30 19:53 | 顯示全部樓層
樓主,編譯時候顯示GO=1是錯誤的
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品二区 | 亚洲国产精品99久久久久久久久 | 国产高清一区二区三区 | 四虎永久在线精品免费一区二 | 欧美一级久久久猛烈a大片 日韩av免费在线观看 | 日韩精品在线视频免费观看 | 黑人精品欧美一区二区蜜桃 | 午夜在线视频 | 国外成人免费视频 | 二区国产 | 精品欧美一区二区三区久久久 | 国产精品欧美一区二区三区不卡 | 日韩一二三区视频 | 精品国产一级 | 日韩欧美在线免费观看视频 | 国产精品中文字幕在线 | 精品视频一区二区三区 | 九九久久这里只有精品 | 精品美女在线观看视频在线观看 | 国产免费又黄又爽又刺激蜜月al | 亚洲国产精品精华素 | 久久99精品久久久久久秒播九色 | 久久成人一区 | 亚洲狠狠 | 欧美亚洲视频在线观看 | 九九伦理电影 | 天天干视频 | 久久久91 | 日韩aⅴ在线观看 | 国产日韩一区二区 | 亚洲网站在线播放 | 亚洲免费在线观看 | 久久高清 | 久久久91| 国产精品久久久亚洲 | 欧美在线国产精品 | 亚洲国产精品一区二区三区 | 亚洲成人一区二区三区 | 黄色av网站免费看 | 一区二区三区在线观看视频 | 盗摄精品av一区二区三区 |