風扇控制系統--初版

風扇控制系統--初版

利用51單片機實現的風扇控制系統,包括硬件到軟件的實現。(功能未完,待完善)

圖片





硬件的代碼如下:
 /********************************************************************
* 文件名  : 風扇控制智能系統 
* 描述    :  
             1、紅外線遙控板 控制風扇開關 擋速
             2、液晶顯示器 顯示風扇的工作情況
             3、客戶端顯示風扇工作情況
             4、客戶端控制風扇工作
             5、定時開關風扇  LED倒數
             6、開啓風扇時 記錄上次的擋速
* 創建人  : wu_zhuojun,2014年2月16日 北京
* 版本號  : 2.0
***********************************************************************/
 
#include <reg51.h>
#include <intrins.h>

#define uchar unsigned char
#define uint  unsigned int

uchar LCD_ID_1[16] = {"I have a dream!"};
uchar LCD_ID_2[16] = {"Speed: 0"};

void delay(uchar x);  //x*0.14MS
void delay1(int ms);
void beep();

sbit IRIN = P3^3;         //紅外接收器數據線
sbit BEEP = P1^5;         //蜂鳴器驅動線
sbit RELAY= P1^4;         //繼電器驅動線

uchar IRCOM[7];

sbit E=P2^7;//1602使能引腳
sbit RW=P2^6;//1602讀寫引腳
sbit RS=P2^5;//1602數據/命令選擇引腳


/********************************************************************
* 名稱 : delay()
* 功能 : 延時,延時時間大概爲140US。
* 輸入 : 無
* 輸出 : 無
***********************************************************************/

void Delay2()
{
int i,j;
for(i=0; i<=10; i++)
for(j=0; j<=2; j++)
;
}


/********************************************************************
* 名稱 : enable(uchar del)
* 功能 : 1602命令函數
* 輸入 : 輸入的命令值
* 輸出 : 無
***********************************************************************/

void enable(uchar del)
{
P0 = del;
RS = 0;
RW = 0;
E = 0;
Delay2();
E = 1;
Delay2();
}

/********************************************************************
* 名稱 : write(uchar del)
* 功能 : 1602寫數據函數
* 輸入 : 需要寫入1602的數據
* 輸出 : 無
***********************************************************************/

void write(uchar del)
{
P0 = del;
RS = 1;
RW = 0;
E = 0;
Delay2();
E = 1;
Delay2();
}

/********************************************************************
* 名稱 : L1602_init()
* 功能 : 1602初始化,請參考1602的資料
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void L1602_init(void)
{
enable(0x01);
enable(0x38);
enable(0x0c);
enable(0x06);
enable(0xd0);
}

/********************************************************************
* 名稱 : L1602_char(uchar hang,uchar lie,char sign)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符顯示"b" ,調用該函數如下
L1602_char(1,5,'b')
* 輸入 : 行,列,需要輸入1602的數據
* 輸出 : 無
***********************************************************************/
void L1602_char(uchar hang,uchar lie,char sign)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
write(sign);
}

/********************************************************************
* 名稱 : L1602_string(uchar hang,uchar lie,uchar *p)
* 功能 : 改變液晶中某位的值,如果要讓第一行,第五個字符開始顯示"ab cd ef" ,調用該函數如下
L1602_string(1,5,"ab cd ef;")
* 輸入 : 行,列,需要輸入1602的數據
* 輸出 : 無
***********************************************************************/
void L1602_string(uchar hang,uchar lie,uchar *p)
{
uchar a;
if(hang == 1) a = 0x80;
if(hang == 2) a = 0xc0;
a = a + lie - 1;
enable(a);
while(1)
{
if(*p == '\0') break;
write(*p);
p++;
}
}

