找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6342|回复: 5
收起左侧

单片机负离子加湿器设计程序源代码

[复制链接]
ID:80436 发表于 2015-5-20 21:32 | 显示全部楼层 |阅读模式

  1. #include<reg52.h>  
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int

  5. sbit  SDA=P0^0;
  6. sbit  SCL=P0^1;

  7. sbit dio=P0^2;
  8. sbit clk=P0^3;
  9. sbit stb=P0^4;

  10. sfr P3M1=0xb1;//强推挽输出
  11. sfr P3M0=0xb2;

  12. sfr ADC_CONTR=0xBC;   //ADC用
  13. sfr ADC_RES=0xBD;
  14. sfr P1ASF=0x9D;

  15. sbit kzd=P3^7;      //低速控制
  16. sbit kzz=P3^6;      //中速控制
  17. sbit kzg=P3^5;      //高速控制
  18. sbit kzf=P3^4;      //负离子控制
  19. sbit kzj=P3^1;      //加湿控制

  20. sbit ledd=P2^1;//低速指示灯
  21. sbit ledz=P2^2;//中速指示灯
  22. sbit ledg=P2^3;//高速指示灯
  23. sbit ledj=P2^4;//加湿指示灯
  24. sbit ledf=P2^5;//负离子指示灯
  25. sbit ledkq=P1^1;//空气质量指示灯
  26. sbit ledds=P1^3;//定时指示灯

  27. sbit fmq=P3^0;      //蜂鸣器

  28. uint zzshu=1000;//初始化时,赋值大于转动脉冲数
  29. uint fzshu=1000;//初始化时,赋值大于转动脉冲数

  30. uchar qw;            //气味处理值
  31. uint qwcaiji; //气味采集值
  32. uint key;

  33. uchar TM_0,TM_2,TM_4;    //TM1629B显示用参数
  34. uchar code table[]={0x7e,0x42,0x5d,0x57,0x63,0x37,0x3f,0x52,0x7f,0x77};

  35. uchar code zheng[]={0x30,0x60,0xc0,0x90};
  36. uchar code fan[]={0x30,0x90,0xc0,0x60};

  37. void TM1629B_xie(uchar xie)
  38. {
  39. uchar i;
  40. for(i=0;i<8;i++)
  41. {
  42. clk=0;
  43. if(xie&0x01)
  44. {dio=1;}
  45. else
  46. {dio=0;}
  47. clk=1;
  48. xie>>=1;
  49. }
  50. }

  51. void TM1629B_COM(uchar cmd)
  52. {
  53. stb=0;
  54. TM1629B_xie(cmd);
  55. stb=1;
  56. }

  57. void TM1629B_mie(void)
  58. {
  59. uchar i;
  60. stb=0;
  61. TM1629B_xie(0xc0);    //地址命令,00H显示地址
  62. for(i=0;i<14;i++)
  63. {TM1629B_xie(0x00);}  //所有显示为灭
  64. stb=1;
  65. }

  66. void TM1629B_init(void)
  67. {
  68. clk=1;
  69. stb=1;
  70. dio=1;
  71. TM1629B_COM(0x00);//显示模式
  72. TM1629B_COM(0x40);//写数据、地址自动增加
  73. TM1629B_mie();
  74. TM1629B_COM(0x89);//显示开,灰度2/16
  75. }

  76. void delay(int x)
  77. {
  78. uint i,j;
  79. for(i=x;i>0;i--)
  80. for(j=1100;j>0;j--);
  81. }

  82. void init_ADC(void);    //ADC初始化
  83. uint get_ADC_qw(void);  //获取气味AD结果
  84. void SC09A(void);//按键扫描

  85. uint a,b;//定时、风速
  86. bit g;//开机
  87. bit qh;//切换标志位

  88. uint num;            //时间定时

  89. uchar ir;           //红外线用
  90. uint startflag;
  91. uint bitnum;
  92. uchar irjsok,irjmok;
  93. uchar ircode[4];
  94. uchar irdata[33];

  95. void irjm(void)                   //把ir时间值解码
  96. {
  97. uchar k,i,j;
  98. uchar value;
  99. k=1;
  100. for(j=0;j<4;j++)
  101. {
  102. for(i=0;i<8;i++)
  103. {
  104. value=value>>1;       //移位保存
  105. if(irdata[k]>6)      //判断值1或0
  106. {
  107. value=value|0x80;
  108. }
  109. k++;
  110. }
  111. ircode[j]=value;
  112. irjmok=1;
  113. }
  114. }

  115. void irkz(void)         //一个码值对应一个控制
  116. {
  117. if(ircode[1]==0xFF)
  118.     {       
  119. if(ircode[2]==0x09)//第1个按钮,开关
  120. {
  121. fmq=1;
  122. delay(15);
  123. fmq=0;
  124. g=~g;         
  125. a=0;//开机复位,定时灯全灭
  126. b=1;//开机低速运行       
  127. if(g==1)
  128. {
  129. zzshu=0;
  130. fzshu=1000;
  131. }
  132. else
  133. {
  134.    zzshu=1000;
  135. fzshu=0;
  136. }
  137. }

  138. if(g==1)              //防止关机时,按键有声音
  139. {       
  140. if(ircode[2]==0x11) //第2个按钮,风速
  141. {
  142. fmq=1;
  143. delay(15);
  144. fmq=0;       
  145. b++;
  146. if(b>3)//风速循环
  147. {
  148. b=1;
  149. }       
  150. }

  151. if(ircode[2]==0x19)//第3个按钮,加湿
  152. {
  153. fmq=1;
  154. delay(15);
  155. fmq=0;

  156. kzj=~kzj;
  157. ledj=~ledj;//加湿指示灯
  158. }
  159. if(ircode[2]==0x17)//第4个按钮,负离子
  160. {
  161. fmq=1;
  162. delay(15);
  163. fmq=0;

  164. ledf=~ledf;
  165. kzf=~kzf;
  166. }

  167. if(ircode[2]==0x16) //第5个按钮,定时
  168. {
  169. fmq=1;
  170. delay(15);
  171. fmq=0;

  172. a=a+60;
  173.        if(a>360)
  174.    {
  175. a=0;
  176. }
  177. qh=1;//按定时按钮,显示自动切换成定时
  178. }       

  179. if(ircode[2]==0x04) //第6个按钮,切换
  180. {
  181. fmq=1;
  182. delay(15);
  183. fmq=0;

  184. qh=~qh;
  185. }
  186. }//if(g==1)
  187. }//if(ircode[1]==0xFF)
  188. }//irkz

  189. void main()
  190. {
  191. uint t;//ADC采样时间控制

  192. P3M1=0;//P3.0强推挽输出
  193. P3M0=0x01;

  194. fmq=1;//上电响
  195. delay(50);
  196. fmq=0;

  197.   delay(350);//电压稳定再进行IAP操作

  198. init_ADC();  
  199.     TM1629B_init();

  200. TMOD=0x12;//定时器1为方式1,定时器0为方式2
  201. EA=1;
  202. TH1=(65535-45872)/256;
  203. TL1=(65535-45872)%256;
  204. ET1=1;
  205. TH0=0x00;
  206. TL0=0x00;
  207. ET0=1;
  208. TR0=1;
  209. TR1=1;    //定时器1开,定时、滤网时间共用
  210. IT1=1;    //外部中断1设置
  211. EX1=1;    //外部中断1允许
  212. IT0=1;    //外部中断0设置
  213. EX0=1;    //外部中断0允许

  214. while(1)
  215. {

  216. if(irjsok)  //红外程序,用遥控器按钮6解除滤网报警
  217. {
  218.    irjm();
  219.        irjsok=0;
  220. }

  221.   if(irjmok)
  222. {
  223. irkz();
  224. irjmok=0;
  225. }
  226. //-----------------------------------------
  227. SC09A();//按键扫描
  228. //-----------------------------------------
  229. if(zzshu<150)//正转150个脉冲
  230. {
  231.    int i;
  232.    zzshu++;
  233. for(i=0;i<4;i++)
  234. {
  235. P1=P1&0x0f;       
  236.         P1=P1|zheng[i];
  237.   delay(8);//
  238. }
  239. }
  240. else
  241. {
  242. P1=P1&0x0f;       
  243. }

  244. if(fzshu<150)//反转150个脉冲
  245. {
  246.    int i;
  247.    fzshu++;
  248. for(i=0;i<4;i++)
  249. {
  250. P1=P1&0x0f;
  251.   P1=P1|fan[i];
  252.   delay(8);//
  253. }       
  254. }
  255. else
  256. {
  257. P1=P1&0x0f;       
  258. }
  259. //---------------------------------------------
  260.         if(a==1)
  261. {
  262. if(num>1100)     //最后1分钟算做55秒
  263. {
  264. g=0;
  265. a=0;//定时时间到关机,为了区别手动按到0值时不能关机
  266. }     
  267. }

  268.                 //红外线测试时加g=1

  269.         if(g==1)//开机时,执行以下程序
  270.         {
  271. if(a!=0) //定时器T0开始工作
  272. {  
  273. if(num>1205)//设置定时时间,1分钟设置为1205
  274.        {
  275. num=0;
  276.    a--;
  277. }
  278. }

  279. if(a==0)//a=0时,一直保持num值加不上去
  280. {
  281. num=0;
  282.    }


  283. if(qh==1)
  284. {
  285. ledkq=1;
  286. ledds=0;
  287. }
  288. else
  289. {
  290. ledkq=0;
  291. ledds=1;
  292. }

  293.     if(b==1)//低速
  294.    {
  295. kzd=0;        //低风
  296. kzz=1;     
  297. kzg=1;

  298.          ledd=0;
  299. ledz=1;
  300. ledg=1;
  301. }
  302.        if(b==2)//中速
  303.    {
  304. kzd=1;     //中风
  305. kzz=0;     
  306. kzg=1;

  307.          ledd=1;
  308. ledz=0;
  309. ledg=1;
  310. }
  311.        if(b==3)//高速
  312.    {
  313. kzd=1;     //高风
  314. kzz=1;     
  315. kzg=0;

  316.                 ledd=1;
  317. ledz=1;
  318. ledg=0;       
  319. }       

  320. TM1629B_COM(0x00);//显示模式
  321. TM1629B_COM(0x44);//写数据、固定地址
  322. stb=0;
  323. TM1629B_xie(0xc0);    //地址命令设置00H,这是个位
  324.        TM1629B_xie(table[TM_0]);
  325. stb=1;
  326. stb=0;
  327. TM1629B_xie(0xc2);    //地址命令设置02H,这是十位
  328.        TM1629B_xie(table[TM_2]);
  329. stb=1;
  330. stb=0;
  331. TM1629B_xie(0xc4);    //地址命令设置04H,这是百位
  332.        TM1629B_xie(table[TM_4]);
  333. stb=1;
  334. TM1629B_COM(0x89);//显示开,灰度2/16

  335. }
  336. else//g不等于1时,关闭输出
  337. {
  338. kzd=1;      //低速控制
  339. kzz=1;      //中速控制
  340. kzg=1;      //高速控制
  341. kzf=1;      //负离子控制
  342. kzj=1;      //加湿控制

  343. ledd=1;//低速指示灯
  344. ledz=1;//中速指示灯
  345. ledg=1;//高速指示灯
  346. ledj=1;//加湿指示灯
  347. ledf=1;//负离子指示灯
  348. ledkq=1;//空气质量指示灯
  349. ledds=1;//定时指示灯   
  350. qh=0;      //开机显示空气质量

  351. TM1629B_COM(0x00);//关闭屏幕操作
  352. TM1629B_COM(0x40);
  353. TM1629B_mie();
  354. TM1629B_COM(0x89);
  355. }

  356.               
  357. qwcaiji=qwcaiji+get_ADC_qw();       
  358. t++;       
  359. if(t==200)                  //调整模拟量处理的时间间隔
  360. {
  361. qw=qwcaiji/200;      //平均滤波
  362. t=0;
  363. qwcaiji=0;
  364. }

  365. if(qh==1)                   //空气质量与定时切换显示
  366. {
  367. TM_0=a%10;
  368. TM_2=a%100/10;
  369. TM_4=a/100;
  370. }
  371. else
  372. {
  373. TM_0=qw%10;      
  374. TM_2=qw%100/10;
  375. TM_4=qw/100;       
  376. }
  377.     }//while
  378. }//main

  379. void T1_time() interrupt 3           //定时、滤网用
  380. {
  381. TH1=(65535-45872)/256;
  382. TL1=(65535-45872)%256;
  383. num++;
  384. }

  385. void timer0() interrupt 1       //红外程序用
  386. {
  387. ir++;                       //一个周期ir值=0.278ms       
  388. }

  389. void int1() interrupt 2     //INT1下降沿接收红外信号
  390. {
  391. if(startflag)
  392. {
  393. if(ir>42)//检测引导吗
  394. {
  395. bitnum=0;
  396. }          
  397. irdata[bitnum]=ir;
  398. ir=0;
  399. bitnum++;
  400. if(bitnum==33)
  401. {
  402. bitnum=0;
  403. irjsok=1;
  404. startflag=0;       
  405. }
  406. }
  407. else
  408. {
  409. startflag=1;
  410. ir=0;
  411. }
  412. }



  413. void init_ADC(void)
  414. {  
  415. P1ASF    =0x01;    //选择P1.0通道
  416. ADC_RES  =0;       //清理结果寄存器的值  
  417. ADC_CONTR=0x80;    //开启电源、540个时钟、选用P1.0口
  418. _nop_();  
  419. _nop_();
  420. _nop_();  
  421. _nop_();
  422. }

  423. void SC09A(void)
  424. {
  425. if(key==0x0020)//开关
  426. {
  427. fmq=1;
  428. delay(15);
  429. fmq=0;

  430. g=~g;         
  431. a=0;//开机复位,定时灯全灭
  432. b=1;//开机低速运行
  433. if(g==1)
  434. {
  435. zzshu=0;
  436. fzshu=1000;
  437. }
  438. else
  439. {
  440.    zzshu=1000;
  441. fzshu=0;
  442. }
  443. key=0;
  444. }
  445. if(g==1)
  446. {
  447. if(key==0x1000)//风速
  448. {
  449. fmq=1;
  450. delay(15);
  451. fmq=0;       
  452. b++;
  453. if(b>3)//风速循环
  454. {
  455. b=1;
  456. }       

  457. key=0;
  458. }
  459. if(key==0x0800)//加湿
  460. {
  461. fmq=1;
  462. delay(15);
  463. fmq=0;

  464. kzj=~kzj;
  465. ledj=~ledj;//加湿指示灯

  466. key=0;
  467. }
  468. if(key==0x0400)//负离子
  469. {
  470. fmq=1;
  471. delay(15);
  472. fmq=0;

  473. ledf=~ledf;
  474. kzf=~kzf;

  475. key=0;
  476. }
  477. if(key==0x0080)//定时
  478. {
  479. fmq=1;
  480. delay(15);
  481. fmq=0;

  482. a=a+60;
  483.        if(a>360)
  484.    {
  485. a=0;
  486. }
  487. qh=1;//按定时按钮,显示自动切换成定时

  488. key=0;
  489. }

  490. if(key==0x0040)//切换
  491. {
  492. fmq=1;
  493. delay(15);
  494. fmq=0;

  495. qh=~qh;

  496. key=0;
  497. }
  498. }//        if(g==1)
  499. }
  500.   
  501. uint get_ADC_qw(void)
  502. {  
  503.      uchar mn=0;  
  504.      ADC_CONTR=0X88; //开电源、开始转换ADC_START=1,选择P1.0
  505.      _nop_();  
  506.      _nop_();
  507.      _nop_();  
  508.      _nop_();  
  509.      while(!(ADC_CONTR&0X10)); //转换结束ADC_FLAG=1
  510. mn=ADC_RES;
  511.      ADC_CONTR&=~0X10;         //ADC_FLAG清零
  512.      _nop_();  
  513.      _nop_();
  514.      _nop_();  
  515.      _nop_();   
  516.      return mn;
  517. }  

  518. void int0() interrupt 0     //INT0下降沿接收SC09A
  519. {
  520. uchar i,j,temp;
  521. uchar dizi=0x81;
  522. uint keyzhi=0xffff;
  523. bit bit_temp;

  524. EA=0; // 屏蔽全局中断
  525. SCL=1;
  526. for(i=0;i<50;i++){}          //延时
  527. SDA=0;                       // 拉低SDA,端口送出START 信号
  528. for(i=0;i<50;i++){}          //延时

  529. for(j=0;j<8;j++)//发送8位地址
  530. {       
  531. SCL=0;
  532. temp=dizi&0x80;
  533. for(i=0;i<50;i++){}          //延时
  534. if(temp==0x80)
  535. SDA=1;
  536. else
  537. SDA=0;
  538. dizi=dizi<<1;
  539. for(i=0;i<50;i++){}          //延时
  540. SCL=1;
  541. for(i=0;i<50;i++){}          //延时
  542. }

  543. SDA=1; //释放SDA 端口,将SDA设置为输入端口
  544. SCL=0;
  545. for(i=0;i<50;i++){}          //延时
  546. SCL=1;
  547. for(i=0;i<50;i++){}          //延时

  548. //此处读ack回应,不做处理


  549. //读16位按键数据
  550. for(j=0;j<16;j++)
  551. {
  552. SCL=0;
  553. for(i=0;i<50;i++){}          //延时
  554. SCL=1;
  555. for(i=0;i<50;i++){}          //延时
  556. bit_temp=SDA;
  557. if(bit_temp)
  558. {
  559. keyzhi=keyzhi<<1;
  560. keyzhi=keyzhi|0x01;
  561. }
  562. else
  563. {
  564. keyzhi=keyzhi<<1;
  565. }
  566. }

  567. SCL=0;
  568. SDA=1;
  569. for(i=0;i<50;i++){}          //延时
  570. SCL=1;
  571. for(i=0;i<50;i++){}          //延时
  572. SCL=0;
  573. SDA=0; //发送 NACK 信号
  574. for(i=0;i<50;i++){}          //延时
  575. SCL=1;
  576. for(i=0;i<50;i++){}          //延时
  577. SDA=1; //结束

  578. key=keyzhi^0xffff;//异或

  579. EA=1; //全局中断使能
  580. /*
  581. CIN0   0x1000     S1风速
  582. CIN1   0x0800     S2加湿
  583. CIN2   0x0400     S3负离子
  584. CIN5   0x0080     S4定时
  585. CIN6   0x0040     S5切换
  586. CIN7   0x0020     S6开关
  587. */
  588. }
复制代码


回复

使用道具 举报

ID:88606 发表于 2018-1-13 09:23 | 显示全部楼层
能看看电路原理图吗?
回复

使用道具 举报

ID:371662 发表于 2018-7-14 21:45 | 显示全部楼层
你好!可以共享学习加湿器程序?QQ:2362034
回复

使用道具 举报

ID:619604 发表于 2019-12-11 19:56 | 显示全部楼层
看看产品电路原理图
回复

使用道具 举报

ID:108573 发表于 2020-2-22 10:28 | 显示全部楼层
没有原理图,程序看不懂
回复

使用道具 举报

ID:97678 发表于 2020-2-23 14:05 | 显示全部楼层
能够提供电气原理图吗?
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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