風扇控制系統--初版
利用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_();
}
}
}
串口接收到單片機是數據:
軟件實現的代碼如下: (待續)