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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 39400|回復: 78
打印 上一主題 下一主題
收起左側

51單片機用PCF8591做個簡易電壓表制作 附程序

  [復制鏈接]
跳轉到指定樓層
樓主
用很簡單的方法制作一個51單片機電壓表,能測量30V以下的直流電壓,沒有精確的電壓表,無法測定其精度,但是用普通的萬用表測試比較之后發現其精度還是不錯的,其精度主要是看其供給的參考電壓的精度,AD轉換的位數,還有分壓電阻的精度。但是用于普通的電壓測量還是不錯的。




可以自行調整分壓電阻的大小和改動電壓算法參數可以直接適應其他量程的電壓測量



源代碼:
  1. #include<reg52.h>    //包含單片機寄存器的頭文件
  2. #include <intrins.h>

  3. #define ulong unsigned long
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define LCD1602_PORT P2          //用LED1602_PORT表示P2總線接口
  7. #define  PCF8591 0x90    //PCF8591 地址
  8. #define  NOP()   _nop_()   /* 定義空指令 */
  9. #define  _Nop()  _nop_()   /*定義空指令*/

  10. // 位定義
  11. sbit SCL=P1^0;       //I2C  時鐘
  12. sbit SDA=P1^1;       //I2C  數據
  13. sbit LCD1602_RS = P0^5;      //定義1602液晶顯示屏的數據/命令選擇端,數據/命令(H/L)
  14. sbit LCD1602_RW = P0^6;      //定義1602液晶顯示屏的讀/寫選擇端,讀/寫(H/L)
  15. sbit LCD1602_EN = P0^7;      //定義1602液晶顯示屏的使能端
  16. bit ack;                 /*應答標志位*/

  17. // 變量定義
  18. uchar AD_CHANNEL;
  19. ulong xdata  LedOut[8];      //單片機內部存取器
  20. ulong  v,a,ss;
  21. uchar date;

  22. // 函數申明
  23. extern bit ack;        //起動總線函數
  24. extern void Start_I2c();    //結束總線函數  
  25. extern void Stop_I2c();        //應答子函數
  26. extern void Ack_I2c(bit a);        //字節數據發送函數
  27. extern void  SendByte(uchar  c);    //有子地址發送多字節數據函數               
  28. extern bit ISendStr(uchar sla,uchar suba,uchar *s,uchar no) ;    //無子地址發送多字節數據函數   
  29. extern bit ISendStrExt(uchar sla,uchar *s,uchar no);    //無子地址讀字節數據函數               
  30. extern uchar RcvByte();

  31. void LCD1602_delay_ms(uint n);
  32. void LCD1602_write_com(uchar com);
  33. void LCD1602_write_data(ulong dat);
  34. void LCD1602_write_word(uchar *s);
  35. void Init_LCD1602();

  36. bit ISendByte(uchar sla,uchar c);
  37. uchar IRcvByte(uchar sla);

  38. //MS延時函數(12M晶振下測試)
  39. void delay_ms(uint n)   
  40. {
  41.     unsigned int  i,j;
  42.     for(i=0;i<n;i++)
  43.         for(j=0;j<123;j++);
  44. }

  45. //寫指令
  46. void LCD1602_write_com(uchar com)
  47. {
  48.     LCD1602_RS = 0;         //1602液晶顯示屏的數據/命令選擇端置0,數據/命令(H/L),此時選擇寫命令操作
  49.     delay_ms(1);
  50.     LCD1602_EN = 1;         //使能,也就是打開液晶接收數據命令的通道
  51.     LCD1602_PORT = com;     //把命令送給P2口
  52.     delay_ms(1);
  53.     LCD1602_EN = 0;
  54. }

  55. //寫數據
  56. void LCD1602_write_data(ulong dat)
  57. {
  58.     LCD1602_RS = 1;         //1602液晶顯示屏的數據/命令選擇端置0,數據/命令(H/L),此時選擇寫數據操作
  59.     delay_ms(1);   
  60.     LCD1602_PORT = dat;     //把數據送給P2口
  61.     LCD1602_EN = 1;
  62.     delay_ms(1);
  63.     LCD1602_EN = 0;
  64. }

  65. //連續寫字符
  66. void LCD1602_write_word(uchar *s)
  67. {
  68.     while(*s>0)
  69.     {
  70.         LCD1602_write_data(*s);
  71.         s++;
  72.     }
  73. }

  74. //1602初始化函數
  75. void Init_LCD1602()                    
  76. {
  77.     LCD1602_EN = 0;
  78.     LCD1602_RW = 0;                        //設置為寫狀態
  79.     LCD1602_write_com(0x38);            //顯示模式設定
  80.     LCD1602_write_com(0x0c);            //開關顯示、光標有無設置、光標閃爍設置
  81.     LCD1602_write_com(0x06);            //寫一個字符后指針加一
  82.     LCD1602_write_com(0x01);            //清屏指令
  83. }
  84. /*******************************************************************
  85.                      起動總線函數               
  86. 函數原型: void  Start_I2c();  
  87. 功能:     啟動I2C總線,即發送I2C起始條件.  
  88. ********************************************************************/
  89. void Start_I2c()
  90. {
  91.   SDA=1;         /*發送起始條件的數據信號*/
  92.   _Nop();
  93.   SCL=1;
  94.   _Nop();        /*起始條件建立時間大于4.7us,延時*/
  95.   _Nop();
  96.   _Nop();
  97.   _Nop();
  98.   _Nop();   
  99.   SDA=0;         /*發送起始信號*/
  100.   _Nop();        /* 起始條件鎖定時間大于4μs*/
  101.   _Nop();
  102.   _Nop();
  103.   _Nop();
  104.   _Nop();      
  105.   SCL=0;       /*鉗住I2C總線,準備發送或接收數據 */
  106.   _Nop();
  107.   _Nop();
  108. }

  109. /*******************************************************************
  110.                       結束總線函數               
  111. 函數原型: void  Stop_I2c();  
  112. 功能:     結束I2C總線,即發送I2C結束條件.  
  113. ********************************************************************/
  114. void Stop_I2c()
  115. {
  116.   SDA=0;      /*發送結束條件的數據信號*/
  117.   _Nop();       /*發送結束條件的時鐘信號*/
  118.   SCL=1;      /*結束條件建立時間大于4μs*/
  119.   _Nop();
  120.   _Nop();
  121.   _Nop();
  122.   _Nop();
  123.   _Nop();
  124.   SDA=1;      /*發送I2C總線結束信號*/
  125.   _Nop();
  126.   _Nop();
  127.   _Nop();
  128.   _Nop();
  129. }

  130. /*******************************************************************
  131.                  字節數據發送函數               
  132. 函數原型: void  SendByte(UCHAR c);
  133. 功能:     將數據c發送出去,可以是地址,也可以是數據,發完后等待應答,并對
  134.           此狀態位進行操作.(不應答或非應答都使ack=0)     
  135.            發送數據正常,ack=1; ack=0表示被控器無應答或損壞。
  136. ********************************************************************/
  137. void  SendByte(uchar  c)
  138. {
  139. uchar  BitCnt;

  140. for(BitCnt=0;BitCnt<8;BitCnt++)  /*要傳送的數據長度為8位*/
  141.     {
  142.      if((c<<BitCnt)&0x80)SDA=1;   /*判斷發送位*/
  143.        else  SDA=0;               
  144.      _Nop();
  145.      SCL=1;               /*置時鐘線為高,通知被控器開始接收數據位*/
  146.       _Nop();
  147.       _Nop();             /*保證時鐘高電平周期大于4μs*/
  148.       _Nop();
  149.       _Nop();
  150.       _Nop();         
  151.      SCL=0;
  152.     }
  153.    
  154.     _Nop();
  155.     _Nop();
  156.     SDA=1;                /*8位發送完后釋放數據線,準備接收應答位*/
  157.     _Nop();
  158.     _Nop();   
  159.     SCL=1;
  160.     _Nop();
  161.     _Nop();
  162.     _Nop();
  163.     if(SDA==1)ack=0;     
  164.        else ack=1;        /*判斷是否接收到應答信號*/
  165.     SCL=0;
  166.     _Nop();
  167.     _Nop();
  168. }

  169. /*******************************************************************
  170.                  字節數據接收函數               
  171. 函數原型: UCHAR  RcvByte();
  172. 功能:        用來接收從器件傳來的數據,并判斷總線錯誤(不發應答信號),
  173.           發完后請用應答函數應答從機。  
  174. ********************************************************************/   
  175. uchar   RcvByte()
  176. {
  177.   uchar  retc;
  178.   uchar  BitCnt;
  179.   
  180.   retc=0;
  181.   SDA=1;                     /*置數據線為輸入方式*/
  182.   for(BitCnt=0;BitCnt<8;BitCnt++)
  183.       {
  184.         _Nop();           
  185.         SCL=0;                  /*置時鐘線為低,準備接收數據位*/
  186.         _Nop();
  187.         _Nop();                 /*時鐘低電平周期大于4.7μs*/
  188.         _Nop();
  189.         _Nop();
  190.         _Nop();
  191.         SCL=1;                  /*置時鐘線為高使數據線上數據有效*/
  192.         _Nop();
  193.         _Nop();
  194.         retc=retc<<1;
  195.         if(SDA==1)retc=retc+1;  /*讀數據位,接收的數據位放入retc中 */
  196.         _Nop();
  197.         _Nop();
  198.       }
  199.   SCL=0;   
  200.   _Nop();
  201.   _Nop();
  202.   return(retc);
  203. }

  204. /********************************************************************
  205.                      應答子函數
  206. 函數原型:  void Ack_I2c(bit a);
  207. 功能:      主控器進行應答信號(可以是應答或非應答信號,由位參數a決定)
  208. ********************************************************************/
  209. void Ack_I2c(bit a)
  210. {
  211.   if(a==0)SDA=0;              /*在此發出應答或非應答信號 */
  212.   else SDA=1;
  213.   _Nop();
  214.   _Nop();
  215.   _Nop();      
  216.   SCL=1;
  217.   _Nop();
  218.   _Nop();                    /*時鐘低電平周期大于4μs*/
  219.   _Nop();
  220.   _Nop();
  221.   _Nop();  
  222.   SCL=0;                     /*清時鐘線,鉗住I2C總線以便繼續接收*/
  223.   _Nop();
  224.   _Nop();   
  225. }


  226. /*******************************************************************
  227. ADC發送字節[命令]數據函數               
  228. *******************************************************************/
  229. bit ISendByte(uchar sla,uchar c)
  230. {
  231.    Start_I2c();              //啟動總線
  232.    SendByte(sla);            //發送器件地址
  233.    if(ack==0)return(0);
  234.    SendByte(c);              //發送數據
  235.    if(ack==0)return(0);
  236.    Stop_I2c();               //結束總線
  237.    return(1);
  238. }

  239. /*******************************************************************
  240. ADC讀字節數據函數               
  241. *******************************************************************/
  242. uchar IRcvByte(uchar sla)
  243. {  
  244.    uchar c;
  245.    Start_I2c();          //啟動總線
  246.    SendByte(sla+1);      //發送器件地址
  247.    if(ack==0)return(0);
  248.    c=RcvByte();          //讀取數據0
  249.    Ack_I2c(1);           //發送非就答位
  250.    Stop_I2c();           //結束總線
  251.    return(c);
  252. }

  253. //    字符顯示函數
  254. void Display()
  255. {
  256.     LCD1602_write_com(0x80);            //指針設置,指向1602液晶第一行第一列
  257.     LCD1602_write_word("Voltage: ");
  258.     LCD1602_write_com(0x80+0x0e);            //指針設置,指向1602液晶第一行第一列
  259.     LCD1602_write_word(" V");
  260. }

  261. //實時電壓顯示函數
  262. void Display_Voltage()
  263. {
  264.     ss=(v*a);
  265.     ss=((ss*6)/100);
  266.     LCD1602_write_com(0x80+0x09);    //1602液晶屏命令操作,表示起始顯示位置為第二行第7列   
  267.     LCD1602_write_data(ss%10000000/1000000 + 0x30);
  268.     LCD1602_write_data(ss%1000000/100000 + 0x30);
  269.     LCD1602_write_data('.');
  270.     LCD1602_write_data(ss%100000/10000 + 0x30);
  271.     LCD1602_write_data(ss%10000/1000 + 0x30);
  272. //    LCD1602_write_data(ss%1000/100 + 0x30);
  273. //    LCD1602_write_data('.');
  274. //    LCD1602_write_data(ss%100/10 + 0x30);
  275. //    LCD1602_write_data(ss%10/1 + 0x30);
  276. }
  277. //******************************************************************/
  278. main()
  279. {  
  280.     Init_LCD1602(); //初始化LCD1602
  281.     Display();
  282.     a=50000000/255;
  283.         while(1)
  284.     {
  285.         ISendByte(PCF8591,0x41);
  286.         v=IRcvByte(PCF8591);      
  287.         Display_Voltage();         
  288.     }      
  289. }

