找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 1617|回复: 6
收起左侧

变压器故障检测

[复制链接]
ID:1044901 发表于 2023-4-20 13:19 | 显示全部楼层 |阅读模式
500黑币
2.png 1.png

单片机源程序如下:
  1. #include <reg51.h>
  2. #include <intrins.h>
  3. #include <math.h>
  4. #define uchar unsigned char
  5. #define uint  unsigned int
  6. #define ulong unsigned long
  7. sbit LED=P1^7;
  8. sbit LED1=p3^7;
  9. uint ad;
  10. uint ad1;
  11. uint ad2;
  12. uint ad3;
  13. uint ad4;
  14. uint ad5;
  15. uint ad6;
  16. uint adH2;
  17. uint adCH4;
  18. uint adC0;
  19. uint adC2H2;
  20. uint adC2H4;
  21. uint adC2H6;
  22. sbit key=p1^0;
  23. sbit key1=p1^1;
  24. sbit key2=p1^2;
  25. sbit key3=p1^3;
  26. sbit key4=p1^4;
  27. sbit key5=p1^5;
  28. sbit key6=p1^6;
  29. uchar b;
  30. uchar b1;
  31. uchar b2;
  32. uchar b3;
  33. uint hc;
  34. uint u=0;
  35. uint i=0;
  36. uint ux=300;
  37. uint ix=10;
  38. uint wendu=80;
  39. uchar code zifu[]="0123456789abcdef";
  40. uchar code zifu0[]="H2:000 CH4:000";
  41. uchar code zifu1[]="CO:000 C2H2:000";
  42. uchar code zifu2[]="C2H4:000 C2H6:000";
  43. uchar code zifu3[]="B:0-0-0";
  44. uchar code zifu4[]="dianya:000";
  45. uchar code zifu5[]="dianliu:000";
  46. uchar code zifu6[]="wendu:000";
  47. uchar moshi=0;
  48. #includ <ad.h>
  49. #include <ds18.h>
  50. #include <lcd.h>
  51. sbit beer=P2^6;
  52. void beerc()
  53. {
  54. beer=0; _delay_ms(60);
  55. beer=1;_delay_ms(1);
  56. }
  57. void led()
  58. {
  59. LED=0;
  60. LED1=0;
  61. delay();
  62. }
  63. viod read()
  64. {
  65. readds();
  66. ad1=get_data(0);
  67. ad2=get_data(1);
  68. ad3=get_data(2);
  69. ad4=get_data(3);
  70. ad5=get_data(4);
  71. ad6=get_data(5);
  72. //电压电流
  73. u=get_data(6);
  74. i=get_data(7); _delay_ms(10);
  75. //赋值
  76. adh2=ad1;
  77. adch4=ad2;
  78. adco=ad3;
  79. adc2h2=ad4;
  80. adc2h4=ad5;
  81. adc2h6=ad6;
  82. //比值 1
  83. hc=adc2h2*10/adc2h4;
  84. if(hc<1) b1=0;
  85. if((hc>=1)&&(hc<10)) b1=1;
  86. if((hc>=10)&&(hc<30)) b1=1;
  87. if(hc>=30) b1=2;
  88. //比值 2
  89. hc=adch4*10/adh2;
  90. if(hc<1) b2=1;
  91. if((hc>=1)&&(hc<10)) b2=0;
  92. if((hc>=10)&&(hc<30)) b2=2;
  93. if(hc>=30) b2=2;
  94. //比值 3
  95. hc=adc2h2*10/adc2h6;
  96. if(hc<1) b3=0;
  97. if((hc>=1)&&(hc<10)) b3=0;
  98. if((hc>=10)&&(hc<30)) b3=1;
  99. if(hc>=30) b3=2;
  100. if((b1==0)&&(b2==0)&&(b3==0)) b=0;
  101. if((b1==0)&&(b2==1)&&(b3==0)) b=1;
  102. if((b1==0)&&(b2==0)&&(b3==1)) b=2;
  103. if((b1==0)&&(b2==2)&&(b3==0)) b=3;
  104. if((b1==0)&&(b2==2)&&(b3==1)) b=4;
  105. if((b1==0)&&(b2==0)&&(b3==2)) b=5;
  106. if((b1==0)&&(b2==1)&&(b3==2)) b=5;
  107. if((b1==0)&&(b2==2)&&(b3==2)) b=5;
  108. if((b1==2)&&(b2==0)) b=6;
  109. if((b1==2)&&(b2==1)) b=6;
  110. if((b1==2)&&(b2==2)) b=6;
  111. if((b1==1)&&(b2==0)) b=7;
  112. if((b1==1)&&(b2==1)) b=7;
  113. if((b1==1)&&(b2==2)) b=7;
  114. if(b>0)beerc();LED=0;LED1=1;
  115. if(u>ux)beerc();LED=0;LED1=1;
  116. if(i>ix)beerc();LED=0;LED1=1;
  117. if(wendu>wendux)beerc();LED=0;LED1=1;
  118. }
  119. void xianshi()
  120. {
  121. lcd1602_adr(0x08);
  122. lcd1602_writenumber(0x30+u%1000/100)
  123. lcd1602_writenumber(0x30+u%100/10);
  124. lcd1602_writenumber(0x30+u%10);
  125. lcd1602_adr(0x0d);
  126. lcd1602_writenumber(0x30+ux%1000/100);
  127. lcd1602_writenumber(0x30+ux%100/10);
  128. lcd1602_writenumber(0x30+ux%10);
  129. //当前 i
  130. lcd1602_adr(0x48);
  131. lcd1602_writenumber(0x30+i%1000/100);
  132. lcd1602_writenumber(0x30+i%100/10);
  133. lcd1602_writenumber(0x30+i%10);
  134. lcd1602_adr(0x4D);
  135. lcd1602_writenumber(0x30+ix%1000/100);
  136. lcd1602_writenumber(0x30+ix%100/10);
  137. lcd1602_writenumber(0x30+ix%10);
  138. //当前 w
  139. lcd1602_adr(0x18);
  140. lcd1602_writenumber(0x30+wendu%1000/100);
  141. lcd1602_writenumber(0x30+wendu%100/10);
  142. lcd1602_writenumber(0x30+wendu%10);
  143. lcd1602_adr(0x1D);
  144. lcd1602_writenumber(0x30+wendux%1000/100);
  145. lcd1602_writenumber(0x30+wendux%100/10);
  146. lcd1602_writenumber(0x30+wendux%10);
  147. lcd1602_adr(0x53);
  148. lcd1602_writenumber(0x30+b1%10);
  149. lcd1602_adr(0x55);
  150. lcd1602_writenumber(0x30+b2%10);
  151. lcd1602_adr(0x57);
  152. lcd1602_writenumber(0x30+b3%10);
  153. lcd1602_adr(0x5f);
  154. lcd1602_writenumber(0x30+b%10); //----------------------------------
  155. //切换
  156. if(key==0)
  157. {
  158. moshi=0;
  159. LCD1602_string(1,1,zifu0);
  160. LCD1602_string(2,1,zifu1);
  161. LCD1602_string(3,1,zifu2);
  162. LCD1602_string(4,1,zifu3);
  163. LED=0;LED1=1;
  164. while(key==0);
  165. }
  166. //SET
  167. if(key1==0){if(ux<999)ux=ux+1; while(key1==0); }
  168. if(key2==0){if(ux> 0)ux=ux-1; while(key2==0); }
  169. //SET
  170. if(key3==0){if(ix<999)ix=ix+1; while(key3==0); }
  171. if(key4==0){if(ix> 0)ix=ix-1; while(key4==0); }
  172. //SET
  173. if(key5==0){if(wendux<199)wendux=wendux+1; while(key5==0); }
  174. if(key6==0){if(wendux> 0)wendux=wendux-1; while(key6==0); }
  175. }
  176. void xianshi0()
  177. {
  178. //当前 H2
  179. lcd1602_adr(0x04);
  180. lcd1602_writenumber(0x30+adh2%1000/100);
  181. lcd1602_writenumber(0x30+adh2%100/10);
  182. lcd1602_writenumber(0x30+adh2%10);
  183. //当前 CH4
  184. lcd1602_adr(0x44);
  185. lcd1602_writenumber(0x30+adch4%1000/100);
  186. lcd1602_writenumber(0x30+adch4%100/10);
  187. lcd1602_writenumber(0x30+adch4%10);
  188. //当前 H2
  189. lcd1602_adr(0x14);
  190. lcd1602_writenumber(0x30+adco%1000/100);
  191. lcd1602_writenumber(0x30+adco%100/10);
  192. lcd1602_writenumber(0x30+adco%10);
  193. //当前 C2H2
  194. lcd1602_adr(0x0D);
  195. lcd1602_writenumber(0x30+adc2h2%1000/100);
  196. lcd1602_writenumber(0x30+adc2h2%100/10);
  197. lcd1602_writenumber(0x30+adc2h2%10);
  198. //当前 C2H4
  199. lcd1602_adr(0x4D);
  200. lcd1602_writenumber(0x30+adc2h4%1000/100);
  201. lcd1602_writenumber(0x30+adc2h4%100/10);
  202. lcd1602_writenumber(0x30+adc2h4%10);
  203. //当前 C2H2
  204. lcd1602_adr(0x1D);
  205. lcd1602_writenumber(0x30+adc2h6%1000/100);
  206. lcd1602_writenumber(0x30+adc2h6%100/10);
  207. lcd1602_writenumber(0x30+adc2h6%10);
  208. lcd1602_adr(0x53);
  209. lcd1602_writenumber(0x30+b1%10);
  210. lcd1602_adr(0x55);
  211. lcd1602_writenumber(0x30+b2%10);
  212. lcd1602_adr(0x57);
  213. lcd1602_writenumber(0x30+b3%10);
  214. lcd1602_adr(0x5f);
  215. lcd1602_writenumber(0x30+b%10);
  216. //切换
  217. if(key==0)
  218. {
  219. moshi=1;
  220. LCD1602_string(1,1,zifu4);
  221. LCD1602_string(2,1,zifu5);
  222. LCD1602_string(3,1,zifu6);
  223. LED1=0;LED=1;
  224. while(key==0);
  225. }
  226. }
  227. void main()
  228. {
  229. _delay_ms(1);
  230. //初始化
  231. lcd1602_init();
  232. LCD1602_string(1,1,zifu0);
  233. LCD1602_string(1,1,zifu0);
  234. LCD1602_string(2,1,zifu1);
  235. LCD1602_string(3,1,zifu2);
  236. LCD1602_string(4,1,zifu3);
  237. readds18();_delay_ms(300);
  238. readds18();_delay_ms(300);
  239. readds18();_delay_ms(300);
  240. readds18();_delay_ms(300);
  241. readds18();_delay_ms(300);
  242. //进入循环
  243. while(1)
  244. {
  245. read();
  246. if(moshi==0)xianshi0();
  247. if(moshi==1)xianshi1();
  248. }
  249. }
  250. void _delay_ms(uint t)
  251. {
  252. uint i,j;
  253. for(i=0;i<t;i++)
  254. for(j=0;j<120;j++);
  255. }
  256. //延时函数 us
  257. void _delay_us(uchar t)
  258. {
  259. while(t>0)t--;
  260. }
  261. //接口定义
  262. sbit SDO = P2^0;//数据输出口
  263. sbit ADD = P2^1;//通道选择
  264. sbit CS = P2^2;//启动
  265. sbit CLK = P2^3;//时钟时序
  266. sbit EOC = P2^4;//为高时轮换结束
  267. unsigned int adhc1=0;
  268. unsigned int adhc2=0;
  269. //读 AD 中的数据
  270. unsigned int get_data2(unsigned char ch)
  271. {
  272. unsigned char i;
  273. unsigned int temp=0;
  274. //4 有效地址左对齐
  275. ch <<= 4;
  276. CLK=0;_delay_us(1);
  277. CS=0;
  278. //地址-4
  279. for (i=0;i<4;i++)
  280. {
  281. if(ch&0X80)ADD=1; else ADD=0;_delay_us(1);
  282. CLK=1;_delay_us(1);
  283. CLK=0;_delay_us(1);
  284. ch <<= 1;
  285. }
  286. //CLK-8
  287. for (i=0;i<8;i++)
  288. { ADD=0;
  289. CLK=1;_delay_us(1);
  290. CLK=0;_delay_us(1);
  291. }
  292. //片选 信号
  293. CS=1;_delay_us(20);
  294. CS=0;_delay_us(10);
  295. //读取 10 位数据
  296. for (i=0;i<10;i++)
  297. {
  298. temp <<= 1;
  299. if(SDO)temp|=0x01; _delay_us(1);
  300. CLK=1;_delay_us(1);
  301. CLK=0;_delay_us(1);
  302. }
  303. CS=1;
  304. return(temp*9/10);
  305. }
  306. //读 AD 中的数据
  307. unsigned int get_data(unsigned char ch)
  308. {
  309. unsigned int temp=0;
  310. adhc1=get_data2(ch);
  311. adhc2=get_data2(ch);
  312. temp=(adhc1+adhc2)/2;
  313. return(temp);
  314. }
  315. //传感器的数据线
  316. sbit DQ=P2^7;
  317. int wendu=0;
  318. uchar z1;
  319. //延时函数
  320. void delay3(unsigned int i)
  321. {
  322. while(i--);
  323. }
  324. //初始化
  325. void Init_DS18B20(void)
  326. {
  327. unsigned char x=0;
  328. DQ = 1; //DQ 复位
  329. delay3(8); //稍做延时
  330. DQ = 0; //单片机将 DQ 拉低
  331. delay3(80); //精确延时 大于 480us
  332. DQ = 1; //拉高总线
  333. delay3(10);
  334. x=DQ; //稍做延时后 如果 x=0 则初始化成功 x=1 则初始化失败
  335. delay3(5);
  336. }
  337. //读一个字节
  338. unsigned char ReadOneChar(void)
  339. {
  340. unsigned char i=0;
  341. unsigned char dat = 0;
  342. for (i=8;i>0;i--)
  343. {
  344. DQ = 0; // 给脉冲信号
  345. dat>>=1;
  346. DQ = 1; // 给脉冲信号
  347. if(DQ)
  348. dat|=0x80;
  349. delay3(5);
  350. }
  351. return(dat);
  352. }
  353. //写一个字节
  354. void WriteOneChar(unsigned char dat)
  355. {
  356. unsigned char i=0;
  357. for (i=8; i>0; i--)
  358. {
  359. DQ = 0;
  360. DQ = dat&0x01;
  361. delay3(5);
  362. DQ = 1;
  363. dat>>=1;
  364. }
  365. delay3(5);
  366. }
  367. //读取温度
  368. unsigned int ReadTemperature(void)
  369. {
  370. unsigned char a=0;
  371. unsigned int b=0;
  372. unsigned int t=0;
  373. Init_DS18B20();
  374. WriteOneChar(0xCC); // 跳过读序号列号的操作
  375. WriteOneChar(0x44); // 启动温度转换
  376. delay3(10);
  377. Init_DS18B20();
  378. WriteOneChar(0xCC); //跳过读序号列号的操作
  379. WriteOneChar(0xBE); //读取温度寄存器等(共可读 9 个寄存器) 前两个就是温度
  380. a=ReadOneChar(); //低位
  381. b=ReadOneChar(); //高位
  382. b<<=8;
  383. t=a+b;
  384. return(t);
  385. }
  386. //数据处理
  387. void readds18()
  388. {
  389. unsigned int y=0;
  390. unsigned long x=0;
  391. y=ReadTemperature();
  392. //正
  393. if(!(y&0xf000))
  394. {
  395. z1=0;
  396. x=y;
  397. x=x*625/10000;
  398. wendu=x;
  399. }
  400. if(y&0xf000)
  401. {
  402. z1=1;
  403. y=-y;
  404. x=y;
  405. x=x*625/10000;
  406. wendu=0-x;
  407. }
  408. }
  409. sbit RS=P3^2; //写信号
  410. sbit E=P3^3; //使能信号
  411. #define e1 E=1
  412. #define rs1 RS=1
  413. #define e0 E=0
  414. #define rs0 RS=0
  415. #define PP P1
  416. //写 1602 控制字
  417. void lcd1602_writecrtl(uchar dat)
  418. {
  419. rs0;//写信号置 0
  420. _delay_us(5);
  421. PP=dat;
  422. e1;//使能信号置 1
  423. _delay_us(5);
  424. e0;//使能信号置 0
  425. }
  426. //写 1602 数据
  427. void lcd1602_writenumber(uchar dat)
  428. {
  429. rs1;//写信号置 1
  430. _delay_us(5);
  431. PP=dat;
  432. e1;//使能信号置 1
  433. _delay_us(5);
  434. e0;//使能信号置 0
  435. }
  436. //1602 初始化
  437. void lcd1602_init()
  438. {
  439. lcd1602_writecrtl(0x38); //显示模式
  440. lcd1602_writecrtl(0x06); //显示光标移动位置
  441. lcd1602_writecrtl(0x0c); //显示开及光标设置
  442. lcd1602_writecrtl(0x01); //显示清屏
  443. }
  444. //显示地址
  445. void lcd1602_adr(uchar dat)
  446. {
  447. lcd1602_writecrtl(0x80 | dat);
  448. }
  449. //行显示- void LCD1602_string(uchar hang,uchar lie,uchar const *p)
  450. {
  451. uchar a;
  452. if(hang == 1) a = 0x00;
  453. if(hang == 2) a = 0x40;
  454. if(hang == 3) a = 0x10;
  455. if(hang == 4) a = 0x50;
  456. a = a + lie - 1;
  457. lcd1602_adr(a);
  458. while(1)
  459. {
  460. if(*p == '\0') break;
  461. lcd1602_writenumber(*p);
  462. p++;
  463. }
  464. }
  465. //uchar code zifux[]="1234567812345678"
  466. //LCD1602_string(1,1,zifux);
  467. //LCD1602_string(2,1,zifux);
