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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 9728|回復: 4
收起左側

單片機+PCF8591實現數字電壓表的仿真+代碼

  [復制鏈接]
ID:460629 發表于 2019-1-3 14:51 | 顯示全部樓層 |閱讀模式
制作數字電壓表(2學時)

一、實驗目的:

1. 了解I2C串行總線工作原理及通信協議

2. 了解ADC0804、DAC0832、PCF8591與AT89S51的接口設計

3. 掌握ADC0804、DAC0832、PCF8591的編程方法

4. 能夠熟練運用數模轉換模塊

二、實驗要求:

1. 數字電壓表:在AT89C52系統中采用PCF8591芯片,測量0-5V范圍內的直流電壓,并在2位數碼管上顯示電壓值。

三、實驗設備:(PROTEUS元件表)


四、實驗報告:

1.描述實驗過程(重要步驟用屏幕截圖表示)。

2.給出在PROTEUS中設計的單片機系統電路圖

3.畫出程序流程圖

4.給出在KEIL中編寫的源程序。

5.描述在proteus中仿真運行程序的實驗現象

五、實驗總結


單片機源程序如下:


  1. /**********************BST-M51實驗開發板例程************************
  2. *  平臺:BST-M51 + Keil U4 + STC89C52
  3. *  名稱:AD串口讀取實驗
  4. *  公司:深圳市亞博軟件開發有限公司      
  5. *  日期:2015-6
  6. *  晶振:11.0592MHZ
  7. ******************************************************************/
  8. #include<reg52.h>    //包含單片機寄存器的頭文件
  9. #include <intrins.h>

  10. #define  AddWr 0x90    //PCF8591 地址

  11. // 變量定義
  12. unsigned char AD_CHANNEL=0;
  13. unsigned char  D[32];
  14. unsigned char code table[10]={0xC0,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};   //共陽極數碼管0~9顯示的數值表
  15. unsigned int data dis[3]={0x00,0x00,0x00};  //用以計算存儲輸出電壓的3元素數組

  16. sbit scl=P2^0;       //I2C  時鐘
  17. sbit sda=P2^1;       //I2C  數據
  18. bit ack;                 /*應答標志位*/
  19. sbit C1=P2^6;//數碼管位選
  20. sbit C2=P2^7;//數碼管位選
  21. sbit Dp=P2^5;//小數點

  22. unsigned char date;

  23. /*******************************************************************
  24.                      起動總線函數              
  25. 函數原型: void  Start_I2c();
  26. 功能:     啟動I2C總線,即發送I2C起始條件.
  27. ********************************************************************/
  28. void Start_I2c()
  29. {
  30.   sda=1;         /*發送起始條件的數據信號*/
  31.   _nop_();
  32.   scl=1;
  33.   _nop_();        /*起始條件建立時間大于4.7us,延時*/
  34.   _nop_();
  35.   _nop_();
  36.   _nop_();
  37.   _nop_();   
  38.   sda=0;         /*發送起始信號*/
  39.   _nop_();        /* 起始條件鎖定時間大于4μs*/
  40.   _nop_();
  41.   _nop_();
  42.   _nop_();
  43.   _nop_();      
  44.   scl=0;       /*鉗住I2C總線,準備發送或接收數據 */
  45.   _nop_();
  46.   _nop_();
  47. }

  48. /*******************************************************************
  49.                       結束總線函數              
  50. 函數原型: void  Stop_I2c();
  51. 功能:     結束I2C總線,即發送I2C結束條件.
  52. ********************************************************************/
  53. void Stop_I2c()
  54. {
  55.   sda=0;      /*發送結束條件的數據信號*/
  56.   _nop_();       /*發送結束條件的時鐘信號*/
  57.   scl=1;      /*結束條件建立時間大于4μs*/
  58.   _nop_();
  59.   _nop_();
  60.   _nop_();
  61.   _nop_();
  62.   _nop_();
  63.   sda=1;      /*發送I2C總線結束信號*/
  64.   _nop_();
  65.   _nop_();
  66.   _nop_();
  67.   _nop_();
  68. }

  69. /*******************************************************************
  70.                  字節數據發送函數              
  71. 函數原型: void  I2C_SendByte(UCHAR c);
  72. 功能:     將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
  73.           此狀態位進行操作.(不應答或非應答都使ack=0)   
  74.            發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
  75. ********************************************************************/
  76. void  I2C_SendByte(unsigned char  c)
  77. {
  78. unsigned char  i;

  79. for(i=0;i<8;i++)  /*要傳送的數據長度為8位*/
  80.     {
  81.      if((c<<i)&0x80)sda=1;   /*判斷發送位*/
  82.        else  sda=0;               
  83.      _nop_();
  84.      scl=1;               /*置時鐘線為高,通知被控器開始接收數據位*/
  85.       _nop_();
  86.       _nop_();             /*保證時鐘高電平周期大于4μs*/
  87.       _nop_();
  88.       _nop_();
  89.       _nop_();        
  90.      scl=0;
  91.     }

  92.     _nop_();
  93.     _nop_();
  94.     sda=1;                /*8位發送完后釋放數據線,準備接收應答位*/
  95.     _nop_();
  96.     _nop_();  
  97.     scl=1;
  98.     _nop_();
  99.     _nop_();
  100.     _nop_();
  101.     if(sda==1)ack=0;   
  102.        else ack=1;        /*判斷是否接收到應答信號*/
  103.     scl=0;
  104.     _nop_();
  105.     _nop_();
  106. }

  107. /*******************************************************************
  108.                  字節數據接收函數              
  109. 函數原型: UCHAR  I2C_RcvByte();
  110. 功能:        用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
  111.           發完后請用應答函數應答從機。
  112. ********************************************************************/   
  113. unsigned char   I2C_RcvByte()
  114. {
  115.   unsigned char  retc=0,i;
  116.   sda=1;                     /*置數據線為輸入方式*/
  117.   for(i=0;i<8;i++)
  118.       {
  119.         _nop_();         
  120.         scl=0;                  /*置時鐘線為低,準備接收數據位*/
  121.         _nop_();
  122.         _nop_();                 /*時鐘低電平周期大于4.7μs*/
  123.         _nop_();
  124.         _nop_();
  125.         _nop_();
  126.         scl=1;                  /*置時鐘線為高使數據線上數據有效*/
  127.         _nop_();
  128.         _nop_();
  129.         retc=retc<<1;
  130.         if(sda==1)retc=retc+1;  /*讀數據位,接收的數據位放入retc中 */
  131.         _nop_();
  132.         _nop_();
  133.       }
  134.   scl=0;   
  135.   _nop_();
  136.   _nop_();
  137.   return(retc);
  138. }

  139. /********************************************************************
  140.                      應答子函數
  141. 函數原型:  void Ack_I2c(bit a);
  142. 功能:      主控器進行應答信號(可以是應答或非應答信號,由位參數a決定)
  143. ********************************************************************/
  144. void Ack_I2c(bit a)
  145. {
  146.   if(a==0)sda=0;              /*在此發出應答或非應答信號 */
  147.   else sda=1;                                                          /*0為發出應答,1為非應答信號 */
  148.   _nop_();
  149.   _nop_();
  150.   _nop_();     
  151.   scl=1;
  152.   _nop_();
  153.   _nop_();                    /*時鐘低電平周期大于4μs*/
  154.   _nop_();
  155.   _nop_();
  156.   _nop_();
  157.   scl=0;                     /*清時鐘線,住I2C總線以便繼續接收*/
  158.   _nop_();
  159.   _nop_();   
  160. }

  161. /************************************************************
  162. * 函數名        : Pcf8591_DaConversion
  163. * 函數功能      : PCF8591的輸出端輸出模擬量
  164. * 輸入          : addr(器件地址),channel(轉換通道),value(轉換的數值)
  165. * 輸出                       : 無
  166. ******************* *****************************************/
  167. bit Pcf8591_DaConversion(unsigned char addr,unsigned char channel,  unsigned char Val)
  168. {
  169.    Start_I2c();              //啟動總線
  170.    I2C_SendByte(addr);            //發送器件地址
  171.    if(ack==0)return(0);
  172.    I2C_SendByte(0x40|channel);              //發送控制字節
  173.    if(ack==0)return(0);
  174.    I2C_SendByte(Val);            //發送DAC的數值
  175.    if(ack==0)return(0);
  176.    Stop_I2c();               //結束總線
  177.    return(1);
  178. }

  179. /************************************************************
  180. * 函數名        : Pcf8591_SendByte
  181. * 函數功能                            : 寫入一個控制命令
  182. * 輸入          : addr(器件地址),channel(轉換通道)
  183. * 輸出                       : 無
  184. ************************************************************/
  185. bit PCF8591_SendByte(unsigned char addr,unsigned char channel)
  186. {
  187.    Start_I2c();              //啟動總線
  188.    I2C_SendByte(addr);            //發送器件地址
  189.    if(ack==0)return(0);
  190.    I2C_SendByte(0x40|channel);              //發送控制字節
  191.    if(ack==0)return(0);
  192.    Stop_I2c();               //結束總線
  193.    return(1);
  194. }

  195. /************************************************************
  196. * 函數名                     : PCF8591_RcvByte
  197. * 函數功能                 : 讀取一個轉換值
  198. * 輸入          :
  199. * 輸出          : dat
  200. ************************************************************/
  201. unsigned char PCF8591_RcvByte(unsigned char addr)
  202. {
  203.    unsigned char dat;

  204.    Start_I2c();          //啟動總線
  205.    I2C_SendByte(addr+1);      //發送器件地址
  206.    if(ack==0)return(0);
  207.    dat=I2C_RcvByte();          //讀取數據0

  208.    Ack_I2c(1);           //發送非應答信號
  209.    Stop_I2c();           //結束總線
  210.    return(dat);
  211. }
  212. /*------------------------------------------------
  213.                  串口初始化函數
  214. ------------------------------------------------*/
  215. void init_com(void)
  216. {
  217. EA=1;        //開總中斷
  218. ES=1;        //允許串口中斷
  219. ET1=1;        //允許定時器T1的中斷
  220. TMOD=0x20;   //定時器T1,在方式2中斷產生波特率
  221. PCON=0x00;   //SMOD=0
  222. SCON=0x50;   // 方式1 由定時器控制
  223. TH1=0xfd;    //波特率設置為9600
  224. TL1=0xfd;
  225. TR1=1;       //開定時器T1運行控制位

  226. }
  227. /*------------------------------------------------
  228.                   延時函數
  229. ------------------------------------------------*/
  230. void delay(unsigned char i)
  231. {
  232.   unsigned char j,k;
  233.   for(j=i;j>0;j--)
  234.     for(k=125;k>0;k--);
  235. }
  236. /*------------------------------------------------
  237. 把讀取值轉換成一個一個的字符,給串口顯示
  238. ------------------------------------------------*/
  239. void To_ascii(unsigned char num)
  240. {            
  241.               SBUF=num/100+'0';                                               
  242.               delay(200);                             
  243.               SBUF=num/10%10+'0';                                            
  244.               delay(200);            
  245.               SBUF=num%10+'0';
  246.               delay(200);
  247. }
  248. /*------------------------------------------------
  249.                     主函數
  250. ------------------------------------------------*/
  251. main()
  252. {

  253.               init_com();
  254.               while(1)
  255.               {
  256.               /********以下AD-DA處理*************/
  257.               PCF8591_SendByte(AddWr,0);              //啟動轉換
  258.               D[0]=PCF8591_RcvByte(AddWr);  //讀轉換完的數字信號,ADC0 模數轉換1      光敏電阻            
  259.               /********以下將AD的值通過串口發送出去*************/
  260.               dis[1]=D[0]/51;   //每刻度值為5/256V,所以電壓值為輸出的8位數字值*5/256V,計算輸出電壓的整數值
  261.               dis[2]=D[0]%51;   //dis[2]位中間暫存數據位
  262.               dis[2]=dis[2]*10;   
  263.               dis[0]=dis[2]/51;    //計算輸出電壓的小數值            
  264.             
  265.               C1=0;                //關閉第二位數碼管
  266.               C2=1;                //打開第一位數碼管
  267.                  Dp=1;                //打開小數點
  268.               P1=table[dis[0]];    //顯示整數部分及小數點
  269.               delay(10);           //延時一定時間
  270.                                          
  271.      C2=0;                //關閉第一位數碼管
  272.               C1=1;                //打開第二位數碼管
  273.               Dp=0;                //關閉小數點
  274.               P1=table[dis[1]];     //顯示小數部分
  275.             
  276.               /*delay(200);            
  277.               To_ascii(D[0]);
  278.               SBUF='\n';
  279.               delay(200);
  280.               if(RI)
  281.               {
  282.                             date=SBUF;    //單片機接受
  283.                             SBUF=date;    //單片機發送
  284.                             RI=0;
  285.               }*/            
  286.    }
  287. }
