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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 148846|回復: 55
收起左側

學51單片機-基于PCF8591的AD采樣和DA輸出

  [復制鏈接]
ID:74835 發表于 2015-4-8 22:48 | 顯示全部樓層 |閱讀模式
      
      首先思考一個問題,我們的世界是數字的還是模擬的?
      當然是模擬的了,所有的量都是在一定范圍內連續變化的。我們為了能夠更加方便的描述這些量,對它們進行了數字化。而數字量就不一樣了,它是分立的的幾個值。
      舉個例子,我們形容一個人的身高,模擬的說法是一米七到一米七五之間,數字的說法就是一米七三。
接下來說AD轉換器,它的出現也是為了讓我們能更方便、更直接的描述電壓的高低。AD轉換器,英文全稱為Analog-to-Digital Converter,是模擬量到數字量的一個轉換過程,主要用于電壓的采集。它的出現就如同有了一把尺子,很容易就能量出電壓的高低。
在電子設備中,經常要檢測各種模擬量:溫度、壓力、速度、流量、重力加速度等等,這些模擬量都被相應的傳感器轉換為電壓信號,我們只需要測量電壓的高低,就能得到相應參數。
AD的主要參數有哪些?
1、AD的位數:表明這個AD共有2^n個刻度,8位AD,輸出的刻度是0~255.
2、分辨率:就是AD能夠分辨的最小的模擬量變化,假設5.10V的系統用8位的AD采樣,那么它能分辨的最小電壓就是5.10/255=0.02V。
3、INL:Interger NONliner 積分非線性度,表示了ADC器件在所有的數值點上對應的模擬值,和真實值之間誤差最大的那一點的誤差值。也就是,輸出數值偏離線性最大的距離。單位是LSB(即最低位所表示的量)。比如12位ADC:TLC2543,INL值為1LSB。那么,如果基準4.095V,測某電壓得的轉換結果是1000,那么,真實電壓值可能分布在0.999~1.001V之間。
4、DNL:Differencial NonLiner-差分非線性度,理論上說,模數器件相鄰量個數據之間,模擬量的差值都是一樣的。就相一把疏密均勻的尺子。但實際并不如此。一把分辨率1毫米的尺子,相鄰兩刻度之間也不可能都是1毫米整。那么,ADC相鄰兩刻度之間最大的差異就叫差分非線性值(Differencial NonLiner)。DNL值如果大于1,那么這個ADC甚至不能保證是單調的,輸入電壓增大,在某個點數值反而會減小。這種現象在SAR(逐位比較)型ADC中很常見。
5、基準源:有內部基準源、外部基準源等等。
6、轉換速率:也就是轉換周期的倒數,轉換周期就是完成一次AD轉換所需的時間。
今天要用到的器件是PCF8591,為什么選它?太多的開發板上用它做演示了,而且還是IIC總線通信的。既學習了AD采樣,又學習了IIC總線。
先上應用電路:
      如上圖所示,PCF8591的9腳和10腳,一個是數據線SDA,一個是時鐘線SCL。分別接到單片機的P2.0 , P2.1上面。