復制代碼

評分

參與人數 10黑幣 +153 收起 理由
huangyuxin + 15
294 + 4
ZB0717226 + 5 很給力!
jinmei1314 + 5 很給力!
vvv64 + 5 共享資料的黑幣獎勵!
炫神 + 5 很給力!
自知 + 5 很給力!
qjzyx + 6 贊一個!
darkly5251 + 3 很給力!
admin + 100 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏25 分享淘帖 頂12 踩
回復

使用道具 舉報

沙發
ID:110866 發表于 2017-5-4 00:15 | 只看該作者
仿真怎么沒給
回復

使用道具 舉報

板凳
ID:212280 發表于 2017-6-18 15:35 | 只看該作者
非常感謝,正在學習PCF8591的使用
回復

使用道具 舉報

地板
ID:145507 發表于 2017-7-28 13:00 | 只看該作者
對我幫助很大  學習了
回復

使用道具 舉報

5#
ID:239025 發表于 2017-10-12 22:14 | 只看該作者
學習了
回復

使用道具 舉報

6#
ID:223453 發表于 2017-11-23 20:45 | 只看該作者
為什么顯示屏顯示的都是0啊,都不跳
回復

使用道具 舉報

7#
ID:247901 發表于 2017-11-24 19:15 | 只看該作者
學習了
回復