/********************************************************************
* 名稱 : Com_Init()
* 功能 : 初始化串口程序,晶振11.0592, 波特率9600
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void Com_Init(void)
{
     TMOD = 0x20;
     PCON = 0x00;
     SCON = 0x50;
     TH1 = 0xFd;
     TL1 = 0xFd;
     TR1 = 1;
}

/********************************************************************
* 名稱 : main()
* 功能 : 
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
main()
{
    //所要發送的數據 所用的串口是燒寫程序的串口,並不是9針串口
//uchar code Buffer[] = "wo shi wuzhuojun"; 
    //uchar *p = Buffer;
//P2 = 0x00;
//p = Buffer;

    //=========初始化紅外線控制 Begin=======//
    IE = 0x84;                 //允許總中斷中斷,使能 INT1 外部中斷
    TCON = 0x10;               //觸發方式爲脈衝負邊沿觸發
    
    IRIN=1;                    //I/O口初始化
    BEEP=1;
    RELAY=1; 
    //=========初始化紅外線控制 End=======//
    delay1(10);                 //延時
    L1602_init();               //初始化LCD

             
L1602_string(1, 1, LCD_ID_1);  //設置 液晶顯示屏  顯示LCD_ID_1的內容
L1602_string(2, 1, LCD_ID_2);  //設置 液晶顯示屏  顯示LCD_ID_2的內容


   //=======初始化串口 Begin=======//
Com_Init();

#if 0
while(1)
{
SBUF = *p;
while(!TI)                   //如果發送完畢,硬件會置位TI
{
_nop_();
}
p++;
if(*p == '\0') break;//在每個字符串的最後,會有一個'\0'
TI = 0;                //TI清零
}
#endif
    //=======初始化串口 Begin=======//

    while(1);

} //end main

/********************************************************************
* 名稱 : IR_IN interrupt 2 using 0
* 功能 : 接收紅外線數據,並中斷處理液晶屏顯示
* 輸入 : 無
* 輸出 : 無
***********************************************************************/
void IR_IN() interrupt 2 using 0
{
    //======初始化串口發送數據 變量  Begin=======//
uchar code strSpeed[][4] = {"0", "1", "2", "3" }; 
    uchar *p = strSpeed[0];  //初始化爲 0 檔
    //======初始化串口發送數據 變量  End=======//

    unsigned char j,k,N=0;
    EX1 = 0;   
delay(15);
if (IRIN==1) 
    { 
        EX1 =1;
   return;
                           //確認IR信號出現
    while (!IRIN)            //等IR變爲高電平,跳過9ms的前導低電平信號。
    {
        delay(1);
    }

    for (j=0;j<4;j++)         //收集四組數據
    { 
        for (k=0;k<8;k++)        //每組數據有8位
        {
           while (IRIN)            //等 IR 變爲低電平,跳過4.5ms的前導高電平信號。
           {
               delay(1);
           }
           while (!IRIN)          //等 IR 變爲高電平
           {
               delay(1);
           }
           while (IRIN)           //計算IR高電平時長
           {
               delay(1);
               N++;           
               if (N>=30)
          { 
                   EX1=1;
              return;
               } //if (N>=30)    //0.14ms計數過長自動離開。
           } //while (IRIN)      //高電平計數完畢                
           IRCOM[j]=IRCOM[j] >> 1;            //數據最高位補“0”
           if (N>=8) 
           {
               IRCOM[j] = IRCOM[j] | 0x80;    //數據最高位補“1”
           }  //if (N>=8)
           N=0;
       }//for (k=0;k<8;k++)
    }//for (j=0;j<4;j++) 
   
   if (IRCOM[2]!=~IRCOM[3])
   { 
       EX1=1;
       return; 
   }

   IRCOM[5]=IRCOM[2] & 0x0F;     //取鍵碼的低四位
   IRCOM[6]=IRCOM[2] >> 4;       //右移4次,高四位變爲低四位

   if(IRCOM[5]>9)
   { 
        IRCOM[5]=IRCOM[5]+0x37;
   }
   else
 IRCOM[5]=IRCOM[5]+0x30;

   if(IRCOM[6]>9)
    { 
        IRCOM[6]=IRCOM[6]+0x37;
    }
   else
 IRCOM[6]=IRCOM[6]+0x30;

    //=======控制 液晶顯示屏顯示數據 Begin=========//
    //L1602_char(2,10,IRCOM[5]); 
    //L1602_char(2,9,IRCOM[6]);
 
    if( ('4' == IRCOM[6]) && ('5' == IRCOM[5]))  //觸發開關鍵
    { 
        p = strSpeed[0];   //檔速
        L1602_char(2,8,'0');
    }
    else if( ('0' == IRCOM[6]) && ('C' == IRCOM[5]))  //觸發1號鍵
    {
        
        p = strSpeed[1];   //檔速
        L1602_char(2,8,'1');
    }
    else if( ('1' == IRCOM[6]) && ('8' == IRCOM[5]))  //觸發2號鍵
    {
        p = strSpeed[2];   //檔速
        L1602_char(2,8,'2');
    }
    else if( ('5' == IRCOM[6]) && ('E' == IRCOM[5]))  //觸發3號鍵
    {
        p = strSpeed[3];   //檔速
        L1602_char(2,8,'3');
    }
    //=======控制 液晶顯示屏顯示數據 End=========//


    //=======發送串口數據 Begin=========//
while(1)
{
SBUF = *p;
while(!TI)                   //如果發送完畢,硬件會置位TI
{
_nop_();
}
p++;
if(*p == '\0') break;//在每個字符串的最後,會有一個'\0'
TI = 0;                //TI清零
}
    //=======發送串口數據 End=========//

     //beep();
     EX1 = 1; 

/**********************************************************/
void beep()
{
  unsigned char i;
  for (i=0;i<100;i++)
   {
   delay(4);
   BEEP=!BEEP;                 //BEEP取反
   } 
  BEEP=1;                      //關閉蜂鳴器
}
/**********************************************************/
void delay(unsigned char x)    //x*0.14MS
{
 unsigned char i;
  while(x--)
 {
  for (i = 0; i<13; i++) {}
 }
}

/**********************************************************/
void delay1(int ms)
{
 unsigned char y;
  while(ms--)
 {
  for(y = 0; y<250; y++)
  {
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  }
 }
}



串口接收到單片機是數據:

圖片 
軟件實現的代碼如下: (待續)
發佈了23 篇原創文章 · 獲贊 3 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章