為什么選這兩個引腳?因為51單片機上沒有IIC總線接口,需要用普通的IO模擬,所以它隨便選了兩個IO接上就行。
VREF是什么?基準電壓,也是它能測量的最大電壓。
如何控制?今天先不說IIC總線,只說控制流程。
看器件手冊可以知道:
分四步:
1、發送地址字節,選擇該器件。
2、發送控制字節,選擇相應通道。               //
3、重新發送地址字節,選擇該器件。
4、接收目標通道的數據。
這次的程序流程是:AD采樣,串口發送,循環執行。
下面是AD采樣源代碼:
  1. /**********************51單片機學習例程************************
  2. *  平臺:Keil U4 + STC89C52
  3. *  名稱:AD采樣+串口發送
  4. *  編寫:起航
  5. *  晶體:11.0592MHZ
  6. ******************************************************************/
  7. #include <reg52.h>
  8. #include <intrins.h>

  9. typedef unsigned char uint8;
  10. typedef unsigned int uint16;

  11. #define SLAVEADDR  0x90                 //定義器件地址
  12. #define nops()  do{_nop_();_nop_();_nop_();_nop_();_nop_();} while(0) //定義空指令


  13. sbit SCL = P2^1;       //I2C  時鐘
  14. sbit SDA = P2^0;       //I2C  數據

  15. void delay(uint16 n)
  16. {
  17.         while (n--);
  18. }
  19. /**
  20. * 函數: i2c_start()
  21. * 功能: 啟動i2c                  起始信號
  22. */
  23. void i2c_start()
  24. {
  25.         SCL = 1;
  26.         nops();
  27.         SDA = 1;
  28.         nops();
  29.         SDA = 0;
  30.         nops();
  31.         SCL = 0;
  32. }

  33. /**
  34. * 函數: i2c_stop()
  35. * 功能: 停止i2c
  36. */
  37. void i2c_stop()
  38. {
  39.         SCL = 0;
  40.         nops();
  41.         SDA = 0;
  42.         nops();
  43.         SCL = 1;
  44.         nops();
  45.         SDA = 1;
  46.         nops();
  47. }

  48. /**
  49. * 函數: i2c_ACK(bit ck)
  50. * 功能: ck為1時發送應答信號ACK,
  51. *       ck為0時不發送ACK
  52. */
  53. void i2c_ACK(bit ck)
  54. {
  55.     if (ck)
  56.                 SDA = 0;
  57.     else
  58.                 SDA = 1;
  59.     nops();
  60.     SCL = 1;
  61.     nops();
  62.     SCL = 0;
  63.         nops();
  64.     SDA = 1;
  65.     nops();
  66. }

  67. /**
  68. * 函數: i2c_waitACK()
  69. * 功能: 返回為0時收到ACK
  70. *       返回為1時沒收到ACK
  71. */
  72. bit i2c_waitACK()
  73. {
  74.         SDA = 1;
  75.         nops();
  76.         SCL = 1;
  77.         nops();
  78.         if (SDA)
  79.         {   
  80.                 SCL = 0;
  81.                 i2c_stop();
  82.                 return 1;
  83.         }
  84.         else
  85.         {  
  86.                 SCL = 0;
  87.                 return 0;
  88.         }
  89. }

  90. /**
  91. * 函數: i2c_sendbyte(uint8 bt)
  92. * 功能: 將輸入的一字節數據bt發送
  93. */
  94. void i2c_sendbyte(uint8 bt)
  95. {
  96.     uint8 i;
  97.    
  98.     for(i=0; i<8; i++)
  99.     {  
  100.         if (bt & 0x80)
  101.                         SDA = 1;
  102.         else
  103.                         SDA = 0;
  104.         nops();
  105.         SCL = 1;
  106.         bt <<= 1;
  107.         nops();      
  108.         SCL = 0;
  109.     }
  110. }

  111. /**
  112. * 函數: i2c_recbyte( )
  113. * 功能: 從總線上接收1字節數據
  114. */
  115. uint8 i2c_recbyte()
  116. {
  117.         uint8 dee, i;
  118.        
  119.         for (i=0; i<8; i++)
  120.         {
  121.                 SCL = 1;   
  122.                 nops();
  123.                 dee <<= 1;
  124.                 if (SDA)
  125.                         dee = dee | 0x01;
  126.                 SCL = 0;
  127.                 nops();
  128.         }
  129.        
  130.         return dee;
  131. }

  132. /**
  133. * 函數: i2c_readbyte
  134. * 輸入: addr
  135. * 功能: 讀出一字節數據
  136. * 返回值: 0->成功  1->失敗
  137. */
  138. bit i2c_readbyte(uint8 com, uint8 *dat)
  139. {       
  140.         i2c_start();
  141.         i2c_sendbyte(SLAVEADDR);    //地址
  142.     if (i2c_waitACK())
  143.                 return 1;
  144.         i2c_sendbyte(com);        //控制字節
  145.     if (i2c_waitACK())
  146.                 return 1;
  147.         i2c_start();
  148.         i2c_sendbyte(SLAVEADDR+1); //地址
  149.     if (i2c_waitACK())
  150.                 return 1;
  151.         *dat = i2c_recbyte();      //讀數據
  152.         i2c_ACK(0);                //因為只讀一字節數據,不發送ACK信號
  153.         i2c_stop();   
  154.        
  155.         return 0;
  156. }

  157. /**
  158. * UART初始化
  159. * 波特率:9600
  160. */
  161. void uart_init(void)
  162. {
  163.     ET1=0;
  164.     TMOD = 0x21;        // 定時器1工作在方式2(自動重裝)
  165.     SCON = 0x50;        // 10位uart,允許串行接受

  166.     TH1 = 0xFD;
  167.     TL1 = 0xFD;

  168.     TR1 = 1;
  169. }

  170. /**
  171. * UART 發送一字節
  172. */
  173. void UART_Send_Byte(uint8 dat)
  174. {
  175.         SBUF = dat;
  176.         while (TI == 0);
  177.         TI = 0;
  178. }


  179. main()
  180. {
  181.         uint8 ans;

  182.         uart_init();

  183.         while(1)
  184.         {

  185.                 i2c_readbyte(0x43, &ans);
  186.             
  187.                 UART_Send_Byte(ans);
  188.                 delay(50000);
  189.         }
  190. }
復制代碼
本程序下載鏈接(附帶PCF8591中文資料pdf資料): PCF8591AD采樣.rar (459.16 KB, 下載次數: 948)

評分

參與人數 3黑幣 +15 收起 理由
愛拉屎 + 5 絕世好帖!
勇猛的大表哥 + 5 共享資料的黑幣獎勵!
vancee + 5 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区天堂 | 九九热这里| 日日摸天天添天天添破 | 久草福利| 精品久久久久久 | 国产精品揄拍一区二区 | 国产精品久久久久久久久久久久 | 国产精品久久久久久久久久久久久 | 午夜精品一区二区三区在线观看 | 久久99视频这里只有精品 | 日韩精品一区二区三区在线播放 | 色视频免费 | 久久九九99 | 成人在线精品视频 | 国产精品a久久久久 | 99久久国产免费 | 国产成人综合网 | 久久免费精品 | 91 久久 | 另类专区亚洲 | 干干天天| 国产精品一区二区三区99 | 精品久久久久久久久久久久久久 | 亚洲成网站| 久久久91精品国产一区二区三区 | 精品国产1区2区3区 一区二区手机在线 | 成人av电影在线 | 亚洲精品久久久9婷婷中文字幕 | 欧美日韩三级在线观看 | 中国一级特黄毛片大片 | 亚洲一区二区三区在线播放 | 精品九九在线 | 成人免费淫片aa视频免费 | 成人黄色在线视频 | 欧美精品一区二区三区在线播放 | 日韩国产欧美一区 | 亚洲精品久久久久久久久久吃药 | 色婷婷国产精品 | caoporn免费| 国产成人午夜精品影院游乐网 | 特黄色一级毛片 |