使用道具 舉報

8#
ID:249545 發表于 2017-11-25 20:55 | 只看該作者
老師的電壓表相當先進.
能進一步升級嗎?  制做液晶玻璃顯示屏.51MCU做成OTP COB固定在PCB上,用斑馬線連接顯示屏.這樣成工業品.批量生產.
回復

使用道具 舉報

9#
ID:71549 發表于 2017-11-29 18:14 | 只看該作者
對我幫助很大  學習了.....
回復

使用道具 舉報

10#
ID:257027 發表于 2017-12-4 11:25 | 只看該作者
對我幫助很大  學習了
回復

使用道具 舉報

11#
ID:241545 發表于 2017-12-13 17:35 | 只看該作者
謝謝分享
回復

使用道具 舉報

12#
ID:262595 發表于 2017-12-17 11:52 | 只看該作者
謝謝分享謝謝啊加兩分吧
回復

使用道具 舉報

13#
ID:263213 發表于 2017-12-18 18:27 | 只看該作者
謝謝,很給力
回復

使用道具 舉報

14#
ID:240102 發表于 2017-12-20 19:14 | 只看該作者
樓主大大  ,可以寫這個 —————— PCF8591 +12864 +89s52測電壓0-30V的程序么?! 好想要!
回復

使用道具 舉報