复制代码



回复

使用道具 举报

ID:262 发表于 2023-4-20 17:23 | 显示全部楼层
什么故障?不明白啊  还是描述清楚一下 吧
回复

使用道具 举报

ID:1044901 发表于 2023-4-20 19:09 | 显示全部楼层
heicad 发表于 2023-4-20 17:23
什么故障?不明白啊  还是描述清楚一下 吧

我想做的是在变压器正常运行时,显示电压电流温度,在变压器故障是显示H2,CH4,C2H2,C2H4,CO,C2H6等气体的数量和一个由改良三比值法得到的编码,这个编码就能判断故障类型,同时有声光报警。通过键盘可以转换变压器的远行状态(正常/故障)和对温度,电流,电压进行调节。
回复

使用道具 举报

ID:584814 发表于 2023-4-21 17:31 | 显示全部楼层
先画框图明确思路,然后简化成单一功能编程并通过,再后逐步增加功能。
回复

使用道具 举报

ID:213173 发表于 2023-4-21 19:47 | 显示全部楼层
不懂,变压器故障需要判断氢气,甲烷,乙炔,环氧乙烷,一氧化碳,乙烯浓度?
回复

使用道具 举报

ID:1073249 发表于 2023-4-23 23:07 来自手机 | 显示全部楼层
设计有问题,变压器的电压电流温度测量不需要用到气体监测。既然能测量电压电流温度功能变压器故障一目了然不需要故障代码。也可能是我没有理解楼主所想表达的吧!
回复

使用道具 举报

ID:229502 发表于 2023-4-23 23:52 | 显示全部楼层
外行胡说,楼主别介意。电流电压测量要介入电路,要有取样电路然后和基准比较显示在lcd上。其他气体检测需要各气传感器的驱动或是一个气体传感器的数据进行比对。以上是被动测量,而楼主最后的电流电压调节就是主动干预电路了,需要知道干预电路的方法。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表