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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 11676|回復(fù): 7
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)仿真PCF8591數(shù)字電壓表(程序帶詳細(xì)注釋)電壓0-5V

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
在AT89C52系統(tǒng)中采用PCF8591芯片,測量0-5V范圍內(nèi)的直流電壓,并在2位數(shù)碼管上顯示電壓值。
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


注釋很全的單片機(jī)源程序如下:
  1. #include<reg52.h>    //包含單片機(jī)寄存器的頭文件
  2. #include <intrins.h>

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

  4. // 變量定義
  5. unsigned char AD_CHANNEL=0;
  6. unsigned char  D[32];

  7. sbit scl=P2^0;       //I2C  時鐘
  8. sbit sda=P2^1;       //I2C  數(shù)據(jù)
  9. bit ack;                 /*應(yīng)答標(biāo)志位*/

  10. unsigned char date;
  11. sbit C1=P2^6;//數(shù)碼管位選
  12. sbit C2=P2^7;//數(shù)碼管位選
  13. sbit Dp=P2^5;//小數(shù)點(diǎn)
  14. table[10]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};   //共陽極數(shù)碼管0~9顯示的數(shù)值表
  15. unsigned int data dis[3]={0x00,0x00,0x00};  //用以計(jì)算存儲輸出電壓的3元素?cái)?shù)組
  16. /*******************************************************************
  17.                      起動總線函數(shù)               
  18. 函數(shù)原型: void  Start_I2c();  
  19. 功能:     啟動I2C總線,即發(fā)送I2C起始條件.  
  20. ********************************************************************/
  21. void Start_I2c()
  22. {
  23.   sda=1;         /*發(fā)送起始條件的數(shù)據(jù)信號*/
  24.   _nop_();
  25.   scl=1;
  26.   _nop_();        /*起始條件建立時間大于4.7us,延時*/
  27.   _nop_();
  28.   _nop_();
  29.   _nop_();
  30.   _nop_();   
  31.   sda=0;         /*發(fā)送起始信號*/
  32.   _nop_();        /* 起始條件鎖定時間大于4μs*/
  33.   _nop_();
  34.   _nop_();
  35.   _nop_();
  36.   _nop_();      
  37.   scl=0;       /*鉗住I2C總線,準(zhǔn)備發(fā)送或接收數(shù)據(jù) */
  38.   _nop_();
  39.   _nop_();
  40. }

  41. /*******************************************************************
  42.                       結(jié)束總線函數(shù)               
  43. 函數(shù)原型: void  Stop_I2c();  
  44. 功能:     結(jié)束I2C總線,即發(fā)送I2C結(jié)束條件.  
  45. ********************************************************************/
  46. void Stop_I2c()
  47. {
  48.   sda=0;      /*發(fā)送結(jié)束條件的數(shù)據(jù)信號*/
  49.   _nop_();       /*發(fā)送結(jié)束條件的時鐘信號*/
  50.   scl=1;      /*結(jié)束條件建立時間大于4μs*/
  51.   _nop_();
  52.   _nop_();
  53.   _nop_();
  54.   _nop_();
  55.   _nop_();
  56.   sda=1;      /*發(fā)送I2C總線結(jié)束信號*/
  57.   _nop_();
  58.   _nop_();
  59.   _nop_();
  60.   _nop_();
  61. }

  62. /*******************************************************************
  63.                  字節(jié)數(shù)據(jù)發(fā)送函數(shù)               
  64. 函數(shù)原型: void  I2C_SendByte(UCHAR c);
  65. 功能:     將數(shù)據(jù)c發(fā)送出去,可以是地址,也可以是數(shù)據(jù),發(fā)完后等待應(yīng)答,并對
  66.           此狀態(tài)位進(jìn)行操作.(不應(yīng)答或非應(yīng)答都使ack=0)     
  67.            發(fā)送數(shù)據(jù)正常,ack=1; ack=0表示被控器無應(yīng)答或損壞。
  68. ********************************************************************/
  69. void  I2C_SendByte(unsigned char  c)
  70. {
  71. unsigned char  i;

  72. for(i=0;i<8;i++)  /*要傳送的數(shù)據(jù)長度為8位*/
  73.     {
  74.      if((c<<i)&0x80)sda=1;   /*判斷發(fā)送位*/
  75.        else  sda=0;               
  76.      _nop_();
  77.      scl=1;               /*置時鐘線為高,通知被控器開始接收數(shù)據(jù)位*/
  78.       _nop_();
  79.       _nop_();             /*保證時鐘高電平周期大于4μs*/
  80.       _nop_();
  81.       _nop_();
  82.       _nop_();         
  83.      scl=0;
  84.     }
  85.    
  86.     _nop_();
  87.     _nop_();
  88.     sda=1;                /*8位發(fā)送完后釋放數(shù)據(jù)線,準(zhǔn)備接收應(yīng)答位*/
  89.     _nop_();
  90.     _nop_();   
  91.     scl=1;
  92.     _nop_();
  93.     _nop_();
  94.     _nop_();
  95.     if(sda==1)ack=0;     
  96.        else ack=1;        /*判斷是否接收到應(yīng)答信號*/
  97.     scl=0;
  98.     _nop_();
  99.     _nop_();
  100. }

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

  133. /********************************************************************
  134.                      應(yīng)答子函數(shù)
  135. 函數(shù)原型:  void Ack_I2c(bit a);
  136. 功能:      主控器進(jìn)行應(yīng)答信號(可以是應(yīng)答或非應(yīng)答信號,由位參數(shù)a決定)
  137. ********************************************************************/
  138. void Ack_I2c(bit a)
  139. {  
  140.   if(a==0)sda=0;              /*在此發(fā)出應(yīng)答或非應(yīng)答信號 */
  141.   else sda=1;                                  /*0為發(fā)出應(yīng)答,1為非應(yīng)答信號 */
  142.   _nop_();
  143.   _nop_();
  144.   _nop_();      
  145.   scl=1;
  146.   _nop_();
  147.   _nop_();                    /*時鐘低電平周期大于4μs*/
  148.   _nop_();
  149.   _nop_();
  150.   _nop_();  
  151.   scl=0;                     /*清時鐘線,住I2C總線以便繼續(xù)接收*/
  152.   _nop_();
  153.   _nop_();   
  154. }

  155. /************************************************************
  156. * 函數(shù)名        : Pcf8591_DaConversion
  157. * 函數(shù)功能      : PCF8591的輸出端輸出模擬量
  158. * 輸入          : addr(器件地址),channel(轉(zhuǎn)換通道),value(轉(zhuǎn)換的數(shù)值)
  159. * 輸出                 : 無
  160. ******************* *****************************************/
  161. bit Pcf8591_DaConversion(unsigned char addr,unsigned char channel,  unsigned char Val)
  162. {
  163.    Start_I2c();              //啟動總線
  164.    I2C_SendByte(addr);            //發(fā)送器件地址
  165.    if(ack==0)return(0);
  166.    I2C_SendByte(0x40|channel);              //發(fā)送控制字節(jié)
  167.    if(ack==0)return(0);
  168.    I2C_SendByte(Val);            //發(fā)送DAC的數(shù)值  
  169.    if(ack==0)return(0);
  170.    Stop_I2c();               //結(jié)束總線
  171.    return(1);
  172. }

  173. /************************************************************
  174. * 函數(shù)名        : Pcf8591_SendByte
  175. * 函數(shù)功能                : 寫入一個控制命令
  176. * 輸入          : addr(器件地址),channel(轉(zhuǎn)換通道)
  177. * 輸出                 : 無
  178. ************************************************************/
  179. bit PCF8591_SendByte(unsigned char addr,unsigned char channel)
  180. {
  181.    Start_I2c();              //啟動總線
  182.    I2C_SendByte(addr);            //發(fā)送器件地址
  183.    if(ack==0)return(0);
  184.    I2C_SendByte(0x40|channel);              //發(fā)送控制字節(jié)
  185.    if(ack==0)return(0);
  186.    Stop_I2c();               //結(jié)束總線
  187.    return(1);
  188. }

  189. /************************************************************
  190. * 函數(shù)名               : PCF8591_RcvByte
  191. * 函數(shù)功能           : 讀取一個轉(zhuǎn)換值
  192. * 輸入          :
  193. * 輸出          : dat
  194. ************************************************************/
  195. unsigned char PCF8591_RcvByte(unsigned char addr)
  196. {  
  197.    unsigned char dat;

  198.    Start_I2c();          //啟動總線
  199.    I2C_SendByte(addr+1);      //發(fā)送器件地址
  200.    if(ack==0)return(0);
  201.    dat=I2C_RcvByte();          //讀取數(shù)據(jù)0

  202.    Ack_I2c(1);           //發(fā)送非應(yīng)答信號
  203.    Stop_I2c();           //結(jié)束總線
  204.    return(dat);
  205. }
  206. /*------------------------------------------------
  207.                  串口初始化函數(shù)
  208. ------------------------------------------------*/
  209. void init_com(void)
  210. {
  211. EA=1;        //開總中斷
  212. ES=1;        //允許串口中斷
  213. ET1=1;
  214. TMOD=0x22;   //定時器T1,在方式2中斷產(chǎn)生波特率
  215. PCON=0x00;   //SMOD=0
  216. SCON=0x50;   // 方式1 由定時器控制
  217. TH1=0xfd;    //波特率設(shè)置為9600
  218. TL1=0xfd;
  219. TR1=1;       //開定時器T1運(yùn)行控制位


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

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

所有資料51hei提供下載:
數(shù)字電壓表.zip (197.63 KB, 下載次數(shù): 279)


評分

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

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏5 分享淘帖 頂1 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:489559 發(fā)表于 2019-3-14 19:16 | 只看該作者
從串口中輸入的數(shù)據(jù)是電壓值嗎
回復(fù)

使用道具 舉報(bào)

板凳
ID:404722 發(fā)表于 2019-5-19 17:41 | 只看該作者
shawang 發(fā)表于 2019-3-14 19:16
從串口中輸入的數(shù)據(jù)是電壓值嗎

這里沒有使用串口,可以通過串口把數(shù)據(jù)發(fā)送出去
回復(fù)

使用道具 舉報(bào)

地板
ID:712432 發(fā)表于 2020-3-20 17:49 | 只看該作者
樓主就是測量不是有范圍嗎。超過范圍降壓設(shè)計(jì)以后怎么保證輸出值是降壓前的。還有測量出的是有效值嗎?
回復(fù)

使用道具 舉報(bào)

5#
ID:909477 發(fā)表于 2021-5-16 10:35 | 只看該作者
請問要顯示小數(shù)點(diǎn)后兩位該怎樣處理
回復(fù)

使用道具 舉報(bào)

6#
ID:992042 發(fā)表于 2021-12-18 21:03 | 只看該作者
樓主設(shè)計(jì)的太好了,學(xué)習(xí)到了很多。
回復(fù)

使用道具 舉報(bào)

7#
ID:1031469 發(fā)表于 2022-6-2 13:55 | 只看該作者
P1是什么器件在protus里怎么找的呀
回復(fù)

使用道具 舉報(bào)

8#
ID:236933 發(fā)表于 2024-4-5 11:31 | 只看該作者
代碼編譯之后,用這個仿真運(yùn)行數(shù)碼管無顯示
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 日韩中文字幕视频在线观看 | 一区二区三区精品视频 | 久久免费观看视频 | 看a级黄色毛片 | 亚洲va欧美va天堂v国产综合 | 国产免费一区 | 午夜小视频免费观看 | 在线观看av网站永久 | 亚洲一区二区三区四区在线观看 | 在线观看免费av网 | 亚洲播放 | 蜜桃在线播放 | 日本精品视频在线观看 | 国产欧美日韩精品一区 | 日韩中文字幕av | 国产成人午夜精品影院游乐网 | 91久色| 91一区二区 | 亚洲永久字幕 | 一区二区视频在线观看 | 在线观看av网站永久 | 久久伊人亚洲 | 久久久www成人免费精品张筱雨 | 黄频视频 | 在线免费观看毛片 | 亚洲成网站 | 浴室洗澡偷拍一区二区 | 一区二区视频在线 | 一区二区av在线 | 91中文字幕在线观看 | 天天干天天操天天射 | 国产亚洲精品久久久久久牛牛 | 精品国产一区二区三区免费 | 999久久精品 | 午夜精品久久久久久久 | 久久精品二区亚洲w码 | 久久精品国产精品青草 | 老司机久久 | 做a的各种视频 | 久久久久成人精品亚洲国产 | 免费成人av网站 |