15#
ID:264801 發表于 2017-12-21 15:46 | 只看該作者
問一下,接線全部按照你的來,為什么顯示器不顯示電壓
回復

使用道具 舉報

16#
ID:265343 發表于 2017-12-22 16:01 | 只看該作者
很好的帖子。寫的很詳細!
回復

使用道具 舉報

17#
ID:272494 發表于 2018-1-6 19:59 | 只看該作者
程序下不了QAQ,,哪位兄弟能給我發一份。。
回復

使用道具 舉報

18#
ID:272494 發表于 2018-1-8 14:29 | 只看該作者
姚元紅 發表于 2017-12-21 15:46
問一下,接線全部按照你的來,為什么顯示器不顯示電壓

我的也是,zenme 回事,請教
回復

使用道具 舉報

19#
ID:272625 發表于 2018-1-25 05:05 | 只看該作者
好資料,感謝樓主
回復

使用道具 舉報

20#
ID:272625 發表于 2018-1-25 21:29 | 只看該作者
我也試試看,行不行
回復

使用道具 舉報

21#
ID:269211 發表于 2018-1-26 22:05 | 只看該作者
非常感謝,正在學習PCF8591的使用
回復

使用道具 舉報

22#
ID:285225 發表于 2018-2-25 00:06 | 只看該作者
謝謝答主,可以用數碼管試試感覺也很方便
回復

