风扇控制系统--初版

来源:互联网 发布:刺客信条起源n卡优化 编辑:程序博客网 时间:2024/04/29 15:40
风扇控制系统--初版

利用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_();
  }
 }
}



串口接收到单片机是数据:

图片 
软件实现的代码如下: (待续)
0 0