復制代碼
0.png

所有資料51hei提供下載:

實驗九制作數字電壓表.rar (419.46 KB, 下載次數: 209)

評分

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

查看全部評分

回復

使用道具 舉報

ID:362692 發表于 2020-1-3 15:10 來自手機 | 顯示全部樓層
程序還不錯,借鑒的一部分
回復

使用道具 舉報

ID:743707 發表于 2020-5-4 16:02 來自手機 | 顯示全部樓層
這個圖可以有清楚的嗎
回復

使用道具 舉報

ID:782630 發表于 2020-6-17 22:24 | 顯示全部樓層
正在學,感謝分享
回復

使用道具 舉報

ID:585455 發表于 2020-9-13 15:33 | 顯示全部樓層
正在學習pcf8591;很棒的資料。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 午夜精品在线观看 | 成人免费在线观看视频 | 国产偷录视频叫床高潮对白 | 黄色日本视频 | 日韩一区二区在线看 | 四虎影院在线免费观看 | 久久一区二区三区四区 | 亚洲欧美日韩精品久久亚洲区 | 国产99精品 | 天天干天天草 | 日日操夜夜操天天操 | 亚洲在线一区二区 | 91热爆在线观看 | 亚洲视频精品 | 国产精品福利久久久 | 在线视频一区二区三区 | 91精品国模一区二区三区 | 性色的免费视频 | 岛国精品 | 国产ts人妖一区二区三区 | 欧美黄色一区 | 欧美在线国产精品 | 中文字字幕一区二区三区四区五区 | 国产免费观看久久黄av片涩av | 日韩在线国产 | 影音av | 91色在线 | 精品日韩一区二区 | 九九伊人sl水蜜桃色推荐 | 黄色成人在线网站 | 一区二区电影网 | 国产精品 欧美精品 | 欧美一级免费 | 亚洲一级毛片 | 亚洲国产高清高潮精品美女 | 亚洲欧美日韩精品久久亚洲区 | 在线免费观看毛片 | 夜夜摸夜夜操 | 亚洲国产精品一区二区三区 | 国产免费福利小视频 | 亚洲国产视频一区 |