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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

ACS712+51單片機電流測量程序與Proteus仿真圖

[復制鏈接]
跳轉到指定樓層
樓主
acs712+51單片機+DS18B20溫度與電流測量電路與程序
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include<reg52.h>
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. sbit DQ=P0^1; //ds18b20 與單片機連接口

  5. sbit RS=P1^0; //1602 寫數據 / 寫命令選擇端口
  6. //RS=1 寫數據,即要顯示的內容
  7. //RS=0 寫命令,即一些 LCD設置命令
  8. sbit RW=P1^1; //1602 讀/ 寫選擇端, RW=0為寫模式
  9. sbit EN=P1^2; // 給 EN一個高脈沖,將數據送入液晶控制器,完成寫操作

  10. /******adc配置*****/
  11. sbit EOC_1543 = P3 ^ 7;
  12. sbit SCLK_1543 = P3 ^ 5;
  13. sbit ADDR_1543 = P3 ^ 3;
  14. sbit DOUT_1543 = P3 ^ 2;
  15. sbit CS_1543 = P3 ^ 4;

  16. uchar code str1[]={"cur:"};
  17. uchar code str2[]={"temp:"};
  18. uchar data disdata[4];// 百、十、個、小數位
  19. uchar data cur_c[3];

  20. uint tvalue; // 溫度值
  21. uchar tflag; // 溫度正負標志
  22. /**********************lcd1602 設置子函數 *********************/
  23. void delay1ms(uint ms) // 延時 1 毫秒子函數 ,形參為 ms(不夠精確的)
  24. {
  25. unsigned int i,j;
  26. for(i=0;i<ms;i++)
  27. for(j=0;j<120;j++);
  28. }

  29. void delayus(unsigned char x)   // 延時 (x*2+5) us
  30. {
  31.     while(--x);
  32. }
  33. void wr_com(uchar com) //lcd 寫控制指令子函數,形參為 com
  34. {
  35. delay1ms(1); // 調用延時子函數,并用實參 1 代替延時子函數中的形參 ms
  36. RS=0; //RS=0 進入寫命令狀態,即一些 LCD設置命令
  37. RW=0; //RW=0 為寫模式
  38. EN=0;  //EN=0 時不能完成寫操作
  39. P2=com; // 把要設置的指令碼 com送給 P2 口
  40. delay1ms(1);
  41. EN=1; // 給 EN一個高脈沖,將數據送入液晶控制器,完成寫操作
  42. delay1ms(1);
  43. EN=0; }//EN=0 時不能完成寫操作
  44. /******************檢測忙標志函數***************************/  
  45. void check_busy(void)
  46. {
  47.   uchar dt;
  48.   do
  49. {
  50.               dt=0xff;
  51.               EN=0;
  52.               RS=0;
  53.               RW=1;
  54.               EN=1;
  55.               dt=P2;
  56.               }while(dt&0x80);
  57.               EN=0;
  58. }

  59. //*****************寫數據*******************************/
  60. void wr_dat(uchar dat) //lcd 寫顯示數據子函數,形參為 dat
  61. {
  62. /* check_busy();*/
  63. delay1ms(1);
  64. RS=1; //RS=1 進入寫數據狀態,即要顯示的內容
  65. RW=0; //RW=0 為寫模式
  66. EN=0; //EN=0 時不能完成寫操作
  67. P2=dat; // 把要顯示的數據 dat 送給 P2 口
  68. delay1ms(1);
  69. EN=1; // 給 EN一個高脈沖,將數據送入液晶控制器,完成寫操作
  70. delay1ms(1);
  71. EN=0; //EN=0 時不能完成寫操作
  72. }
  73. void lcd_init() //lcd 初始化設置子函數,不帶參數 ,0x38 是顯示模式設置 , 其余是顯示開 / 關及光標設置,無順序
  74. {
  75. delay1ms(15);
  76. wr_com(0x38); // 調用寫控制指令子函數,并用實參 "0011 1000" 代替形參 com
  77. //0x38 表示設置為 16*2 顯示,每個塊為 5*7 點陣, 8 位數據接口
  78. delay1ms(5);
  79. wr_com(0x08); // 調用寫控制指令子函數,并用實參 "0000 1000" 代替形參 com
  80. //0x08 表示設置為關顯示、不顯示光標、光標不閃爍
  81. delay1ms(5);
  82. wr_com(0x01); // 調用寫控制指令子函數,并用實參 "0000 0001" 代替形參 com
  83. //0x01 表示顯示數據清屏(數據指針清 0,所有顯示清 0)
  84. delay1ms(5);
  85. wr_com(0x06);// 調用寫控制指令子函數,并用實參 "0000 0110" 代替形參 com
  86. //0x06 表示當讀或寫一個字符后地址指針加 1,且光標加 1; 當寫一個字符時,整屏顯示不移動
  87. delay1ms(5);
  88. wr_com(0x0c);// 調用寫控制指令子函數,并用實參 "0000 1100" 代替形參 com
  89. //0x0c 打開顯示、不顯示光標、光標不閃爍
  90. delay1ms(5);
  91. }
  92. void display(uchar *p) //lcd 顯示字符串子函數
  93. {
  94. while(*p!='\0') // 測試是否等于 '\0' ,即判斷字符是否結尾
  95. {
  96. wr_dat(*p); // 顯示指針所指的字符串
  97. p++; // 指針加 1
  98. delay1ms(1);
  99. }
  100. }
  101. void init_play() // 初始化顯示子函數
  102. {
  103. lcd_init(); // 調用 lcd 初始化設置子函數,對 LCD進行初始化
  104. wr_com(0x80); // 調用寫控制指令子函數,并用實參 "1000 0000" 代替形參 com
  105. // 并將數據指針定位到第一行第一個字符處
  106. display(str1);// 從第一行第一個字符處顯示字符串 str1
  107. wr_com(0x80+0x40);// 調用寫控制指令子函數,并用實參 "1000 0000" 代替形參 com
  108. // 并將數據指針定位到第二行第一個字符處
  109. display(str2); // 從第二行第一個字符處顯示字符串 str2
  110. }

  111. /********************************************************/
  112. /********************ds18b20 程序 ***********************/
  113. void delay_18b20(uint i) // 延時 1 微秒
  114. {
  115. while(i--);
  116. }
  117. void ds18b20rst() //ds18b20 初始化子函數
  118. // 要求"數據線拉高 - 延時 - 數據線拉低 - 延時大于 480 微妙 -數據線拉高 - 延時等待 "
  119. {
  120. uchar x=0;
  121. DQ = 1; // 信號線 DQ復位
  122. delay_18b20(4); // 延時
  123. DQ = 0; //DQ 拉低
  124. delay_18b20(100); // 精確延時大于 480us
  125. DQ = 1; // 拉高
  126. delay_18b20(40);
  127. }
  128. void ds18b20wr(uchar wdata) /* 寫數據子函數 , 無返回值,含參數 */
  129. {
  130. uchar i=0;
  131. for (i=8; i>0; i--)// 要寫完一個字節,故需要重復 8 次以下操作
  132. {
  133. DQ = 0; // 數據線拉低
  134. DQ = wdata&0x01;//wdata 是一個形參,將其與 0000 0001 進行按位與
  135. // 按從低到高的順序發送數據(一次發送一位 )
  136. delay_18b20(10);
  137. DQ = 1; // 最后將數據線拉高
  138. wdata>>=1; // 將 wdata 右移 1 位
  139. }
  140. }
  141. uchar ds18b20rd() // 讀數據子函數 , 是有返回值 dat
  142. {
  143. uchar i=0;
  144. uchar dat = 0;
  145. for (i=8;i>0;i--)// 要讀完一個字節,故需要重復 8 次以下操作
  146. {
  147. DQ = 0; // 給脈沖信號
  148. dat>>=1;
  149. DQ = 1; // 給脈沖信號
  150. if(DQ)
  151. dat|=0x80;
  152. delay_18b20(10);
  153. }
  154. return(dat); // 返回 dat
  155. }
  156. read_temp() // 讀取溫度值并轉換的子函數,有返回值溫度值 tvalue
  157. {
  158. uchar a,b;
  159. ds18b20rst(); // 調用 ds18b20 初始化子函數
  160. ds18b20wr(0xcc);// 調用寫數據子函數,向 ds18b20 寫命令 0xcc
  161. //ccH 表示跳過 ROM讀序列號,適用于單機工作,直接向 18b20 發送溫度變換命令
  162. ds18b20wr(0x44);// 調用寫數據子函數,向 ds18b20 寫命令 0x44
  163. //44H 表示啟動 ds18b20 溫度轉換 , 結果自行存入 9 字節的 RAM中
  164. ds18b20rst(); // 調用 ds18b20 初始化子函數
  165. ds18b20wr(0xcc);// 同上
  166. ds18b20wr(0xbe);// 調用寫數據子函數,向 ds18b20 寫命令 0xbe
  167. //beH 表示讀取 RAM中 9 字節的溫度數據
  168. a=ds18b20rd(); // 調用讀數據子函數,并將所得數據給 a
  169. b=ds18b20rd(); //
  170. tvalue=b; // 把 b 的值給 tvalue
  171. tvalue<<=8; //tvalue 左移 8 位
  172. tvalue=tvalue|a;//tvalue 與 a 進行按位或
  173. if(tvalue<0x0fff)//
  174. tflag=0; // 前五位為 0 時,讀取的溫度為正,標志位為 0,此時只要
  175. // 將測得數值乘以 0.0625 即可得到實際溫度
  176. else // 前五位為 1 時,讀取的溫度為負,標志位為 1,此時需要
  177. { // 將測得數值取反后再加 1,再乘以 0.0625 即可得到實際溫度
  178. tflag=1; // 此時表示負溫度
  179. tvalue=~tvalue+1;
  180. }
  181. tvalue=tvalue*(0.625);// 溫度值擴大 10 倍,精確到 1 位小數
  182. return(tvalue); // 返回溫度值
  183. }
  184. /**********************************************************/
  185. /************************ 溫度值顯示 *********************/
  186. void ds18b20disp() // 溫度值顯示
  187. {
  188. uchar flagdat;
  189. disdata[0]=tvalue/1000+0x30; // 百位數
  190. disdata[1]=tvalue%1000/100+0x30;// 十位數
  191. disdata[2]=tvalue%100/10+0x30; // 個位數
  192. disdata[3]=tvalue%10+0x30; // 小數位
  193. if(tflag==0)
  194. flagdat=0x2b; // 正溫度顯示符號 :+
  195. else
  196. flagdat=0x2d; // 負溫度顯示負號 :-
  197. if(disdata[0]==0x30)
  198. {
  199. disdata[0]=0x20; // 如果百位為 0,不顯示
  200. if(disdata[1]==0x30)
  201. {
  202. disdata[1]=0x20; // 如果百位為 0,十位為 0 也不顯示
  203. }
  204. }
  205. wr_com(0x80+0x46); // 定位數據指針的位置:第二行第五個字符處
  206. wr_dat(flagdat); // 顯示符號位
  207. wr_com(0x80+0x47);  // 定位數據指針的位置:第二行第六個字符處
  208. wr_dat(disdata[0]);  // 顯示百位
  209. wr_com(0x80+0x48);  // 定位數據指針的位置:第二行第七個字符處
  210. wr_dat(disdata[1]);  // 顯示十位
  211. wr_com(0x80+0x49);  // 定位數據指針的位置:第二行第八個字符處
  212. wr_dat(disdata[2]);  // 顯示個位
  213. wr_com(0x80+0x4A);  // 定位數據指針的位置:第二行第九個字符處
  214. wr_dat(0x2e); // 顯示小數點
  215. wr_com(0x80+0x4B);  // 定位數據指針的位置:第二行第十個字符處
  216. wr_dat(disdata[3]);  // 顯示小數位
  217.               /**********************顯示攝氏度************************/
  218. wr_com(0x80+0x4C);  // 定位數據指針的位置:第二行第十一個字符處
  219. wr_dat(0XDF);
  220. wr_com(0x80+0x4D);  // 定位數據指針的位置:第二行第十二個字符處
  221. wr_dat(0X43);
  222. }

  223. /**********************************************************/
  224. /********************TLC1543************************/
  225. void TLC1543_init(void)
  226. {
  227.         CS_1543 = 1;
  228.         SCLK_1543 = 0;
  229. }


  230. uint ReadADC_TLC1543(uchar ain)
  231. {
  232.         uchar t;
  233.         uint adc_value = 0;
  234.         ain <<= 4;

  235.         CS_1543 = 0;
  236.         for (t = 0; t < 10; t++)         // 將判斷語句改為 temp<12
  237.         {                                       // 程序可移殖至 TLC2543.
  238.                 adc_value <<= 1;
  239.                 ain <<= 1;
  240.                 ADDR_1543 = CY;
  241.                 if (DOUT_1543)   adc_value += 1;
  242.                 SCLK_1543 = 1;
  243.                 delayus(1);
  244.                 SCLK_1543 = 0;
  245.         }
  246.         CS_1543 = 1;

  247.         return  adc_value;
  248. }

  249. uint get_cur()
  250. {
  251.         uint vol,cur_1;
  252.         vol = ReadADC_TLC1543(0) * 0.49; //輸入adc電壓的100倍。4.9=5(參照電壓)*/1024(10位)*100(用于顯示)
  253.         cur_1 = 5*vol-1250; //實際電流的100倍用于顯示,cur_real=(vol_real-2.5)*5
  254.         return cur_1;
  255. }

  256. void displaycur(uint cur)
  257. {
  258.         cur_c[0] = cur/1000%10+0x30;
  259.         cur_c[1]= cur/100%100+0x30;
  260.     cur_c[2]= cur/10%10+0x30;
  261.         wr_com(0x80 + 0x07);  // 定位數據指針的位置:第一行第七個字符處
  262.         wr_dat(cur_c[0]);  // 顯示十位
  263.         wr_com(0x80 + 0x08);  // 定位數據指針的位置:第一行第八個字符處
  264.         wr_dat(cur_c[1]);  // 顯示個位
  265.         wr_com(0x80 + 0x09);  // 定位數據指針的位置:第一行第九個字符處
  266.         wr_dat(0x2e); // 顯示小數點
  267.         wr_com(0x80 + 0x0A);  // 定位數據指針的位置:第一行第十個字符處
  268.         wr_dat(cur_c[2]);  // 顯示小數位
  269.         wr_com(0x80 + 0x0C);  // 定位數據指針的位置:第二行第十二個字符處
  270.         wr_dat(0X41);
  271. }

  272. /*******************************************************/
  273. /******************** 主程序 *****************************/
  274. void main()
  275. {
  276. init_play();  // 調用 lcd 初始化顯示子函數
  277. TLC1543_init();
  278. while(1)
  279. {
  280. read_temp(); // 調用 ds18b20 讀取溫度
  281. ds18b20disp(); // 調用溫度顯示子函數
  282. displaycur(get_cur());
  283. }
  284. }
