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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機控制風扇程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:329632 發表于 2018-5-14 15:38 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
單片機源程序如下:
  1. //宏定義
  2. #define uchar unsigned char
  3. #define uint unsigned int

  4. //包含頭文件
  5. #include <reg52.h>
  6. #include <18b20.h>
  7. #include <stdlib.h>
  8. #include <intrins.h>
  9. #include <eeprom52.h>
  10. #define Imax 14000    //此處為晶振為11.0592時的取值,
  11. #define Imin 8000    //如用其它頻率的晶振時,
  12. #define Inum1 1450    //要改變相應的取值。
  13. #define Inum2 700
  14. #define Inum3 3000
  15. sbit K1=P1^1;
  16. sbit K2=P1^2;
  17. sbit K3=P1^3;                  //按鍵定義
  18. sbit PWM=P3^6;                  //PWM輸出
  19. sbit BUZZ=P1^4;                  //蜂鳴器控制腳
  20. sbit RSD=P2^0;                  //熱釋電引腳
  21. unsigned char Im[4]={0x00,0x00,0x00,0x00};
  22. uchar displaydata[4]; //顯示暫存數組
  23. //全局變量
  24. char f,dang,count,count1,a_a;  //檔位
  25. unsigned long m,Tc;
  26. unsigned char IrOK;          //定義紅外工作變量
  27. void   jisuan();          //聲明計算函數
  28. uchar mode;
  29. char sec_b=0;
  30. bit flag_b=0;
  31. uint TH,TL;                          //上下限變量
  32. uchar baif,suiji;
  33. unsigned char code duan[17]={
  34. 0x5F,0x44,0x9D,0xD5,0xC6,0xD3,0xDB,0x47,0xDF,0xD7,    0xCF,0xDA,0x98,0xDC,0x9B,0x8B}; //接線從高到低:g c dp d e b f a
  35. //0、1、2、3、4、5、6、7、8、9、A、b、c、d、E、F的顯示碼                                                          //
  36. unsigned char code wei[8]={          //數碼管的位選
  37. 0xef,0xdf,0xbf,0x7f,0xfe,0xfd,0xfb,0xf7};
  38. uchar code zhuanhuan[4]={10,5,3,0};//轉換數組
  39. void write_eeprom()                           //內部eeprom寫函數
  40. {

  41.         SectorErase(0x2000);                   //清空
  42.         SectorErase(0x2c00);
  43.         SectorErase(0x2e00);
  44.         byte_write(0x2c00,TH/256);       
  45.         byte_write(0x2c01,TH%256);
  46.         byte_write(0x2c02,TL/256);
  47.         byte_write(0x2c03,TL%256);           //將上下限數據保存到eeprom
  48.         byte_write(0x2c04,dang);       
  49.         byte_write(0x2c05,mode);               
  50.         byte_write(0x2060,0x01);

  51. }

  52. /******************把數據從單片機內部eeprom中讀出來*****************/
  53. void read_eeprom()                                                                                                                                  
  54. {

  55.     mode = byte_read(0x2c05);
  56.         dang = byte_read(0x2c04);
  57.         TH = byte_read(0x2c00)*256+byte_read(0x2c01);
  58.         TL = byte_read(0x2c02)*256+byte_read(0x2c03);
  59.         a_a = byte_read(0x2060);
  60.          
  61. }

  62. /**************開機自檢eeprom初始化*****************/
  63. void init_eeprom()
  64. {
  65.         a_a = byte_read(0x2060);
  66.         if(a_a != 1)                //新的單片機初始單片機內問eeprom
  67.         {
  68.        
  69.                 a_a = 1;
  70.                 write_eeprom();           //保存數據
  71.         }       
  72. }

  73. void delay(uint z)         //延時函數
  74. {
  75.   uint z1,z2;
  76.   for(z1=0;z1<z;z1++)
  77.   for(z2=0;z2<110;z2++);
  78. }

  79. void display()                          //顯示函數
  80. {
  81.   uchar i;
  82. if(mode==0)            //無極變速
  83. {
  84.    displaydata[0]=0x00;
  85.    displaydata[1]=duan[disdata[1]];
  86.    displaydata[2]=duan[disdata[2]]|0x20;
  87.    displaydata[3]=duan[disdata[3]];
  88. }
  89.   else if(mode==1)                    //上限
  90. {
  91.    displaydata[0]=0xce;        //H                   11001110
  92.    displaydata[1]=duan[TH%1000/100];
  93.    displaydata[2]=duan[TH%100/10]|0x20;
  94.    displaydata[3]=duan[TH%10];
  95. }
  96.   else if(mode==2)                                   //下限
  97. {
  98.    displaydata[0]=0x1a;                         //L   00111000
  99.    displaydata[1]=duan[TL%1000/100];
  100.    displaydata[2]=duan[TL%100/10]|0x20;
  101.    displaydata[3]=duan[TL%10];
  102. }
  103.    else if(mode==3)          //檔位0到3檔
  104. {
  105.    displaydata[0]=duan[dang];
  106.    displaydata[1]=0x80;         //01000000
  107.    displaydata[2]=duan[disdata[1]];
  108.    displaydata[3]=duan[disdata[2]];
  109. }
  110.     else if(mode==4)
  111. {
  112.    displaydata[0]=0xda;        //b自然風
  113.    displaydata[1]=duan[disdata[1]];
  114.    displaydata[2]=duan[disdata[2]]|0x20;
  115.    displaydata[3]=duan[disdata[3]];
  116. }

  117.         for(i=0;i<4;i++)                //循環4次顯示4位數碼管
  118.         {
  119.             P2=wei[i];                        //選中位
  120.                 P0=displaydata[i];        //送入顯示碼
  121.             delay(3);                        //延時
  122.                 P2=0xff;                        //關閉位
  123.                 P0=0x00;                        //復位顯示碼
  124.         }

  125. }
  126. void key()                                                          //按鍵函數
  127. {
  128.   if(K1==0||(Im[2]==0x47&&IrOK==1))          //按鍵1按下或者遙控器上的按鍵按下
  129.   {
  130.    delay(5);                                                  //延時去抖

  131.     if(K1==0||(Im[2]==0x47&&IrOK==1)) //再次判斷按鍵按下
  132.         {
  133.                 BUZZ=0;
  134.                 delay(20);
  135.                 BUZZ=1;                                                  //按鍵音
  136.          mode++;                                                  //模式加
  137.          if(mode>4)                                                  //模式加到大于4
  138.          mode=0;                                                  //模式清零
  139. //         Im[2]=0;
  140.          IrOK=0;                                                  //變量清零
  141.          write_eeprom();                                  //寫入eeprom數據
  142.          while(!K1);                                          //按鍵釋放
  143.         }
  144.   }
  145.   if(K2==0||(Im[2]==0x40&&IrOK==1))
  146.   {
  147.    delay(5);

  148.     if(K2==0||(Im[2]==0x40&&IrOK==1))
  149.         {
  150.                 BUZZ=0;
  151.                 delay(20);
  152.                 BUZZ=1;
  153.          if(mode==1)                                        //模式等于1時
  154.          {
  155.           TH++;                                                        //上限加
  156.           if(TH>999)                                        //上限加到大于99.9度
  157.                  
  158.           TH=TL+1;                                                //上限等于下限加一
  159.          }
  160.          else if(mode==2)                                //模式等于2時
  161.          {
  162.           TL++;                                                        //下限加
  163.           if(TL>=TH)                                        //下限加到大于等于上限
  164.           TL=TH-1;                                                //下限等于上限減一
  165.          }
  166.           else if(mode==3)                                //模式等于3時
  167.          {
  168.           dang++;                                                //檔位加一
  169.           if(dang>3)                                        //檔位大于3時
  170.           dang=0;                                                //檔位清零
  171.          }
  172.          Im[2]=0;
  173.          IrOK=0;                                                //紅外變量清零
  174.           write_eeprom();                                //寫入eeprom數據
  175.          while(!K2);                                        //按鍵釋放
  176.         }

  177.   }

  178.   if(K3==0||(Im[2]==0x19&&IrOK==1))
  179.   {
  180.    delay(5);

  181.     if(K3==0||(Im[2]==0x19&&IrOK==1))
  182.         {
  183.                 BUZZ=0;
  184.                 delay(20);
  185.                 BUZZ=1;
  186.          if(mode==1)
  187.          {
  188.           TH--;
  189.           if(TH<=TL)
  190.           TH=TL+1;
  191.          }
  192.          else if(mode==2)
  193.          {
  194.           TL--;
  195.           if(TL>=TH)
  196.           TL=TH-1;
  197.          }
  198.           else if(mode==3)
  199.          {
  200.            dang--;
  201.           if(dang<0)
  202.           dang=3;
  203.          }
  204.          Im[2]=0;
  205.          IrOK=0;
  206.           write_eeprom();
  207.          while(!K3);
  208.         }
  209.   }
  210. }
  211. void jisuan()                                                          //計算函數
  212. {
  213.   if((mode==0||mode==1||mode==2)&&RSD==1) //模式0、1、2并且熱釋電有信號時
  214.   {
  215.     if(tvalue<=TL)                                                 //溫度小于下限時
  216.         PWM=1;                                                                 //關閉輸出,占空比0%
  217.         else if(tvalue>=TH)                                         //溫度大于等于上限
  218.         PWM=0;                                                                 //打開輸出,占空比100%
  219.         else                                                                  //其他狀態時
  220.         {
  221.           baif=(((tvalue-TL)*50)/(TH-TL));   //占空比控制變量計算得到
  222. //計算方法:當前溫度減去下限值乘以5再除以上限減下限
  223.           if(count1>baif) //根據變量判斷占空比大小
  224.           PWM=1;                  //關閉風扇
  225.           else
  226.           PWM=0;                  //打開風扇
  227.         }
  228.   }
  229.   else if(mode==3)                                           //模式3時
  230.   {
  231.     if(count1>(zhuanhuan[dang]*5))           //根據檔位計算出占空比
  232.         PWM=0;
  233.         else
  234.         PWM=1;
  235.   }
  236.   else if((mode==4&&flag_b==0)&&RSD==1)        //模式4時,熱釋電有信號
  237.   {
  238.    suiji=rand();                                  //讀隨機函數
  239.    suiji=suiji%23;                                  //隨機數計算
  240.    if(10>suiji)                                          //判斷隨機數是否小于10
  241.    PWM=0;                                                  //輸出開
  242.    else                                                          //隨機數大于等于10
  243.    PWM=1;                                                  //輸出關
  244.         flag_b=1;                                          //變量置1
  245.   }
  246.   if(RSD==0&&mode!=3)                          //熱釋電沒有信號時
  247.   PWM=1;                                                  //關閉輸出
  248. }
  249. void main()                                                  //主函數
  250. {
  251.   uint count;                                          //定義變量
  252.   EA=1;                                                          //打開中斷總開關
  253.   EX1=1;                                                  //打開外部中斷1
  254.   IT1=1;                                                  //下降沿有效
  255.   TMOD=0x11;                                          //定時器工作方式

  256.   TR0=0;                                                  //關閉T0
  257.   TH0=0;
  258.   TL0=0;                                                  //初值0
  259.   ET1=1;                                                  //T1允許中斷

  260.   TR1=1;                                                  //T1打開中斷
  261.   TH1=0xfc;
  262.   TL1=0x18;                                                  //T1初值1ms
  263.   mode=0;                                                  //初始模式0
  264.   TH=300;
  265.   TL=200;                                                  //上下限初始值
  266.   init_eeprom();                                  //初始化eeprom
  267.   read_eeprom();                                  //讀取eeprom數據
  268. while(1)                                                  //進入循環
  269.         {            
  270.                 jisuan();                                  //計算函數
  271.                 count++;                                  //變量加
  272.                 if(count>200)                          //加到大于200
  273.                 {
  274.                         count=0;                          //清零
  275.                         TR1=0;                                  //關閉定時器T1
  276.                         read_wendu();                  //讀取溫度
  277.                         TR1=1;                                  //打開定時器T1
  278.                 }
  279.                 jisuan();                                  //計算函數
  280.                 display();                                  //顯示函數
  281.                 key();                                          //按鍵函數
  282.                 jisuan();                                  //計算函數
  283.         }
  284. }
  285. void timer1() interrupt 3                  //定時器T1工作函數
  286. {
  287. TH1=0xfc;
  288. TL1=0x18;                                                  //重新賦初值

  289.   count1++;                                                  //加
  290.   if(count1>50)
  291.   {
  292.           count1=0;
  293.         if(mode==4&&flag_b==1)                 //模式等于4時,變量為1
  294.         {
  295.                 sec_b++;                                 //變量加
  296.                 if(sec_b>=8)                         //加到8時
  297.                 {
  298.                         sec_b=0;                         //清零
  299.                         flag_b=0;                         //清零
  300.                 }
  301.         }
  302.   }
  303. }

  304. void intersvr1(void) interrupt 2                 //紅外工作函數
  305. {
  306. TR0=1;
  307. Tc=TH0*256+TL0;//提取中斷時間間隔時長
  308. TH0=0;
  309. TL0=0;         //定時中斷重新置零
  310. if((Tc>Imin)&&(Tc<Imax))
  311. {
  312.         m=0;
  313.         f=1;

  314.         return;
  315. }       //找到啟始碼
  316. if(f==1)
  317. {
  318.     if(Tc>Inum1&&Tc<Inum3)
  319.     {
  320.            Im[m/8]=Im[m/8]>>1|0x80; m++;
  321.     }
  322.     if(Tc>Inum2&&Tc<Inum1)
  323.     {
  324.       Im[m/8]=Im[m/8]>>1; m++; //取碼
  325.            }
  326.            if(m==32)
  327.     {
  328.       m=0;  
  329.       f=0;
  330.        
  331.       if(Im[2]==~Im[3])
  332.       {
  333.            IrOK=1;
  334.                           TR0=0;
  335.            }
  336.       else
  337.           {
  338.            IrOK=0;   //取碼完成后判斷讀碼是否正確

  339.            }
  340.     }
  341.                //準備讀下一碼
  342. }


  343. }


  344. Ds18b20
  345. sbit DQ=P1^0;//ds18b20與單片機連接口

  346. uchar data disdata[5];
  347. uint tvalue;//溫度值
  348. uchar tflag;//溫度正負標志

  349. /******************************ds1820程序***************************************/
  350. void delay_18B20(uchar k)//延時1微秒
  351. {
  352.         while(k--);
  353. }

  354. void ds1820rst()/*ds1820復位*/
  355. {  
  356.      
  357.          DQ = 1;          //DQ復位
  358.          delay_18B20(4);  //延時
  359.          DQ = 0;          //DQ拉低
  360.          delay_18B20(100); //精確延時大于480us
  361.          DQ = 1;          //拉高
  362.          delay_18B20(40);         
  363. }  
  364.   
  365. uchar ds1820rd()/*讀數據*/
  366. {   
  367.      unsigned char i=0;
  368.          unsigned char dat = 0;
  369.          for (i=8;i>0;i--)
  370.          {   DQ = 0; //給脈沖信號
  371.                   dat>>=1;
  372.                   DQ = 1; //給脈沖信號
  373.                   if(DQ)
  374.                   dat|=0x80;
  375.                   delay_18B20(10);//延時106us
  376.          }
  377.         return(dat);
  378. }

  379. void ds1820wr(uchar wdata)/*寫數據*/
  380. {
  381.     unsigned char i=0;
  382.     for (i=8; i>0; i--)
  383.    {
  384.      DQ = 0;
  385.      DQ = wdata&0x01;
  386.      delay_18B20(10);//延時106us
  387.      DQ = 1;
  388.      wdata>>=1;
  389.    }
  390. }
  391.   


  392. uint read_wendu()/*讀取溫度值并轉換*/
  393. {
  394.   uchar a,b;
  395.   ds1820rst();   
  396.   ds1820wr(0xcc);//*跳過讀序列號*/
  397.   ds1820wr(0x44);//*啟動溫度轉換*/
  398.   ds1820rst();   
  399.   ds1820wr(0xcc);//*跳過讀序列號*/
  400.   ds1820wr(0xbe);//*讀取溫度*/
  401.   a=ds1820rd();
  402.   b=ds1820rd();
  403.   tvalue=b;
  404.   tvalue<<=8;
  405.   tvalue=tvalue|a;
  406.   if(tvalue<0x0fff)
  407.   tflag=0;
  408.   else
  409.   {
  410.     tvalue=~tvalue+1;
  411.         tflag=1;
  412.   }
  413.   tvalue=tvalue*(0.625);//溫度值擴大10倍,精確到1位小數
  414.      disdata[1]=tvalue%1000/100;//十位數
  415.     disdata[2]=tvalue%100/10;//個位數
  416.     disdata[3]=tvalue%10;//小數位
  417.   return(tvalue);
  418. }

  419. eeprom
  420. #ifndef _EEPROM52_H_
  421. #define _EEPROM52_H_


  422. /********STC89C51扇區分布*******
  423. 第一扇區:1000H--11FF
  424. 第二扇區:1200H--13FF
  425. 第三扇區:1400H--15FF
  426. 第四扇區:1600H--17FF
  427. 第五扇區:1800H--19FF
  428. 第六扇區:1A00H--1BFF
  429. 第七扇區:1C00H--1DFF
  430. 第八扇區:1E00H--1FFF
  431. *****************/

  432. /********STC89C52扇區分布*******
  433. 第一扇區:2000H--21FF
  434. 第二扇區:2200H--23FF
  435. 第三扇區:2400H--25FF
  436. 第四扇區:2600H--27FF
  437. 第五扇區:2800H--29FF
  438. 第六扇區:2A00H--2BFF
  439. 第七扇區:2C00H--2DFF
  440. 第八扇區:2E00H--2FFF
  441. *****************/


  442. #define RdCommand 0x01 //定義ISP的操作命令
  443. #define PrgCommand 0x02
  444. #define EraseCommand 0x03
  445. #define Error 1
  446. #define Ok 0
  447. #define WaitTime 0x01 //定義CPU的等待時間
  448. sfr ISP_DATA=0xe2;  //寄存器申明
  449. sfr ISP_ADDRH=0xe3;
  450. sfr ISP_ADDRL=0xe4;
  451. sfr ISP_CMD=0xe5;
  452. sfr ISP_TRIG=0xe6;
  453. sfr ISP_CONTR=0xe7;

  454. /* ================ 打開 ISP,IAP 功能 ================= */
  455. void ISP_IAP_enable(void)
  456. {
  457.          EA = 0;       /* 關中斷   */
  458.          ISP_CONTR = ISP_CONTR & 0x18;       /* 0001,1000 */
  459.          ISP_CONTR = ISP_CONTR | WaitTime; /* 寫入硬件延時 */
  460.          ISP_CONTR = ISP_CONTR | 0x80;       /* ISPEN=1  */
  461. }
  462. /* =============== 關閉 ISP,IAP 功能 ================== */
  463. void ISP_IAP_disable(void)
  464. {
  465.          ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
  466.          ISP_TRIG = 0x00;
  467.          EA   =   1;   /* 開中斷 */
  468. }
  469. /* ================ 公用的觸發代碼 ==================== */
  470. void ISPgoon(void)
  471. {
  472.          ISP_IAP_enable();   /* 打開 ISP,IAP 功能 */
  473.          ISP_TRIG = 0x46;  /* 觸發ISP_IAP命令字節1 */
  474.          ISP_TRIG = 0xb9;  /* 觸發ISP_IAP命令字節2 */
  475.          _nop_();
  476. }
  477. /* ==================== 字節讀 ======================== */
  478. unsigned char byte_read(unsigned int byte_addr)
  479. {
  480.         EA = 0;
  481.          ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址賦值 */
  482.          ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  483.          ISP_CMD   = ISP_CMD & 0xf8;   /* 清除低3位  */
  484.          ISP_CMD   = ISP_CMD | RdCommand; /* 寫入讀命令 */
  485.          ISPgoon();       /* 觸發執行  */
  486.          ISP_IAP_disable();    /* 關閉ISP,IAP功能 */
  487.          EA  = 1;
  488.          return (ISP_DATA);    /* 返回讀到的數據 */
  489. }
  490. /* ================== 扇區擦除 ======================== */
  491. void SectorErase(unsigned int sector_addr)
  492. {
  493.          unsigned int iSectorAddr;
  494.          iSectorAddr = (sector_addr & 0xfe00); /* 取扇區地址 */
  495.          ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
  496.          ISP_ADDRL = 0x00;
  497.          ISP_CMD = ISP_CMD & 0xf8;   /* 清空低3位  */
  498.          ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3  */
  499.          ISPgoon();       /* 觸發執行  */
  500.          ISP_IAP_disable();    /* 關閉ISP,IAP功能 */
  501. }
  502. /* ==================== 字節寫 ======================== */
  503. void byte_write(unsigned int byte_addr, unsigned char original_data)
  504. {
  505.          EA  = 0;
  506. //         SectorErase(byte_addr);
  507.          ISP_ADDRH = (unsigned char)(byte_addr >> 8);  /* 取地址  */
  508.          ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  509.          ISP_CMD  = ISP_CMD & 0xf8;    /* 清低3位 */
  510.          ISP_CMD  = ISP_CMD | PrgCommand;  /* 寫命令2 */
  511.          ISP_DATA = original_data;   /* 寫入數據準備 */
  512.          ISPgoon();       /* 觸發執行  */
  513.          ISP_IAP_disable();     /* 關閉IAP功能 */
  514.          EA =1;
  515. }
  516. #endif

