找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11980|回復: 0
收起左側

51單片機數(shù)碼管顯示學號程序+Proteus仿真電路圖

[復制鏈接]
ID:507059 發(fā)表于 2019-4-8 15:41 | 顯示全部樓層 |閱讀模式
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
0.png 0.png

單片機源程序如下:
  1. #include <reg52.h>
  2. sbit hang1=P2^0;
  3. sbit hang2=P2^1;
  4. sbit lie1=P2^2;
  5. sbit lie2=P2^3;
  6. sbit buzzer=P2^7;                                //蜂鳴器

  7. //與ADC相關的位聲明
  8. sbit ADC_START=P3^4;                        //轉換啟動信號,高脈沖啟動轉換
  9. sbit ADC_EOC=P3^2;                                //轉換結束信號,高電平轉換結束
  10. sbit ADC_A=P3^5;
  11. sbit ADC_B=P3^6;
  12. sbit ADC_C=P3^7;
  13. unsigned char code table[]={0x03,0x9f,0x25,0x0d,
  14.                             0x99,0x49,0x41,0x1f,
  15.                             0x01,0x09,0x11,0xc1,
  16.                             0xe5,0x85,0x21,0x71,0xff};


  17. void sendstr(unsigned char);         //串口發(fā)送數(shù)字顯示
  18. void delay(unsigned char );                 //延時函數(shù)
  19. void desplay();                                        //移動顯示學號函數(shù)
  20. void keyscan();                                        //鍵盤掃描函數(shù)
  21. void desplay_key_number();
  22. void Get_ADC(void);        //ADC轉換函數(shù)

  23. unsigned char b=0,i,counter=4,Time=0,flag=0,INT;
  24. float ADC_V;        //AD轉換的電壓值       
  25. int main()
  26. {

  27.         /*主程序初始化部分*/

  28.         EA=1;                //開總中斷
  29.         SCON=0x00;          //串口初始化 ,工作方式0
  30.         EX1=1;                //開外部中斷1
  31.         IT1=1;                //外部中斷1電平觸發(fā)
  32.         ET0=1;                //開啟定時器0中斷
  33.         ET1=1;                //開啟定時器1中斷
  34.         TMOD=0X11;        //定時器0工作方式1,定時器1工作方式1
  35.         TH0=(65536-50000)/256;
  36.         TL0=(65536-50000)%256;
  37.         TH1=(65536-500)/256;
  38.         TL1=(65536-500)%256;                               
  39.         hang1=hang2=0;
  40.         ADC_A=ADC_B=ADC_C=0;                //選擇ADC轉換通道0

  41.    


  42.         desplay();        //上電顯示學號
  43.         while(1)
  44.         {
  45.                
  46.                 if(INT)                                                        //INT=1表示進入外部中斷1,則可以進行鍵盤掃描
  47.                 {
  48.                         keyscan();                                        //掃描得到鍵值
  49.                         TR0=0;                                                //關閉定時器0,判斷此時按鍵按下的時間
  50.                         INT=0;
  51.                         EX1=1;                                           //開外部中斷1
  52.                 }
  53.                 if(counter!=4)
  54.                 {
  55.                                                                
  56.                         if(flag)                                 //到2.5秒執(zhí)行
  57.                         {
  58.                                  switch (counter)
  59.                                 {
  60.                                         case 0:                                                                          //DA功能鍵,即梯形波
  61.                                                         TR1=1;                                                          //啟動定時器1產生波形
  62.                                                         break;
  63.                                         case 1:                                                                           //學號顯示鍵
  64.                                
  65.                                                         desplay();        //顯示學號        delay(100);
  66.                                                         break;
  67.                                         case 2:
  68.                                
  69.                                                        
  70.                                                         break;
  71.                                         case 3:                                                                          //AD功能鍵

  72.                                                         for(i=0;i<8;i++)
  73.                                                                 {
  74.                                                                         sendstr(16);                          //將所有數(shù)碼管清滅
  75.                                                                 }
  76.                                                         Get_ADC();
  77.                                                         SBUF=table[(int)(ADC_V)]&0xfe;          //與小數(shù)點一同顯示
  78.                                                         while(!TI);
  79.                                                         TI=0;
  80.                                                         sendstr((int)(ADC_V*10)%10);
  81.                                                         sendstr((int)(ADC_V*100)%100%10);
  82.                                                         break;
  83.                                         default:
  84.                                                         break;
  85.                                 }
  86.                                 flag=0;                                  //在此將flag清零,而不在中斷中清零
  87.                         }
  88.                         else                                         //未到2.5秒執(zhí)行
  89.                         {
  90.                                
  91.                                         desplay_key_number();
  92.                                                                
  93.                         }
  94.                         counter=4;
  95.                 }
  96.         }
  97.        
  98. }




  99. void INT_1() interrupt 2                 //外部中斷1函數(shù)
  100. {
  101.         TR0=1;                                                 //啟動定時器0
  102.         TR1=0;                                                 //關閉定時器1,以免與定時器0沖突
  103.         Time=0;                                                 //不能在此將flag清零,放下按鍵也會產生抖動,
  104.                                                                 //此時進入中斷將flag清零就錯了,反應不了真實情況
  105.         buzzer=0;
  106.         delay(1);
  107.         buzzer=1;
  108.        
  109.         IE1=0;                                                //軟件清零中斷標志
  110.         EX1=0;                                                //關外部中斷1,等待鍵盤掃描結束再重新打開
  111.         INT=1;                                                //進入中斷標志位
  112. }

  113. void timer_0()        interrupt 1                //定時器0中斷服務函數(shù),用于判斷2.5秒鐘時間是否已到
  114. {
  115.         TH0=(65536-50000)/256;
  116.         TL0=(65536-50000)%256;                                              
  117.         Time++;
  118.         if(Time==50)
  119.                 {
  120.                         flag=1;                         //標志位置1
  121.                         /*蜂鳴器叫兩聲提示時間到*/
  122.                         buzzer=0;
  123.                         delay(1);
  124.                         buzzer=1;
  125.                         delay(1);
  126.                         buzzer=0;
  127.                         delay(1);
  128.                         buzzer=1;
  129.                 }                                               
  130. }

  131. void timer_1()        interrupt 3                  //矩形波發(fā)生中斷函數(shù)
  132. {
  133.         TH1=(65536-500)/256;
  134.         TL1=(65536-500)%256;
  135.         TR0=0;                                                  //關閉定時器0,以免沖突
  136.         switch(b)
  137.         {
  138.                 case 0:
  139.                            P0=0x00;
  140.                            for(i=0;i<51;i++)
  141.                                 {
  142.                                         P0+=5;
  143.                                         ;;;;;;;;;;;;;;;;;;;                         //多個分號,用于延時
  144.                                 }
  145.                            b++;
  146.                            break;
  147.                 case 1:
  148.                            b++;
  149.                            break;
  150.                 case 2:
  151.                            for(i=0;i<51;i++)
  152.                                 {
  153.                                         P0-=5;
  154.                                         ;;;;;;;;;;;;;;;;;;;                         //多個分號,用于延時
  155.                                 }
  156.                                 b++;
  157.                            break;
  158.                 case 3:
  159.                            b=0;
  160.                            break;
  161.                 default:
  162.                                 break;
  163.         }
  164.        
  165. }



  166. void sendstr(unsigned char i) //串口發(fā)送數(shù)字顯示
  167. {
  168.                 SBUF=table[i];
  169.                 while(!TI);
  170.                 TI=0;       
  171. }

  172. void keyscan()                                  //鍵盤掃描函數(shù)
  173. {

  174. //掃描第一行
  175.         hang1=0;
  176.         hang2=1;
  177.         if(lie1==0)
  178.                 {        delay(1);                        //消抖動
  179.                         while(!lie1);
  180.                         counter=0;
  181.                 }
  182.         if(lie2==0)
  183.                 {        delay(1);                        //消抖動
  184.                         while(!lie2);
  185.                         counter=1;
  186.                 }

  187. //掃描第二行
  188.         hang1=1;
  189.         hang2=0;
  190.         if(lie1==0)
  191.                 {        delay(1);                        //消抖動
  192.                         while(!lie1);
  193.                         counter=2;
  194.                 }
  195.         if(lie2==0)
  196.                 {        delay(1);                        //消抖動
  197.                         while(!lie2);
  198.                         counter=3;
  199.                 }

  200.         hang1=hang2=0;                                //出程序拉低按鍵行號
  201. }



  202. void desplay_key_number()                //顯示按鍵值號函數(shù)
  203. {
  204.         unsigned char num;
  205.         for(num=0;num<8;num++)
  206.         {
  207.                 sendstr(counter);
  208.         }
  209. }



  210. void Get_ADC()        //ADC轉換函數(shù)
  211. {
  212.         unsigned char ADC;
  213.         ADC_START=0;           ADC_START=1;         ADC_START=0;                                         //高脈沖啟動轉換       
  214.         while(ADC_EOC==0);                        //等待轉換結束
  215.         ADC=P1;
  216.         ADC_V=(float)(ADC)/255*5;
  217. }





  218. void delay(unsigned char h)                //延時函數(shù)
  219. {
  220.         unsigned char j;
  221.         for(j=0;j<100;j++)
  222.         {
  223.                 while(h--);
  224.         }
  225. }

  226. void desplay()                           //移動顯示學號函數(shù)
  227. {
  228.         unsigned char i;
  229.         for(i=0;i<8;i++)
  230.         {
  231.         sendstr(16);
  232.         }
  233.         i=250;
  234.         sendstr(0);
  235.         delay(i);
  236.         sendstr(1);
  237.         delay(i);
  238.         sendstr(1);
  239.         delay(i);
  240.         sendstr(1);
  241.         delay(i);
  242.         sendstr(0);
  243.         delay(i);
  244.         sendstr(1);
  245.         delay(i);
  246.         sendstr(5);
  247.         delay(i);
  248.         sendstr(0);
  249.         delay(i);               
  250. }
復制代碼

所有資料51hei提供下載:
51單片機數(shù)碼管顯示學號.rar (47.04 KB, 下載次數(shù): 34)


評分

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

查看全部評分

回復

使用道具 舉報

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

本版積分規(guī)則

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

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表