復制代碼
Keil5代碼與Proteus8.8仿真下載:
51單片機電流測量.zip (92.19 KB, 下載次數: 143)

評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:1004160 發表于 2023-10-2 20:43 | 只看該作者
樓主,我測試交流電流,換了個激勵源(就是一個圈圈的那種220V的),是測不到正確電流的。但是換了一個探針類型的就可以了,這是為什么?

1.png (15.22 KB, 下載次數: 69)

1.png
回復

使用道具 舉報

板凳
ID:1122276 發表于 2024-8-2 19:49 | 只看該作者
xinwuhen 發表于 2023-10-2 20:43
樓主,我測試交流電流,換了個激勵源(就是一個圈圈的那種220V的),是測不到正確電流的。但是換了一個探針類 ...

你試過用測直流嗎
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: av国产精品 | h视频免费在线观看 | 射久久| 日本又色又爽又黄的大片 | 国产精品一码二码三码在线 | 日韩成人精品一区 | 亚洲欧美综合 | 天天操夜夜操 | 在线午夜 | 欧美黄 片免费观看 | 日韩综合在线视频 | 成人国产精品免费观看 | 51ⅴ精品国产91久久久久久 | 精品国产乱码久久久久久图片 | 午夜精品一区二区三区三上悠亚 | 日韩欧美一区二区三区免费观看 | 九九热在线观看视频 | 91精品导航 | 欧美一区2区三区4区公司二百 | 成人三级电影 | 99精品久久久久久久 | 亚洲成网站 | 国产精品美女在线观看 | 亚洲高清在线观看 | 在线视频一区二区三区 | 欧美日本一区 | 精品一区二区三区不卡 | 日本免费一区二区三区视频 | 日韩在线观看精品 | 日韩免费一区 | 成人av播放 | 天天色天天射天天干 | 三a毛片 | 亚洲一区视频在线播放 | 91精品国产91 | 波多野结衣电影一区 | 日韩av在线一区二区三区 | 国产精品毛片久久久久久久 | 日韩天堂av| 黄色一级大片在线免费看产 | 久久亚洲一区二区 |