復制代碼



chengxu.doc

68 KB, 下載次數: 15, 下載積分: 黑幣 -5

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

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美一级三级在线观看 | 久久成人一区 | 成人av观看 | 粉嫩一区二区三区国产精品 | 日韩a在线 | 天天综合永久 | 久久精品久久久久久 | 一区二区三区国产精品 | 久久久久久艹 | 成人在线视频一区 | 久久天堂 | 国产亚洲一区二区三区在线 | 黄色一级大片在线观看 | 九九久久99 | av黄色免费在线观看 | 成年人免费在线视频 | xx性欧美肥妇精品久久久久久 | 天天草av | 亚洲精品一区二区网址 | 亚洲91视频 | 一区二区国产精品 | 欧美日韩不卡在线 | 岛国二区 | 国产精品国产精品国产专区不卡 | 久久精品中文字幕 | 国产精品久久久久久久久 | 日本不卡一区 | 日韩欧美一区二区三区免费看 | 国产美女一区二区 | 日韩中文字幕网 | 日韩中文字幕 | 久久久www成人免费精品 | 日韩成人在线免费视频 | 香蕉大人久久国产成人av | 国产成人免费视频网站高清观看视频 | 狠狠爱免费视频 | 午夜爽爽爽男女免费观看影院 | 羞视频在线观看 | 一区二区不卡高清 | 日韩精品av一区二区三区 | 精品欧美黑人一区二区三区 |