使用道具 舉報

23#
ID:285225 發表于 2018-2-28 10:58 | 只看該作者
非常感謝答主的分享
回復

使用道具 舉報

24#
ID:302866 發表于 2018-4-7 21:50 | 只看該作者
老王個 發表于 2018-1-8 14:29
我的也是,zenme 回事,請教

我的也)是  你的弄好了么
回復

使用道具 舉報

25#
ID:303099 發表于 2018-4-9 17:20 | 只看該作者
學習了~感謝樓主的分享
回復

使用道具 舉報

26#
ID:305873 發表于 2018-4-11 15:04 | 只看該作者
學習了,非常感謝答主的分享
回復

使用道具 舉報

27#
ID:308601 發表于 2018-4-15 15:28 | 只看該作者
學習了,感謝分享
回復

使用道具 舉報

28#
ID:316572 發表于 2018-5-4 20:13 | 只看該作者

學習了,感謝分享!!!學習了,感謝分享!!!!
回復

使用道具 舉報

29#
ID:146874 發表于 2018-5-7 16:04 | 只看該作者
感謝樓主分享,很給力
回復

使用道具 舉報

30#
ID:146874 發表于 2018-5-7 16:05 | 只看該作者
謝謝分享
回復

使用道具 舉報

31#
ID:146874 發表于 2018-5-7 16:05 | 只看該作者
謝謝分享,正在學習這方面的資料
回復

使用道具 舉報

32#
ID:324272 發表于 2018-5-7 16:15 | 只看該作者
很厲害啊
回復

使用道具 舉報

33#
ID:316171 發表于 2018-5-8 20:50 | 只看該作者
左下的元件有誰告訴一下名稱是什么么
回復

使用道具 舉報

34#
ID:316572 發表于 2018-5-9 21:14 | 只看該作者
樓主可以仔細解釋一下位定義的意思嗎,不太明白這幾條代碼啊
回復

使用道具 舉報

35#
ID:240994 發表于 2018-5-11 21:53 | 只看該作者
感謝樓主
回復

使用道具 舉報

36#
ID:48413 發表于 2018-5-15 08:00 | 只看該作者
不錯值的學習
回復

使用道具 舉報

37#
ID:318584 發表于 2018-5-15 13:39 | 只看該作者
你好 我按照這個原理圖焊接了50k與250k的電阻 顯示誤差有些大  2.48v我測了2.7v 3.26v測了3.5v 4.96 測了5.05v 請問如何使用算法調整精度
回復

使用道具 舉報

38#
ID:277463 發表于 2018-5-21 21:10 | 只看該作者
estbon 發表于 2017-6-18 15:35
**** 作者被禁止或刪除 內容自動屏蔽 ****

感謝樓主
回復

使用道具 舉報

39#
ID:281991 發表于 2018-5-23 20:16 | 只看該作者
感謝樓主。
回復

使用道具 舉報

40#
ID:353778 發表于 2018-6-19 16:28 | 只看該作者

感謝樓主。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品免费视频 | 亚洲国产精品一区 | 久久久久久看片 | 国产亚洲精品久久久久动 | 日韩欧美久久精品 | 亚洲综合一区二区三区 | av在线一区二区 | 亚洲欧洲成人av每日更新 | 一级在线视频 | 午夜一级做a爰片久久毛片 精品综合 | 黄色欧美在线 | 一久久久 | 亚洲在线一区 | 就操在线 | 国产永久免费 | 黄视频免费在线 | 国产精品a久久久久 | 久久亚洲国产 | 黄视频国产 | 久久久精品视频免费 | 午夜电影在线播放 | 一区二区三区在线 | 亚洲日产精品 | 国产一区二区精品自拍 | 999免费观看视频 | 精品一区二区久久久久久久网站 | 国产精品一区二区三区四区 | 国产成人自拍av | 一区二区三区视频在线观看 | 中文字幕爱爱视频 | 黄色一级免费看 | 一道本在线| 精品三区 | 亚洲一区导航 | 国产精品美女久久久久aⅴ国产馆 | 亚洲一区视频在线 | 成人h视频在线观看 | gav成人免费播放视频 | 福利精品 | 国内精品久久久久 | 欧美久久一区二区三区 |