单片机测光强_单片机强驱动模式 - CSDN
  • 单片机光强检测试验

    2020-07-30 23:32:22
    单片机实现光照强度的测量现实的生活中有广泛的应用,在楼道里这样既节约了电也提高了我们的研究兴趣
  • 很久没写博文了,今天决定用一上午记录曾经用51单片机做的一个智能家居并作为自己第一个比赛的作品。   有以下几个主要部分: 1.现室外光照在一定范围内控制窗帘的自动打开与关闭,可以让上班族无需为每天拉、关...

    名称:智能家居

    转载请注明出处,http://blog.csdn.net/lxk7280

    QQ 416815882

     

    很久没写博文了,今天决定用一上午记录曾经用51单片机做的一个智能家居并作为自己第一个比赛的作品。

     

    有以下几个主要部分:

    1.现室外光照在一定范围内控制窗帘的自动打开与关闭,可以让上班族无需为每天拉、关窗帘而烦扰。

    2.根据外界环境湿度来控制晾衣架的伸缩,在室外湿度比较大的时候为避免衣服受潮自动把晾衣架缩回来,反之正常湿度则可以伸出去让衣服更好的晾晒。

    3.室内出现燃气泄漏时可以自动关闭燃气阀门并给户主手机发出报警信号,并自动打开风机排除险情。

    这几个部分相结合,从而成为一个较完整的智能家居系统,实现家居的智能化和自动化。当然该系统同时还存在很多尚待改进的地方。

     

     

    摘要以及材料:以STC89C51单片机为控制核心,通过光敏传感器,烟雾传感器MQ-2,温湿度传感器DHT11,继电器,NRF24L01等设计的控制电路,实现

    直流电机带动风扇转动(与烟雾传感器),步进电机带动窗帘开闭(与光敏传感器有关),步进电机控制衣架伸缩(与温湿度传感器有关)。

     

    下面以简洁的语言介绍三个传感器模块:

            烟雾传感器模块:能检测到烟雾,可用香烟或者燃烧的纸等测试。若有烟雾 DOUT口会输出高电压(约为5V),平时会输出低电压(约为0V),因此可用51单片机的IO口直接检测是否有烟雾。

            光敏传感器模块:同理,可检测到光,若光强高于一定程度,DOUT口会输出高电压(5V),在此不再赘述。

            温湿度传感器模块:此模块难于上面两个模块。需要在软件上写出相应程序,之后可用(串口调试助手)检测会对外输出五个数据,其中有温度的两个数据(整数部分和小数部分)和湿度(整数部分和小数部分)和一个检验位。(在本智能家居中,通过一个无线NRF24L01模拟室外湿度的检测并返回的控制中心室内的51单片机,再与和单片机有线连接的温湿度传感器测得的数据进行比较)

          总之,这三个模块是很简单的。因为对外只需要三个连接线,两个为正负供电,一个为数据线。除了温湿度传感器需要用软件调试之外其余的都可很轻易检测并实现相应的反应动作。

        

    关键核心:

            通过STC89C51单片机的IO口不断的检测各个传感器的反馈信号,采集信号,并与预定值进行比较,并做出相应反应。如,利用P2的低五位对温湿度传感器,光敏传感器等进行数据采集和电压采集,对采集到的数据进行分析和过滤从而得到环境的温度,对采集到的电压进行比较,由此判断是否有光、光强是否达到一定值或是否有烟雾危险等等。用P1 P3的低四位控制两个步进电机。用继电器控制直流电机。

     

    附照:

      1.烟雾传感器

    2.光敏传感器

    3.温湿度传感器

    4.继电器

    5.无线模块

     

    部分程序:

    步进电机运转部分:

    void  motor_ffw1()

     { 

       unsigned char i;

       unsigned int  j;

       for (j=0; j<12; j++)         //转1*n圈 

        {

          for (i=0; i<8; i++)       //一个周期转30度

            {

              if(Q==1) P1 = FFW[i]&0x1f;  //取数据

         if(Q==2) P1 = FFZ[i]&0x1f;

              delay_two(5);                   //调节转速

            }

         } 

     }

    温湿度传感器读取数据部分:

       RH();    //室内

       shinei_temp=U8T_data_H;

       shinei_RH=U8RH_data_H;

       RH2(); //室外

       shiwai_temp=U8T_data_H;

       shiwai_RH=U8RH_data_H;

       //串口显示程序 

       if(shinei_RH>shiwai_RH&&vis_run2==0)

       {

        if(vis_run2==0)

        run2(1);//电机2正转 把衣架伸出去

    vis_run2=1;

       

       }

       if(shinei_RH<=shiwai_RH)

       {

    if(vis_run2==1)

             run2(2);//电机2 反转 把衣架缩回来

        vis_run2=0;

       }

    烟雾检测部分:

    void check_smog()      //检测烟雾

    {

    if(com_yanwu==0 /*烟雾被检测*/&&vis_send_smog==0/*且未发送*/)

    {

     vis_send_smog=1;

     fengji_run=0;

    }

    if(com_yanwu==1)

    {

    fengji_run=1;

    vis_send_smog=0;

    }

    }

     

     

     

    完整程序(分为室内室外两个部分):

         

     

       1.室内部分(一个c文件,两个h文件):

    #include <reg51.h>
    #include <intrins.h>
    #include "LQ12864.h"
    typedef unsigned char uchar;
    typedef unsigned char uint;
    //****************************************IO端口定义***************************************
    sbit CE     =P2^0;
    sbit CSN     =P2^1;
    sbit  SCK     =P2^2;
    sbit MOSI =P2^3;
    sbit  MISO =P2^4;
    sbit IRQ  =P2^5;
    //***********************************Buf数组*******************************************

    uchar TxBuf[32]= 0X00;

    //*********************************************NRF24L01*************************************
    #define TX_ADR_WIDTH    5    // 5 uints TX address width
    #define RX_ADR_WIDTH    5    // 5 uints RX address width
    #define TX_PLOAD_WIDTH  32   // 20 uints TX payload
    #define RX_PLOAD_WIDTH  32   // 20 uints TX payload
    uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x11}; //本地地址
    uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x10}; //接收地址
    //***************************************NRF24L01寄存器指令*******************************************************
    #define READ_REG        0x00   // 读寄存器指令
    #define WRITE_REG       0x20  // 写寄存器指令
    #define RD_RX_PLOAD     0x61   // 读取接收数据指令
    #define WR_TX_PLOAD     0xA0   // 写待发数据指令
    #define FLUSH_TX        0xE1  // 冲洗发送 FIFO指令
    #define FLUSH_RX        0xE2   // 冲洗接收 FIFO指令
    #define REUSE_TX_PL     0xE3   // 定义重复装载数据指令
    #define NOP             0xFF   // 保留
    //*************************************SPI(nRF24L01)寄存器地址****************************************************
    #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
    #define EN_AA           0x01  // 自动应答功能设置
    #define EN_RXADDR       0x02  // 可用信道设置
    #define SETUP_AW        0x03  // 收发地址宽度设置
    #define SETUP_RETR      0x04  // 自动重发功能设置
    #define RF_CH           0x05  // 工作频率设置
    #define RF_SETUP        0x06  // 发射速率、功耗功能设置
    #define STATUS          0x07  // 状态寄存器
    #define OBSERVE_TX      0x08  // 发送监测功能
    #define CD              0x09  // 地址检测          
    #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
    #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
    #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
    #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
    #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
    #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
    #define TX_ADDR         0x10  // 发送地址寄存器
    #define RX_PW_P0        0x11  // 接收频道0接收数据长度
    #define RX_PW_P1        0x12  // 接收频道0接收数据长度
    #define RX_PW_P2        0x13  // 接收频道0接收数据长度
    #define RX_PW_P3        0x14  // 接收频道0接收数据长度
    #define RX_PW_P4        0x15  // 接收频道0接收数据长度
    #define RX_PW_P5        0x16  // 接收频道0接收数据长度
    #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
    //**************************************************************************************
    void Delay(unsigned int s);
    void Delayms(unsigned int xms);
    void inerDelay_us(unsigned char n);
    void init_NRF24L01(void);
    uint SPI_RW(uint uchar);
    uchar SPI_Read(uchar reg);
    void SetRX_Mode(void);
    uint SPI_RW_Reg(uchar reg, uchar value);
    uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
    uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
    unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
    void nRF24L01_TxPacket(unsigned char * tx_buf);
    //***********************************延时xms毫秒******************************************
    void Delayms(unsigned int xms)
    {
       unsigned int i,j;
       for(i=xms;i>0;i--)
          for(j=110;j>0;j--);
    }
       
    //*****************************************长延时*****************************************
    void Delay(unsigned int s)
    {
     unsigned int i;
     for(i=0; i<s; i++);
     for(i=0; i<s; i++);
    }
    //******************************************************************************************
    uint  bdata sta;   //状态标志
    sbit RX_DR =sta^6;
    sbit TX_DS =sta^5;
    sbit MAX_RT =sta^4;
    /******************************************************************************************
    /*延时函数
    /******************************************************************************************/
    void inerDelay_us(unsigned char n)
    {
     for(;n>0;n--)
      _nop_();
    }
    //****************************************************************************************
    /*NRF24L01初始化
    //***************************************************************************************/
    void init_NRF24L01(void)
    {
        inerDelay_us(100);
      CE=0;    // chip enable
      CSN=1;   // Spi disable
      SCK=0;   // Spi clock line init high
     SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址 
     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
     SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动 ACK应答允许 
     SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21 
     SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   设置信道工作为2.4GHZ,收发必须一致
     SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
     SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);     //设置发射速率为1MHZ,发射功率为最大值0dB 
     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送

    }
    /****************************************************************************************************
    /*函数:uint SPI_RW(uint uchar)
    /*功能:NRF24L01的SPI写时序
    /****************************************************************************************************/
    uint SPI_RW(uint uchar)
    {
     uint bit_ctr;
        for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
       { 
      MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
      uchar = (uchar << 1);           // shift next bit into MSB..
      SCK = 1;                      // Set SCK high..
      uchar |= MISO;           // capture current MISO bit
      SCK = 0;                // ..then set SCK low again
        }
        return(uchar);               // return read uchar
    }
    /****************************************************************************************************
    /*函数:uchar SPI_Read(uchar reg)
    /*功能:NRF24L01的SPI时序
    /****************************************************************************************************/
    uchar SPI_Read(uchar reg)
    {
     uchar reg_val;
     
     CSN = 0;                // CSN low, initialize SPI communication...
     SPI_RW(reg);            // Select register to read from..
     reg_val = SPI_RW(0);    // ..then read registervalue
     CSN = 1;                // CSN high, terminate SPI communication
     
     return(reg_val);        // return register value
    }
    /****************************************************************************************************/
    /*功能:NRF24L01读写寄存器函数
    /****************************************************************************************************/
    uint SPI_RW_Reg(uchar reg, uchar value)
    {
     uint status;
     
     CSN = 0;                   // CSN low, init SPI transaction
     status = SPI_RW(reg);      // select register
     SPI_RW(value);             // ..and write value to it..
     CSN = 1;                   // CSN high again
     
     return(status);            // return nRF24L01 status uchar
    }
    /****************************************************************************************************/
    /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
    /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
    /****************************************************************************************************/
    uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
    {
     uint status,uchar_ctr;
     
     CSN = 0;                      // Set CSN low, init SPI tranaction
     status = SPI_RW(reg);         // Select register to write to and read status uchar
     
     for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
      pBuf[uchar_ctr] = SPI_RW(0);    //
     
     CSN = 1;                          
     
     return(status);                    // return nRF24L01 status uchar
    }
    /*********************************************************************************************************
    /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
    /*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
    /*********************************************************************************************************/
    uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
    {
     uint status,uchar_ctr;
     
     CSN = 0;            //SPI使能      
     status = SPI_RW(reg);  
     for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
      SPI_RW(*pBuf++);
     CSN = 1;           //关闭SPI
     return(status);    //
    }
    /****************************************************************************************************/
    /*函数:void SetRX_Mode(void)
    /*功能:数据接收配置
    /****************************************************************************************************/
    void SetRX_Mode(void)
    {
     CE=0;
     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // IRQ收发完成中断响应,16位CRC ,主接收
     CE = 1;
     inerDelay_us(130);
    }
    /******************************************************************************************************/
    /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
    /*功能:数据读取后放如rx_buf接收缓冲区中
    /******************************************************************************************************/
    unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
    {
        unsigned char revale=0;
     sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
     if(RX_DR)    // 判断是否接收到数据
     {
         CE = 0;    //SPI使能
      SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
          CE=1;      //外加
        inerDelay_us(130);  //外加
      revale =1;   //读取数据完成标志
     }
     SPI_RW_Reg(WRITE_REG+STATUS,0x7e);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志 //改为0通道
     return revale;       
    }
    /***********************************************************************************************************
    /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
    /*功能:发送 tx_buf中数据
    /**********************************************************************************************************/
    void nRF24L01_TxPacket(unsigned char * tx_buf)
    {
     CE=0;   //StandBy I模式 
     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
     SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);     // 装载数据 
    // SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送
     CE=1;    //置高CE,激发数据发送
     inerDelay_us(10);
    }
    //************************************主函数************************************************************


      
      void main(void)
      {
         uchar RE=0;
    //     uchar packet;
         LCD_Init();
         init_NRF24L01() ;
         SetRX_Mode();
         Delayms(1);
         LCD_6x8(0,0,"start");
       while(1)
       {
         while(IRQ==1);  //
         RE= nRF24L01_RxPacket(TxBuf);
         if(RE)//如果接收成功;
         {            
        TxBuf=

         }   
       }
         } 
      
     
     以下为:"LQ12864.h"文件 

    #include "REG51.h"
    sbit LCD_SCL=P1^0; //时钟 D0(SCLK)
    sbit LCD_SDA=P1^1; //D1(MOSI) 数据
    sbit LCD_RST=P1^2; //复位
    sbit LCD_DC =P1^3; //数据/命令控制
    #define XLevelL  0x00
    #define XLevelH  0x10
    #define XLevel     ((XLevelH&0x0F)*16+XLevelL)
    #define Max_Column 128
    #define Max_Row  64
    #define Brightness 0xCF
    #define X_WIDTH 128
    #define Y_WIDTH 64

    void LCD_DLY_ms(unsigned int ms)  //LCD 延时1ms
    {                        
       unsigned int a;
       while(ms)
       {
         a=1800;
         while(a--);
         ms--;
    }
    return;
    }

    void LCD_WrDat(unsigned char dat)   //**LCD写数据 
    {
       unsigned char i=8;         
       LCD_DC=1; 
       for(i=0;i<8;i++) //发送一个八位数据
       {
         LCD_SCL=0;         
         LCD_SDA=dat&0x80;
         LCD_SCL=1;            
         dat<<=1;   
       }
    }
    void LCD_WrCmd(unsigned char cmd)   //****LCD写命令
    {
      unsigned char i=8;        
      LCD_DC=0;
      for(i=0;i<8;i++) //发送一个八位数据
      {
        LCD_SCL=0;
        LCD_SDA=cmd&0x80;
        LCD_SCL=1;
        cmd<<=1;;  
      }  
    }

    void LCD_Setxy(unsigned char x, unsigned char y)  //LCD 设置坐标
    {
      LCD_WrCmd(0xb0+y);
      LCD_WrCmd(((x&0xf0)>>4)|0x10);
      LCD_WrCmd((x&0x0f)|0x01);
    }
    void LCD_Fill(unsigned char bmp_dat)   //bmp_dat=0x00全屏灭,bmp_dat=0xff全屏亮
    {
       unsigned char y,x;
       for(y=0;y<8;y++)
       {
         LCD_WrCmd(0xb0+y);
         LCD_WrCmd(0x01);
         LCD_WrCmd(0x10);
         for(x=0;x<X_WIDTH;x++)
            LCD_WrDat(bmp_dat);
    }
    }
    /*void LCD_CLS(void) //LCD复位
    {
       unsigned char y,x; 
       for(y=0;y<8;y++)
       {
         LCD_WrCmd(0xb0+y);
         LCD_WrCmd(0x01);
         LCD_WrCmd(0x10);
         for(x=0;x<X_WIDTH;x++)
             LCD_WrDat(0);
       }
    }*/
    void LCD_Init(void) //LCD初始化 

       LCD_SCL=1;
       LCD_RST=0;
       LCD_DLY_ms(50);
       LCD_RST=1;       //从上电到下面开始初始化要有足够的时间,即等待RC复位完毕  
       LCD_WrCmd(0xae);//--关闭显示                          turn off oled panel
       LCD_WrCmd(0x00);//---设置低列地址                                    set low column address
       LCD_WrCmd(0x10);//---高列地址                                        set high column address 
       LCD_WrCmd(0x40);//--设置起始地址映射内存显示开始行(0x 00 ~ 0x3f)   set start line address  Set Mapping RAM Display Start Line (0x00~0x3F)
       LCD_WrCmd(0x81);//--设置对比度控制寄存器                             set contrast control register
       LCD_WrCmd(0xcf); // 电流输出亮度设置赛格                             Set SEG Output Current Brightness
       LCD_WrCmd(0xa1);//--设置赛格/列映射  0xa0左右反置0xa1正常            Set SEG/Column Mapping     0xa0左右反置 0xa1正常
       LCD_WrCmd(0xc8);//设置网站/行扫描方向 0xc0上下反置 0xc8正常          Set COM/Row Scan Direction  
       LCD_WrCmd(0xa6);//--正常显示                                         set normal display
       LCD_WrCmd(0xa8);//--集复用率(1 - 64)                               set multiplex ratio(1 to 64)
       LCD_WrCmd(0x3f);//--1/64 duty
       LCD_WrCmd(0xd3);//-设置显示偏移位移映射内存计数器(0x 00 ~ 0x3f)    set display offset Shift Mapping RAM Counter (0x00~0x3F)
       LCD_WrCmd(0x00);//-不偏移                                            not offset
       LCD_WrCmd(0xd5);//--设置显示时钟的分频比/振荡器频率                  set display clock divide ratio/oscillator frequency
       LCD_WrCmd(0x80);//--组分比,时钟设置为100帧/秒                       set divide ratio, Set Clock as 100 Frames/Sec
       LCD_WrCmd(0xd9);//--设定充电周期                                     set pre-charge period
       LCD_WrCmd(0xf1);//15集充电放电1钟钟表                                Set Pre-Charge as 15 Clocks & Discharge as 1 Clock
       LCD_WrCmd(0xda);//--设置组件的引脚配置硬件                           set com pins hardware configuration
       LCD_WrCmd(0x12);
       LCD_WrCmd(0xdb);//--集vcomh                                          set vcomh
       LCD_WrCmd(0x40);//威科姆取消水平集                                   Set VCOM Deselect Level
       LCD_WrCmd(0x20);//-设置页面寻址模式(0x 00 /将/ 0x02)               Set Page Addressing Mode (0x00/0x01/0x02)
       LCD_WrCmd(0x02);//
       LCD_WrCmd(0x8d);//--充电泵启用/禁用                                  set Charge Pump enable/disable
       LCD_WrCmd(0x14);//--集(0x 10个)禁用                                set(0x10) disable
       LCD_WrCmd(0xa4);// 使整个显示(0xa4 / 0xa5)                         Disable Entire Display On (0xa4/0xa5)
       LCD_WrCmd(0xa6);// 禁用反显示(0xa6 / 7)                            Disable Inverse Display On (0xa6/a7)
       LCD_WrCmd(0xaf);//--打开面板                                         turn on oled panel
       LCD_Fill(0x00);  //初始清屏
       LCD_Setxy(0,0);

    void LCD_6x8(unsigned char x, y,unsigned char ch[])//显示6*8一组标准ASCII字符串 显示的坐标(x,y),y为页范围0~7
    {
       unsigned char c=0,i=0,j=0;     
       while (ch[j]!='\0')
       {   
         c =ch[j]-32;
         if(x>126)
         {x=0;y++;}
         LCD_Setxy(x,y);   
         for(i=0;i<6;i++)    
           LCD_WrDat(F6x8[c][i]); 
         x+=6;
         j++;
       }
    }
    void LCD_Cler_6x8(unsigned char x,y,n)//清除N个6*8字符
    {
       unsigned int i=0;
       LCD_Setxy(x,y);
       if(x>126)
      {x=0;y++;}
       for(i=0;i<6*n;i++)
           LCD_WrDat(0x00);
    }
    void ready(unsigned char x,y,unsigned int num)
    {
          switch (num)
          {
         case 0:
            LCD_6x8(x,y,"0");break;
         case 1:
            LCD_6x8(x,y,"1");break;
         case 2:
            LCD_6x8(x,y,"2");break;
         case 3:
            LCD_6x8(x,y,"3");break;
         case 4:
            LCD_6x8(x,y,"4");break;
         case 5:
            LCD_6x8(x,y,"5");break;
         case 6:
            LCD_6x8(x,y,"6");break;
         case 7:
            LCD_6x8(x,y,"7");break;
         case 8:
            LCD_6x8(x,y,"8");break;
         case 9:
            LCD_6x8(x,y,"9");break; 
          } 
    }
    /*void LCD_8x16(unsigned char x, y,unsigned char ch[])//显示8*16一组标准ASCII字符串  显示的坐标(x,y),y为页范围0~7
    {
      unsigned char c=0,i=0,j=0;
      while (ch[j]!='\0')
      {   
        c =ch[j]-32;
        if(x>120)
       {x=0;y++;}
        LCD_Setxy(x,y);   
        for(i=0;i<8;i++)    
          LCD_WrDat(F8X16[c*16+i]);
        LCD_Setxy(x,y+1);   
        for(i=0;i<8;i++)    
          LCD_WrDat(F8X16[c*16+i+8]); 
        x+=8;
        j++;
      }
    }
    void LCD_Cler_8x16(unsigned char x, y,n) //清除n个8*16字符
    {
        unsigned char i;
        if(x>120)
       {x=0;y++;}
     LCD_Setxy(x,y);
     for(i=0;i<8*n;i++)
       LCD_WrDat(0x00);
        LCD_Setxy(x,y+1);
     for(i=0;i<8*n;i++)
       LCD_WrDat(0x00);   
    }
    void LCD_16x16(unsigned char x, y, N)//显示16*16点阵  显示的坐标(x,y),y为页范围0~7
    {
      unsigned char wm=0;
      unsigned int adder=32*N;  //   
      LCD_Setxy(x , y);
      for(wm = 0;wm < 16;wm++)  //            
      {
        LCD_WrDat(F16x16[adder]); 
        adder += 1;
      }     
      LCD_Setxy(x,y + 1);
      for(wm = 0;wm < 16;wm++) //        
      {
        LCD_WrDat(F16x16[adder]);
        adder += 1;
      }     
    }
    void LCD_Cler_16x16(unsigned char x,y,n)//清除n个16*16字
    {
      unsigned char i=0;
      LCD_Setxy(x,y);
      for(i=0;i<16*n;i++)
         LCD_WrDat(0x00);
      LCD_Setxy(x,y+1);
      for(i=0;i<16*n;i++)
         LCD_WrDat(0x00);
    }
    void Draw_BMP(unsigned char x0, y0,x1, y1,unsigned char BMP[])//显示显示BMP图片128×64起始点坐标(x,y),x的范围0~127,y为页的范围0~7*
    {  
     unsigned int j=0;
     unsigned char x,y;
     
      if(y1%8==0)
         y=y1/8;     
      else
         y=y1/8+1;
      for(y=y0;y<y1;y++)
      {
         LCD_Setxy(x0,y);    
         for(x=x0;x<x1;x++)
      {     
         LCD_WrDat(BMP[j++]);      
      }
      }
    }*/

     
     以下为:DHT11.h文件

    //****************************************************************//
    #include <reg51.h>
    #include <intrins.h>
    //
    typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable    无符号8位整型变量  */
    typedef signed   char  S8;       /* defined for signed 8-bits integer variable    有符号8位整型变量  */
    typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable    无符号16位整型变量 */
    typedef signed   int   S16;      /* defined for signed 16-bits integer variable    有符号16位整型变量 */
    typedef unsigned long  U32;      /* defined for unsigned 32-bits integer variable    无符号32位整型变量 */
    typedef signed   long  S32;      /* defined for signed 32-bits integer variable    有符号32位整型变量 */
    typedef float          F32;      /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
    typedef double         F64;      /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
    //
    #define uchar unsigned char
    #define uint unsigned int
    #define   Data_0_time    4

    //----------------------------------------------//
    //----------------IO口定义区--------------------//
    //----------------------------------------------//
    sbit  P2_0  = P2^0 ;

    //----------------------------------------------//
    //----------------定义区--------------------//
    //----------------------------------------------//
    U8  U8FLAG,k;
    U8  U8count,U8temp;
    U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
    U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
    U8  U8comdata;
    U8  count, count_r=0;
    U16 U16temp1,U16temp2;
    /***************************************************************
    SendData(U8 *a)
    {
     outdata[0] = a[0];
     outdata[1] = a[1];
     outdata[2] = a[2];
     outdata[3] = a[3];
     outdata[4] = a[4];
     count = 1;
     SBUF=outdata[0];
    }
     *************************************************************/
           void Delay(U16 j)
        {      U8 i;
         for(;j>0;j--)
       {  
      for(i=0;i<27;i++);

       }
        }
           void  Delay_10us(void)
          {
            U8 i;
            i--;
            i--;
            i--;
            i--;
            i--;
            i--;
           }
     
            void  COM(void)
          {
        
             U8 i;
             
           for(i=0;i<8;i++)   
         {
      
             U8FLAG=2; 
         while((!P2_0)&&U8FLAG++);
       Delay_10us();
          Delay_10us();
       Delay_10us();
         U8temp=0;
          if(P2_0)U8temp=1;
          U8FLAG=2;
       while((P2_0)&&U8FLAG++);
         //超时则跳出for循环   
          if(U8FLAG==1)break;
         //判断数据位是0还是1 
           
      // 如果高电平高过预定0高电平值则数据位为 1
         
         U8comdata<<=1;
            U8comdata|=U8temp;        //0
          }//rof
       
     }
     //--------------------------------
     //-----湿度读取子程序 ------------
     //--------------------------------
     //----以下变量均为全局变量--------
     //----温度高8位== U8T_data_H------
     //----温度低8位== U8T_data_L------
     //----湿度高8位== U8RH_data_H-----
     //----湿度低8位== U8RH_data_L-----
     //----校验 8位 == U8checkdata-----
     //----调用相关子程序如下----------
     //---- Delay();, Delay_10us();,COM();
     //--------------------------------

     void RH(void)
     {
       //主机拉低18ms
           P2_0=0;
        Delay(180);
        P2_0=1;
      //总线由上拉电阻拉高 主机延时20us
        Delay_10us();
        Delay_10us();
        Delay_10us();
        Delay_10us();
      //主机设为输入 判断从机响应信号
        P2_0=1;
      //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行  
        if(!P2_0)   //T !  
        {
        U8FLAG=2;
      //判断从机是否发出 80us 的低电平响应信号是否结束 
        while((!P2_0)&&U8FLAG++);
        U8FLAG=2;
      //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
        while((P2_0)&&U8FLAG++);
      //数据接收状态  
        COM();
        U8RH_data_H_temp=U8comdata;
        COM();
        U8RH_data_L_temp=U8comdata;
        COM();
        U8T_data_H_temp=U8comdata;
        COM();
        U8T_data_L_temp=U8comdata;
        COM();
        U8checkdata_temp=U8comdata;
        P2_0=1;
      //数据校验
     
        U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
        if(U8temp==U8checkdata_temp)
        {
           U8RH_data_H=U8RH_data_H_temp;
           U8RH_data_L=U8RH_data_L_temp;
        U8T_data_H=U8T_data_H_temp;
           U8T_data_L=U8T_data_L_temp;
           U8checkdata=U8checkdata_temp;
        }//fi
        }//fi

     }

     

     

    2.室外部分():

    c文件部分:

    #include "REG51.h"
    #include "intrins.h"
    #include "Tx_nrf.h"
    #include "DHT11.h"
    void main()
    {
        unsigned int i,table=0,dish;
     unsigned char car[3],keyy[10];
     init_NRF24L01();

        while(1)
     {        
        //------------------------
          //调用温湿度读取子程序
          RH();
          //串口显示程序
          //--------------------------
          car[0]=U8RH_data_H;
          Delay(20000);
          IRQ=1;
            SPI_RW(FLUSH_TX );//清空TX_FIFO//此处必要。否则经常出错
            nRF24L01_TxPacket(car); // Transmit Tx buffer data
         CE=0; 
             while(IRQ==1);//等待发送完成
         sta=SPI_Read(STATUS);// 读取状态寄存其来判断数据接收状况
         if(TX_DS)//判断是否发送成功
         {
              for(i=0; i<8; i++)
                        {
    //                    LCD_16x16(i*16,3,i+8);  //发送成功
                        }                           //SetRX_Mode() //变为接受状态
         }
        else
        {
           for(i=0; i<8; i++)                              //若要变为发送模式,init_NRF24L01() ;或CE=0;SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e); 
           {
    //           LCD_16x16(i*16,3,i+16);  //发送失败
           }
        }
        
        SPI_RW_Reg(WRITE_REG+STATUS,0X7e);     //RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清除中断标志 
           
       }

    }

     

    以下为TX—NRF.h部分:

    #include <reg51.h>
    #include <intrins.h>

    typedef unsigned char uchar;
    typedef unsigned char uint;
    //****************************************IO端口定义***************************************
    sbit CE     =P2^5;
    sbit CSN     =P2^1;
    sbit  SCK     =P2^4;
    sbit MOSI =P2^0;
    sbit  MISO =P2^3;
    sbit IRQ  =P2^2;
    //*********************************************NRF24L01*************************************
    #define TX_ADR_WIDTH    5    // 5 uints TX address width
    #define RX_ADR_WIDTH    5    // 5 uints RX address width
    #define TX_PLOAD_WIDTH  32   // 20 uints TX payload
    #define RX_PLOAD_WIDTH  32   // 20 uints TX payload
    uint const TX_ADDRESS[TX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x13}; //本地地址
    uint const RX_ADDRESS[RX_ADR_WIDTH]= {0x34,0x43,0x10,0x10,0x13}; //接收地址
    //***************************************NRF24L01寄存器指令*******************************************************
    #define READ_REG        0x00   // 读寄存器指令
    #define WRITE_REG       0x20  // 写寄存器指令
    #define RD_RX_PLOAD     0x61   // 读取接收数据指令
    #define WR_TX_PLOAD     0xA0   // 写待发数据指令
    #define FLUSH_TX        0xE1  // 冲洗发送 FIFO指令
    #define FLUSH_RX        0xE2   // 冲洗接收 FIFO指令
    #define REUSE_TX_PL     0xE3   // 定义重复装载数据指令
    #define NOP             0xFF   // 保留
    //*************************************SPI(nRF24L01)寄存器地址****************************************************
    #define CONFIG          0x00  // 配置收发状态,CRC校验模式以及收发状态响应方式
    #define EN_AA           0x01  // 自动应答功能设置
    #define EN_RXADDR       0x02  // 可用信道设置
    #define SETUP_AW        0x03  // 收发地址宽度设置
    #define SETUP_RETR      0x04  // 自动重发功能设置
    #define RF_CH           0x05  // 工作频率设置
    #define RF_SETUP        0x06  // 发射速率、功耗功能设置
    #define STATUS          0x07  // 状态寄存器
    #define OBSERVE_TX      0x08  // 发送监测功能
    #define CD              0x09  // 地址检测          
    #define RX_ADDR_P0      0x0A  // 频道0接收数据地址
    #define RX_ADDR_P1      0x0B  // 频道1接收数据地址
    #define RX_ADDR_P2      0x0C  // 频道2接收数据地址
    #define RX_ADDR_P3      0x0D  // 频道3接收数据地址
    #define RX_ADDR_P4      0x0E  // 频道4接收数据地址
    #define RX_ADDR_P5      0x0F  // 频道5接收数据地址
    #define TX_ADDR         0x10  // 发送地址寄存器
    #define RX_PW_P0        0x11  // 接收频道0接收数据长度
    #define RX_PW_P1        0x12  // 接收频道0接收数据长度
    #define RX_PW_P2        0x13  // 接收频道0接收数据长度
    #define RX_PW_P3        0x14  // 接收频道0接收数据长度
    #define RX_PW_P4        0x15  // 接收频道0接收数据长度
    #define RX_PW_P5        0x16  // 接收频道0接收数据长度
    #define FIFO_STATUS     0x17  // FIFO栈入栈出状态寄存器设置
    //**************************************************************************************
    void Delay(unsigned int s);
    void Delayms(unsigned int xms);
    void inerDelay_us(unsigned char n);
    void init_NRF24L01(void);
    uint SPI_RW(uint uchar);
    uchar SPI_Read(uchar reg);
    void SetRX_Mode(void);
    uint SPI_RW_Reg(uchar reg, uchar value);
    uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars);
    uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars);
    unsigned char nRF24L01_RxPacket(unsigned char* rx_buf);
    void nRF24L01_TxPacket(unsigned char * tx_buf);
    //******************************************************************************************
    uint  bdata sta;   //状态标志
    sbit RX_DR =sta^6;
    sbit TX_DS =sta^5;
    sbit MAX_RT =sta^4;
    /******************************************************************************************
    /*延时函数
    /******************************************************************************************/
    void inerDelay_us(unsigned char n)
    {
     for(;n>0;n--)
      _nop_();
    }
    //****************************************************************************************
    /*NRF24L01初始化
    //***************************************************************************************/
    void init_NRF24L01(void)
    {
        inerDelay_us(100);
      CE=0;    // chip enable
      CSN=1;   // Spi disable
      SCK=0;   // Spi clock line init high
     SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS, TX_ADR_WIDTH);    // 写本地地址 
     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, RX_ADDRESS, RX_ADR_WIDTH); // 写接收端地址
     SPI_RW_Reg(WRITE_REG + EN_AA, 0x01);      //  频道0自动 ACK应答允许
     SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1f); //自动重发15次、延时0.5ms+86us
     SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);  //  允许接收地址只有频道0,如果需要多频道可以参考Page21 
     SPI_RW_Reg(WRITE_REG + RF_CH, 0);        //   设置信道工作为2.4GHZ,收发必须一致
     SPI_RW_Reg(WRITE_REG + RX_PW_P0, RX_PLOAD_WIDTH); //设置接收数据长度,本次设置为32字节
     SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07);     //设置发射速率为1MHZ,发射功率为最大值0dB 
     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);     // IRQ收发完成中断响应,16位CRC,主发送

    }
    /****************************************************************************************************
    /*函数:uint SPI_RW(uint uchar)
    /*功能:NRF24L01的SPI写时序
    /****************************************************************************************************/
    uint SPI_RW(uint uchar)
    {
     uint bit_ctr;
        for(bit_ctr=0;bit_ctr<8;bit_ctr++) // output 8-bit
       { 
      MOSI = (uchar & 0x80);         // output 'uchar', MSB to MOSI
      uchar = (uchar << 1);           // shift next bit into MSB..
      SCK = 1;                      // Set SCK high..
      uchar |= MISO;           // capture current MISO bit
      SCK = 0;                // ..then set SCK low again
        }
        return(uchar);               // return read uchar
    }
    /****************************************************************************************************
    /*函数:uchar SPI_Read(uchar reg)
    /*功能:NRF24L01的SPI时序
    /****************************************************************************************************/
    uchar SPI_Read(uchar reg)
    {
     uchar reg_val;
     
     CSN = 0;                // CSN low, initialize SPI communication...
     SPI_RW(reg);            // Select register to read from..
     reg_val = SPI_RW(0);    // ..then read registervalue
     CSN = 1;                // CSN high, terminate SPI communication
     
     return(reg_val);        // return register value
    }
    /****************************************************************************************************/
    /*功能:NRF24L01读写寄存器函数
    /****************************************************************************************************/
    uint SPI_RW_Reg(uchar reg, uchar value)
    {
     uint status;
     CSN = 0;                   // CSN low, init SPI transaction
     status = SPI_RW(reg);      // select register
     SPI_RW(value);             // ..and write value to it..
     CSN = 1;                   // CSN high again 
     return(status);            // return nRF24L01 status uchar
    }
    /****************************************************************************************************/
    /*函数:uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
    /*功能: 用于读数据,reg:为寄存器地址,pBuf:为待读出数据地址,uchars:读出数据的个数
    /****************************************************************************************************/
    uint SPI_Read_Buf(uchar reg, uchar *pBuf, uchar uchars)
    {
     uint status,uchar_ctr;
     
     CSN = 0;                      // Set CSN low, init SPI tranaction
     status = SPI_RW(reg);         // Select register to write to and read status uchar
     
     for(uchar_ctr=0;uchar_ctr<uchars;uchar_ctr++)
      pBuf[uchar_ctr] = SPI_RW(0);    //
     
     CSN = 1;                          
     
     return(status);                    // return nRF24L01 status uchar
    }
    /*********************************************************************************************************
    /*函数:uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
    /*功能: 用于写数据:为寄存器地址,pBuf:为待写入数据地址,uchars:写入数据的个数
    /*********************************************************************************************************/
    uint SPI_Write_Buf(uchar reg, uchar *pBuf, uchar uchars)
    {
     uint status,uchar_ctr;
     
     CSN = 0;            //SPI使能      
     status = SPI_RW(reg);  
     for(uchar_ctr=0; uchar_ctr<uchars; uchar_ctr++) //
      SPI_RW(*pBuf++);
     CSN = 1;           //关闭SPI
     return(status);    //
    }
    /****************************************************************************************************/
    /*函数:void SetRX_Mode(void)
    /*功能:数据接收配置
    /****************************************************************************************************/
    void SetRX_Mode(void)
    {
     CE=0;
     SPI_RW_Reg(WRITE_REG + CONFIG, 0x0f);     // IRQ收发完成中断响应,16位CRC ,主接收
     CE = 1;
     inerDelay_us(130);
    }
    /******************************************************************************************************/
    /*函数:unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
    /*功能:数据读取后放如rx_buf接收缓冲区中
    /******************************************************************************************************/
    unsigned char nRF24L01_RxPacket(unsigned char* rx_buf)
    {
        unsigned char revale=0;
     sta=SPI_Read(STATUS); // 读取状态寄存其来判断数据接收状况
     if(RX_DR)    // 判断是否接收到数据
     {
         CE = 0;    //SPI使能
      SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);// read receive payload from RX_FIFO buffer
      revale =1;   //读取数据完成标志
     }
     SPI_RW_Reg(WRITE_REG+STATUS,0x7e);   //接收到数据后RX_DR,TX_DS,MAX_PT都置高为1,通过写1来清楚中断标志
     return revale;
    }
    /***********************************************************************************************************
    /*函数:void nRF24L01_TxPacket(unsigned char * tx_buf)
    /*功能:发送 tx_buf中数据
    /**********************************************************************************************************/
    void nRF24L01_TxPacket(unsigned char * tx_buf)
    {
     CE=0;   //StandBy I模式
    // SPI_RW_Reg(WRITE_REG + CONFIG, 0x0e);      // IRQ收发完成中断响应,16位CRC,主发送 
     SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH); // 装载接收端地址
     SPI_Write_Buf(WR_TX_PLOAD, tx_buf, TX_PLOAD_WIDTH);     // 装载数据 

     CE=1;   //置高CE,激发数据发送
     inerDelay_us(10);
    }

     

    以下为DHT11。H部分:

    //****************************************************************//
    //                 DHT21使用范例
    //单片机 : AT89S52 或 STC89C52RC
    // 功能  :串口发送温湿度数据 晶振 11.0592M 波特率 9600
    //硬件连接: P2.0口为通讯口连接DHT11,DHT11的电源和地连接单片机的电源和地,单片机串口加MAX232连接电脑
    // 公司  :奥松电子   
    //****************************************************************//

    #include <reg51.h>
    #include <intrins.h>
    //
    typedef unsigned char  U8;       /* defined for unsigned 8-bits integer variable    无符号8位整型变量  */
    typedef signed   char  S8;       /* defined for signed 8-bits integer variable    有符号8位整型变量  */
    typedef unsigned int   U16;      /* defined for unsigned 16-bits integer variable    无符号16位整型变量 */
    typedef signed   int   S16;      /* defined for signed 16-bits integer variable    有符号16位整型变量 */
    typedef unsigned long  U32;      /* defined for unsigned 32-bits integer variable    无符号32位整型变量 */
    typedef signed   long  S32;      /* defined for signed 32-bits integer variable    有符号32位整型变量 */
    typedef float          F32;      /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
    typedef double         F64;      /* double precision floating point variable (64bits) 双精度浮点数(64位长度) */
    //
    #define uchar unsigned char
    #define uint unsigned int
    #define   Data_0_time    4

    //----------------------------------------------//
    //----------------IO口定义区--------------------//
    //----------------------------------------------//
    sbit  P2_0  = P1^2 ;
    sbit  P2_1  = P2^1 ;

    //----------------------------------------------//
    //----------------定义区--------------------//
    //----------------------------------------------//
    U8  U8FLAG,k;
    U8  U8count,U8temp;
    U8  U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;
    U8  U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp;
    U8  U8comdata;
    U8  count, count_r=0;
    U16 U16temp1,U16temp2;
    /***************************************************************
    SendData(U8 *a)
    {
     outdata[0] = a[0];
     outdata[1] = a[1];
     outdata[2] = a[2];
     outdata[3] = a[3];
     outdata[4] = a[4];
     count = 1;
     SBUF=outdata[0];
    }
     *************************************************************/
           void Delay(U16 j)
        {      U8 i;
         for(;j>0;j--)
       {  
      for(i=0;i<27;i++);

       }
        }
           void  Delay_10us(void)
          {
            U8 i;
            i--;
            i--;
            i--;
            i--;
            i--;
            i--;
           }
     
            void  COM(void)
          {
        
             U8 i;
             
           for(i=0;i<8;i++)   
         {
      
             U8FLAG=2; 
         while((!P2_0)&&U8FLAG++);
       Delay_10us();
          Delay_10us();
       Delay_10us();
         U8temp=0;
          if(P2_0)U8temp=1;
          U8FLAG=2;
       while((P2_0)&&U8FLAG++);
         //超时则跳出for循环   
          if(U8FLAG==1)break;
         //判断数据位是0还是1 
           
      // 如果高电平高过预定0高电平值则数据位为 1
         
         U8comdata<<=1;
            U8comdata|=U8temp;        //0
          }//rof
       
     }
       void  COM2(void)
          {
        
             U8 i;
             
           for(i=0;i<8;i++)   
         {
      
             U8FLAG=2; 
         while((!P2_1)&&U8FLAG++);
       Delay_10us();
          Delay_10us();
       Delay_10us();
         U8temp=0;
          if(P2_1)U8temp=1;
          U8FLAG=2;
       while((P2_1)&&U8FLAG++);
         //超时则跳出for循环   
          if(U8FLAG==1)break;
         //判断数据位是0还是1 
           
      // 如果高电平高过预定0高电平值则数据位为 1
         
         U8comdata<<=1;
            U8comdata|=U8temp;        //0
          }//rof
       }
     //--------------------------------
     //-----湿度读取子程序 ------------
     //--------------------------------
     //----以下变量均为全局变量--------
     //----温度高8位== U8T_data_H------
     //----温度低8位== U8T_data_L------
     //----湿度高8位== U8RH_data_H-----
     //----湿度低8位== U8RH_data_L-----
     //----校验 8位 == U8checkdata-----
     //----调用相关子程序如下----------
     //---- Delay();, Delay_10us();,COM();
     //--------------------------------

     void RH(void)
     {
       //主机拉低18ms
           P2_0=0;
        Delay(180);
        P2_0=1;
      //总线由上拉电阻拉高 主机延时20us
        Delay_10us();
        Delay_10us();
        Delay_10us();
        Delay_10us();
      //主机设为输入 判断从机响应信号
        P2_0=1;
      //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行  
        if(!P2_0)   //T !  
        {
        U8FLAG=2;
      //判断从机是否发出 80us 的低电平响应信号是否结束 
        while((!P2_0)&&U8FLAG++);
        U8FLAG=2;
      //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
        while((P2_0)&&U8FLAG++);
      //数据接收状态  
        COM();
        U8RH_data_H_temp=U8comdata;
        COM();
        U8RH_data_L_temp=U8comdata;
        COM();
        U8T_data_H_temp=U8comdata;
        COM();
        U8T_data_L_temp=U8comdata;
        COM();
        U8checkdata_temp=U8comdata;
        P2_0=1;
      //数据校验
     
        U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
        if(U8temp==U8checkdata_temp)
        {
           U8RH_data_H=U8RH_data_H_temp;
           U8RH_data_L=U8RH_data_L_temp;
        U8T_data_H=U8T_data_H_temp;
           U8T_data_L=U8T_data_L_temp;
           U8checkdata=U8checkdata_temp;
        }//fi
        }//fi

     }
     
     void RH2(void)
     {
       //主机拉低18ms
           P2_1=0;
        Delay(180);
        P2_1=1;
      //总线由上拉电阻拉高 主机延时20us
        Delay_10us();
        Delay_10us();
        Delay_10us();
        Delay_10us();
      //主机设为输入 判断从机响应信号
        P2_1=1;
      //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行  
        if(!P2_1)   //T !  
        {
        U8FLAG=2;
      //判断从机是否发出 80us 的低电平响应信号是否结束 
        while((!P2_1)&&U8FLAG++);
        U8FLAG=2;
      //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
        while((P2_1)&&U8FLAG++);
      //数据接收状态  
        COM2();
        U8RH_data_H_temp=U8comdata;
        COM2();
        U8RH_data_L_temp=U8comdata;
        COM2();
        U8T_data_H_temp=U8comdata;
        COM2();
        U8T_data_L_temp=U8comdata;
        COM2();
        U8checkdata_temp=U8comdata;
        P2_1=1;
      //数据校验
     
        U8temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp);
        if(U8temp==U8checkdata_temp)
        {
           U8RH_data_H=U8RH_data_H_temp;
           U8RH_data_L=U8RH_data_L_temp;
        U8T_data_H=U8T_data_H_temp;
           U8T_data_L=U8T_data_L_temp;
           U8checkdata=U8checkdata_temp;
        }//fi
        }//fi
     }

     

     

    over~~如果不正确或者不好的地方,请指出~

    展开全文
  • 单片机常用模块大全

    2017-02-06 22:33:55
    在我们设计单片机电子电路时,会用到一些常用的电路,每次都需要从新画,即费力又费神,还容易出错,所以本人将自己常用的电路设计成模块,每次使用直接负责即可。由于个人的力量有限,希望大家把自己常用的电路发...
    在我们设计单片机电子电路时,会用到一些常用的电路,每次都需要从新画,即费力又费神,还容易出错,所以本人将自己常用的电路设计成模块,每次使用直接负责即可。由于个人的力量有限,希望大家把自己常用的电路发上来分享。电路难免有错,希望大家指出。

    1.双路232通信电路:3线连接方式,对应的是母头,工作电压5V,可以使用MAX202或MAX232。
     
    2. 三极管串口通信:本电路是用三极管搭的,电路简单,成本低,但是问题,一般在低波特率下是非常好的。

     
    3. 单路232通信电路:三线方式,与上面的三级管搭的完全等效。
     
    4. USB转232电路:采用的是PL2303HX,价格便宜,稳定性还不错。
     
    5. SP706S复位电路:带看门狗和手动复位,价格便宜(美信的贵很多),R4为调试用,调试完后焊接好R4。



     
    6.SD卡模块电路(带锁):本电路与SD卡的封装有关,注意与封装对应。此电路可以通过端口控制SD卡的电源,比较完善,可以用于5V和3.3V。但是要注意,有些器件的使用,5V和3.3是不一样的。

     


    7.LCM12864液晶模块(ST7920):本电路是常见的12864电路,价格便宜,带中文字库。可以通过PSB端口的电平来设置其工作在串口模式还是并行模式,带背光控制功能。
     
    8.LCD1602字符液晶模块(KS0066):最常用的字符液晶模块,只能显示数字和字符,可4位或8位控制,带背光功能。

    9.全双工RS485电路(带保护功能):带有保护功能,全双工4线通信模式,适合远距离通信用。
     
    10.RS485半双工通信模块:可以通过选择端口选择数据的传输方向,带保护功率。此模块只能工作在5V。


     
    11. ARM JTAG仿真接口电路:比较完善,可以应用在常规的ARM芯片下,具有有自动下载功能,可以用JLINK或ULINK.
     
    12.5V电源模块:这个电路比较简单,如果用直插可以达到1.5A,如果用贴片的可以到达1A。
     
    13.3.3电源模块:可以到达800mA,价格非常便宜,也有相应的1.8/1.2的芯片,可以直接替换。
     
    14.最常用的开关电源:
     
    15.DS1302数字时钟:一款非常普及的时钟电路,好用,成本低。
     
    16.AT24C02(EEPROM):最常用的EEPROM电路。
     
    17.蜂鸣器驱动:这个电路简单就不多说了。
     
    展开全文
  • 终于是暑假了,开始有点时间了,把以前... 大创项目全称就是 基于单片机的智能窗帘的研究与设计 这是一个很老也很简单的项目了,当时大二寻找题目申请大创的时候,还是个连51单片机都才学一般的菜鸟,总怕自己最后做...

            终于是暑假了,开始有点时间了,把以前做的一些小东西总结一下,其实大创是很早就已经完成了,只不过学校一直到四月份才开始验收结题。项目比较简单,也很方便就能验证功能,比较适合初学者练手,所以大概分享一下。

            大创项目全称就是 基于单片机的智能窗帘的研究与设计 这是一个很老也很简单的项目了,当时大二寻找题目申请大创的时候,还是个连51单片机都才学一般的菜鸟,总怕自己最后做不出来,大创结题不了(事实证明,想要结题还是很容易的,毕竟学校也不想让你毕不了业),所以一直在找哪种名字听起来比较高级,实际比较简单的题目,于是就找到了这个题目。

           一开始是想用51单片机做的,毕竟网上资料也比较多,但是很快就发现,其实51单片机的市场应用已经太久了,比较老了,既然学校有经费资助,于是我就想从头开始学性能更好,资源更加多的STM32单片机了,因为之前学过51了,所以在学习32时概念理解上会比较快,比较容易上手,其实去学后会发现在库函数的帮助下,32用起来不会比51难很多,我当时也是直接买了正点的mini板开始自学,后来参加电设也用上了,所以还是比较值的,不过我觉得学任何东西还是要有目标的去学,比如说要完成一个什么功能,一个什么项目这种,不能拿来视频就开始看,虽然随便一个视频可能都是你没学过的,但是没有项目来督促或则说激励你,要么就会学不下去,要么学完很快就忘了,我学习51就是这样,自己买了开发板开始学,看完视频感觉自己开发板已经掌握的差不多了就搁那不管了,到申请大创项目时,我脑子里也没有一个基本的程序思路。以后想深入学习下matlab,也是想先找几个项目开始学,目标是完成项目,所以就要先学项目所需要的一些功能。

           下面开始说这个项目把。这个智能窗帘要完成的功能也比较简单,就是有手动控制模式和自动控制模式,手动通过红外遥控器实现,自动就是通过光敏电阻测光强度来自动调整窗帘位置,这个项目比较适合用上下升降的窗帘。在手动模式下,只能通过红外遥控控制,但是光强等其它一些参数还是会测量显示;自动模式下,就是先测光强,然后更设定阈值进行比较,然后调整窗帘升降,阈值可以通过按键或者遥控器设置。TFT-LCD屏幕的显示界面如下,界面其实是可以优化一下的,比较懒就没去弄。

    然后验证功能我用的是28BYJ-48步进电机,但是单片机直接驱动不了,需要一个驱动,我用的是ULN2003,演示的时候还是搭了一个模型的,不过已经被我拆了,没有照片了。

    贴个主函数吧,完整的工程我用百度云分享。

    我MDK里是有打注释的,不过一复制到外面就乱码了,变量含义我截图放一下,其他不清楚就下载工程看一下吧

    主函数代码如下:

            顺便说一下我编整个程序的思路,可以看到我设置了很多标志位或者变量,因为我从显示界面开始编写的,有时候也会从按键开始,然后期间每用到一个参数或需要判断的标志就定义一个变量,然后显示界面跟按键写完后,然后根据设置的需要的变量去编写这些参数来源的代码,如光强度通过ADC读取光敏电阻两端电压换算而来,然后再慢慢把用到的变量的来源补充完整,整个程序就慢慢成形了,其他再修修补补就好了。先写显示的代码其实是为了后面写代码过程中可以将一些参数暂时显示出来,这样方便找错,或验证程序运行是否正确。 

    #include "led.h"
    #include "delay.h"
    #include "sys.h"
    #include "usart.h"
    #include "lcd.h"
    #include "remote.h"
    #include "rtc.h"
    #include "stdio.h"
    #include "adc.h"
    #include "key.h"
    #include "motor.h"
    #include "ds18b20.h"
    
    #define Left 0
    #define Right 1
    ////************************************±äÁ¿¶¨Òå************************************//
    	  	
    	u8 Remote_scan; //ºìÍâɨÃè·µ»Ø¼üÖµ
    	u8 Remote_Cmd=0; //0Ϊ×Ô¶¯Ä£Ê½£¬1ΪºìÍâÒ£¿Øģʽ
    	u8 Remote_Left_Right; //0 left   1 right
    	u8* Remote_Key_Str;
    	u8 Time_Record=0; //
    	u8 Motor_Update=1;
    	u8 Motor_CW_Cmd=1;
    	u8 Motor_CCW_Cmd=1;
    	u8 Key_Scan_Cmd=1;
    	u8 Key_Scan;
    	u8 RTC_Sec=0;  //RTC Ãë¸üÐÂ	    
    	//u8 LCD_dir=1;	
    	u8 LCD_Display_Update=1; //LCD ¸üÐÂÏÔʾ
    	u8 LCD_Display_Page=0;  //LCDÏÔʾҳÃæ
    	u8 LCD_Display_Line=1;  //LCDÏÔʾҳÃæ
    	u8 LCD_Clear_Old=0;
    	u8 LCD_Clear_New=0;	
    
    	
    	u8 Temp_Light_Get_Cmd=1;
    	float Light_voltage;   //ADC»»ËãµçѹºóÖ
    	float Light_Intensity=0;  //0-100 ¹âÇ¿¶È
    	u8 Light_HighLimit=35;  //µÚ¶þÒ³¹âÇ¿ÉÏÏÞ
    	u8 Light_LowLimit=30;     //µÚ¶þÒ³¹âÇ¿ÏÂÏÞ
    	short DS18B20_Temperature;  //18B20Ëù²âζÈ
    	u8 Temperature_HighLimit=30;//µÚ¶þҳζÈÉÏÏÞ
    	u8 Temperature_LowLimit=10;  //µÚ¶þҳζÈÏÂÏÞ
      u8 LCD_Str[30];   //ÏÔʾ×Ö·ûÔÝ´æÊý×é
    	u8 Motor_Opendegree=0; //´°Á±¿ªºÏ³Ì¶È
    	
    //************************************º¯Êý¶¨Òå************************************//
    
    
    
     int main(void)
     { 
    	 
    		NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	 	 
    		delay_init();	    	 //ÑÓʱº¯Êý³õʼ»¯	  
    		uart_init(9600);	 	//´®¿Ú³õʼ»¯Îª9600
    	 	LED_Init();		  		//³õʼ»¯ÓëLEDÁ¬½ÓµÄÓ²¼þ½Ó¿Ú	
    	 KEY_Init();
    	  Adc_Init();
       Moto_Init();
    	 Remote_Init();
    	 Motor_Locate(100,2000); // ÉèÖà ´°Á±³õ ʼλÖÃ
    	 	LCD_Init();
    		LCD_Display_Dir(1);
    		POINT_COLOR=BLUE;
    		LCD_DrawRectangle(20,20,300,220);  //»­·½¿ò  x1 y1; x2 y2
    
    //		 while(DS18B20_Init())
    //		 {
    //			 LCD_ShowString(40,100,60,12,12,"DS18B20 error!!!");
    //			 delay_ms(500);
    //		 }
    	 
    		while(RTC_Init())   /////////  RTC³õʼ»¯£¬ÉèÖÿªÊ¼Ê±¼ä
    		{
    			LCD_ShowString(20,20,60,12,12,"error!!!");
    			delay_ms(800);
    		}
    		
    		LCD_ShowString(30,180,300,16,16,"real time :     -  -  ");
    		LCD_ShowString(30,200,300,16,16,"real time :     :  :  ");
    		POINT_COLOR=BLUE;
    		LCD_ShowNum(126,180,calendar.w_year,4,16);
    		LCD_ShowNum(166,180,calendar.w_month,2,16);
    		LCD_ShowNum(190,180,calendar.w_date,2,16);
    		LCD_ShowNum(142,200,calendar.hour,2,16);
    		LCD_ShowNum(166,200,calendar.min,2,16);
    		LCD_ShowNum(192,200,calendar.sec,2,16);		
    		
    		DS18B20_Temperature=DS18B20_Get_Temp();
      while(1) 
    	{		
    		
    		if(RTC_Sec!=calendar.sec)
    		{
    			RTC_Sec=calendar.sec;
    			POINT_COLOR=BLUE;
    			LCD_ShowNum(126,180,calendar.w_year,4,16);
    			LCD_ShowNum(166,180,calendar.w_month,2,16);
    			LCD_ShowNum(190,180,calendar.w_date,2,16);
    			LCD_ShowNum(142,200,calendar.hour,2,16);
    			LCD_ShowNum(166,200,calendar.min,2,16);
    			LCD_ShowNum(192,200,calendar.sec,2,16);
    			LED0=!LED0;	
    			Temp_Light_Get_Cmd=1;
    		}
    		
    //µç»úÐýתλÖÃÏÞÖÆ
    		if(current_angle<100) Motor_CCW_Cmd=0;
    		else if(current_angle>2100) Motor_CW_Cmd=0;
    		else 
    		{
    			Motor_CCW_Cmd=1;
    			Motor_CW_Cmd=1;
    		}
    				
    //ºìÍâÒ£¿ØɨÃè	
    		Remote_scan=Remote_Scan();//Remote_State
    		if(Remote_scan)
    		{	 
    			switch(Remote_scan)  //ºìÍâ°´¼üʶ±ð
    			{
    				case 0:Remote_Key_Str="ERROR    ";break;			   
    				case 162: Remote_Key_Str="POWER  ";
    									LCD_Clear_Old--;
    									Remote_Cmd=!Remote_Cmd;break;	    
    				case 98:Remote_Key_Str="UP      ";
    									if(Remote_Cmd==0)
    									{
    										if(LCD_Display_Page==1)
    															{
    																switch(LCD_Display_Line)
    																{
    																	case 1: Temperature_HighLimit++;
    																					Temperature_HighLimit=(Temperature_HighLimit>40)?40:Temperature_HighLimit;
    																					break;
    																	case 2: Temperature_LowLimit++;
    																					Temperature_LowLimit=(Temperature_LowLimit>Temperature_HighLimit)?(Temperature_HighLimit-1):Temperature_LowLimit;
    																					break;
    																	case 3: Light_HighLimit++;
    																					Light_HighLimit=(Light_HighLimit>100)?100:Light_HighLimit;
    																					break;
    																	case 4: Light_LowLimit++;
    																					Light_LowLimit=(Light_LowLimit>Light_HighLimit)?(Light_HighLimit-1):Light_LowLimit;
    																					break;
    																	default:break;
    																}
    															}
    									}break;	    
    				case 2:Remote_Key_Str="PLAY     ";break;		 
    				case 226:Remote_Key_Str="ALIENTEK";break;		  
    				case 194:Remote_Key_Str="RIGHT  ";
    									Remote_Left_Right=Right;break;	   
    				case 34:Remote_Key_Str="LEFT    ";
    									Remote_Left_Right=Left;break;		  
    				case 224:Remote_Key_Str="VOL-   ";break;		  
    				case 168:Remote_Key_Str="DOWN   ";
    									if(Remote_Cmd==0)
    									{
    										if(LCD_Display_Page==1)
    															{
    																switch(LCD_Display_Line)
    																{
    																	case 1: Temperature_HighLimit--;
    																					Temperature_HighLimit=(Temperature_HighLimit<Temperature_LowLimit)?(Temperature_LowLimit+1):Temperature_HighLimit;
    																					break;
    																	case 2: Temperature_LowLimit--;
    																					Temperature_LowLimit=(Temperature_LowLimit<10)?10:Temperature_LowLimit;
    																					break;
    																	case 3: Light_HighLimit--;
    																					Light_HighLimit=(Light_HighLimit<Light_LowLimit)?(Light_LowLimit+1):Light_HighLimit;
    																					break;
    																	case 4: Light_LowLimit--;
    																					Light_LowLimit=(Light_LowLimit<10)?10:Light_LowLimit;
    																					break;
    																	default:break;
    																}
    															}
    									}break;		   
    				case 144:Remote_Key_Str="VOL+   ";break;		    
    				case 104:Remote_Key_Str="1      ";break;		  
    				case 152:Remote_Key_Str="2      ";break;	   
    				case 176:Remote_Key_Str="3      ";break;	    
    				case 48:Remote_Key_Str="4      ";break;		    
    				case 24:Remote_Key_Str="5      ";break;		    
    				case 122:Remote_Key_Str="6      ";break;		  
    				case 16:Remote_Key_Str="7      ";break;			   					
    				case 56:Remote_Key_Str="8      ";break;	 
    				case 90:Remote_Key_Str="9      ";break;
    				case 66:Remote_Key_Str="0      ";break;
    				case 82:Remote_Key_Str="DELETE ";break;		 
    			}
    		}
    		
    //Ò£¿ØÆ÷ÊÖ¶¯¿ØÖÆ   ģʽ******************************************************************
    		if(Remote_Cmd==1) 
    		{
    				if(LCD_Clear_Old==LCD_Clear_New)  //ÇåÆÁ×ÔËø£¬²»È»ÏÔʾµÄÎÄ×Ö»áÉÁ˸
    				{
    					LCD_Clear_New--;
    					LCD_Fill(22,22,298,178,WHITE);	//Çå³þ֮ǰµÄÏÔʾ
    				}						
    				LCD_ShowString(30,120,200,24,24,"SYMBOL:");
    				LCD_ShowString(126,120,14*12,24,24,Remote_Key_Str);	//ÏÔʾSYMBOL
    				sprintf((char*)LCD_Str,"Motor Angle: %d          ",current_angle-100);  // "Open Degree: %d%%        "
    				LCD_ShowString(30,150,20*8,16,16,LCD_Str);
    
    				if(Motor_CCW_Cmd==1||Motor_CW_Cmd==1)
    				{
    						switch(Remote_Left_Right)
    						{
    							case Left:  Remote_Left_Right=3;
    													if(current_angle>(-50))
    													{
    														Motorccw_angle(50,2000);break;   //Ò£¿ØÆ÷°´ÏÂ×ó,ÒÔ2000ËÙ¶ÈÕý´«360¶È
    													}
    							case Right: Remote_Left_Right=3;
    													if(current_angle<2200)
    													{
    														Motorcw_angle(50,2000);break;
    													}
    													
    						}
    				}
    		}
    //×Ô¶¯¿ØÖÆ    ģʽ********************************************************************
    		else if(Remote_Cmd==0)
    		{
    				if(LCD_Clear_Old==LCD_Clear_New)
    				{
    					LCD_Clear_New--;
    					LCD_Fill(22,22,298,178,WHITE);	//Çå³þ֮ǰµÄÏÔʾ
    				}
    				
    				
    	  //ζȻñÈ¡×Ó³ÌÐò
    					if(Temp_Light_Get_Cmd==1)
    					{
    						Temp_Light_Get_Cmd=0;
    						//DS18B20_Temperature=DS18B20_Get_Temp();
    						Light_voltage=Get_Adc(1)*3.3/4096;
    						Light_Intensity=(3.3-Light_voltage)*100/3.3;
    						
    						LCD_Display_Update=1;  //»ñÈ¡ÍêζȹâÇ¿ÐèÒª¸üÐÂÏÔʾÒÔ¼°µç»úλÖÃ
    						Motor_Update=1;
    					}
    			//¸ù¾Ý¹âÇ¿¶Èµ÷½Úµç»úλÖÃ		
    					if(Motor_CW_Cmd==1&&(Light_Intensity<Light_LowLimit))
    					{
    								Motorcw_angle(10,2000);
    					}
    					else if(Motor_CCW_Cmd&&(Light_Intensity>Light_HighLimit))
    							{
    								Motorccw_angle(10,2000);
    							}
    					
    
    				////°´¼ü×Ó³ÌÐò	ÿ50msɨÃèÒ»´Î	
    					//if(Time_Record%2==0) Key_Scan_Cmd=1;
    					Key_Scan_Cmd=1;
    					if(Key_Scan_Cmd==1)
    					{
    						Key_Scan_Cmd=0;
    						Key_Scan=KEY_Scan(0);
    
    						if(Key_Scan!=0) LCD_Display_Update=1;  //ÈôÓа´¼ü±»°´Ï£¬ÐèÒª¸üÐÂÏÔʾ
    					switch(Key_Scan)
    						{
    							case KEY0_PRES: if(LCD_Display_Page==1)
    															{
    																switch(LCD_Display_Line)
    																{
    																	case 1: Temperature_HighLimit++;
    																					Temperature_HighLimit=(Temperature_HighLimit>40)?40:Temperature_HighLimit;
    																					break;
    																	case 2: Temperature_LowLimit++;
    																					Temperature_LowLimit=(Temperature_LowLimit>Temperature_HighLimit)?(Temperature_HighLimit-1):Temperature_LowLimit;
    																					break;
    																	case 3: Light_HighLimit++;
    																					Light_HighLimit=(Light_HighLimit>100)?100:Light_HighLimit;
    																					break;
    																	case 4: Light_LowLimit++;
    																					Light_LowLimit=(Light_LowLimit>Light_HighLimit)?(Light_HighLimit-1):Light_LowLimit;
    																					break;
    																	default:break;
    																}
    															}
    															
    															break;
    															
    							case KEY1_PRES: if(LCD_Display_Page==1)
    															{
    																switch(LCD_Display_Line)
    																{
    																	case 1: Temperature_HighLimit--;
    																					Temperature_HighLimit=(Temperature_HighLimit<Temperature_LowLimit)?(Temperature_LowLimit+1):Temperature_HighLimit;
    																					break;
    																	case 2: Temperature_LowLimit--;
    																					Temperature_LowLimit=(Temperature_LowLimit<10)?10:Temperature_LowLimit;
    																					break;
    																	case 3: Light_HighLimit--;
    																					Light_HighLimit=(Light_HighLimit<Light_LowLimit)?(Light_LowLimit+1):Light_HighLimit;
    																					break;
    																	case 4: Light_LowLimit--;
    																					Light_LowLimit=(Light_LowLimit<10)?10:Light_LowLimit;
    																					break;
    																	default:break;
    																}
    															}break;
    															
    							case WKUP_PRES: if(LCD_Display_Page==0) LCD_Display_Page=1;
    															else 
    															{
    																LCD_Display_Line++;
    																if(LCD_Display_Line==5) 
    																{
    																	LCD_Display_Line=1;
    																	LCD_Display_Page=0;
    																}
    															}break;
    							default:break;
    						}
    						
    					}
    					
    					if(LCD_Display_Update==1)
    					{
    						LCD_Display_Update=0;
    						if(LCD_Display_Page==0)
    						{
    							LCD_ShowString(25,40,400,16,16,"                             ");
    							LCD_ShowString(128,40,72,16,16,"Parameter");
    							sprintf((char*)LCD_Str,"Light      : %.1f        ",Light_Intensity); //
    							LCD_ShowString(30,80,25*8,16,16,LCD_Str);
    							sprintf((char*)LCD_Str,"Temperature: %2d.%d C         ",DS18B20_Temperature/10,DS18B20_Temperature%10);
    							LCD_ShowString(30,120,25*8,16,16,LCD_Str);
    							sprintf((char*)LCD_Str,"Motor Angle: %d          ",current_angle-100);  // "Open Degree: %d%%        "
    							LCD_ShowString(30,150,20*8,16,16,LCD_Str);
    						}
    						else //if(LCD_Display_Page==1)
    						{
    							POINT_COLOR=BLUE;
    							if(LCD_Display_Line==1) POINT_COLOR=RED;
    							sprintf((char*)LCD_Str,"Temp_HighLimit : %d C   ",Temperature_HighLimit); //
    							LCD_ShowString(30,40,25*8,16,16,LCD_Str);
    							POINT_COLOR=BLUE;
    							if(LCD_Display_Line==2) POINT_COLOR=RED;
    							sprintf((char*)LCD_Str,"Temp_LowLimit  : %d C    ",Temperature_LowLimit);
    							LCD_ShowString(30,80,25*8,16,16,LCD_Str);
    							POINT_COLOR=BLUE;
    							if(LCD_Display_Line==3) POINT_COLOR=RED;
    							sprintf((char*)LCD_Str,"Light_HighLimit: %d      ",Light_HighLimit);  //
    							LCD_ShowString(30,120,25*8,16,16,LCD_Str);
    							POINT_COLOR=BLUE;
    							if(LCD_Display_Line==4) POINT_COLOR=RED;
    							sprintf((char*)LCD_Str,"Light_HighLimit: %d       ",Light_LowLimit);  //
    							LCD_ShowString(30,150,25*8,16,16,LCD_Str);
    							POINT_COLOR=BLUE;
    						}
    					}
    				Time_Record++;
    				if(Time_Record==100) Time_Record=0;
    				delay_ms(10);
    
    		}		
    		
    		
    	}
    }	
    		
    

           刚开始的时候,感觉结题这个项目都有困难,但是慢慢学习单片机,了解了一些这方面的资料后,就会发现这个项目很简单,因为不怎么需要硬件方面的知识,现在支持STM32的各种模块非常多,基本不用自己搭电路,一开始光敏电阻的模拟以及数字苏输入我是想自己买光敏电阻搭电路的,后来发现模块非常的便宜,也比自己搭的肯定要稳定,毫不犹豫就买了模块。 

    完整工程请查看:

           链接:https://pan.baidu.com/s/1W5-XI9iZV1pG2jMLjq1gGw       提取码:fo0z 

           这个代码是正点精英板的代码,因为驱动步进电机要比较大的电流,mini板上没有那种能提供大电流的电源接口。

     

    展开全文
  • GY-30数字光强度模块BH1750FVI资料。压缩包内含数据手册、接线图(原理图)、STC89c52用Lcd1602显示光照度数据的例子程序、还有avr的例子程序。资料是网上找到的,这段时间在用这个模块,用的89c52,资料没有问题,...

    GY-30数字光强度模块BH1750FVI资料。压缩包内含数据手册、接线图(原理图)、STC89c52用Lcd1602显示光照度数据的例子程序、还有avr的例子程序。资料是网上找到的,这段时间在用这个模块,用的89c52,资料没有问题,lcd1602显示模块采集的光照度。

    GY-30数字光强度模块BH1750FVI:

    下面是stc89c52中的接线图

    avr中的接线图:

    代码甩上:

    //***************************************
    // BH1750FVI IIC测试程序
    // 使用单片机STC89C51 
    // 晶振:11.0592M
    // 显示:LCD1602
    // 编译环境 Keil uVision2
    // 参考宏晶网站24c04通信程序
    //****************************************
    #include  <REG51.H>        
    #include  <math.h>    //Keil library  
    #include  <stdio.h>   //Keil library        
    #include  <INTRINS.H>
    #define   uchar unsigned char
    #define   uint unsigned int        
    #define   DataPort P0         //LCD1602数据端口
    sbit          SCL=P1^0;      //IIC时钟引脚定义
    sbit            SDA=P1^1;      //IIC数据引脚定义
    sbit      LCM_RS=P2^6;   //LCD1602命令端口                
    sbit      LCM_RW=P2^5;   //LCD1602命令端口                
    sbit      LCM_EN=P2^7;   //LCD1602命令端口 
    
    #define          SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
                                  //ALT  ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
    typedef   unsigned char BYTE;
    typedef   unsigned short WORD;
    
    BYTE    BUF[8];                         //接收数据缓存区              
    uchar   ge,shi,bai,qian,wan;            //显示变量
    int     dis_data;                       //变量
    
    void delay_nms(unsigned int k);
    void InitLcd();
    void Init_BH1750(void);
    
    void WriteDataLCM(uchar dataW);
    void WriteCommandLCM(uchar CMD,uchar Attribc);
    void DisplayOneChar(uchar X,uchar Y,uchar DData);
    void conversion(uint temp_data);
    
    void  Single_Write_BH1750(uchar REG_Address);               //单个写入数据
    uchar Single_Read_BH1750(uchar REG_Address);                //单个读取内部寄存器数据
    void  Multiple_Read_BH1750();                               //连续的读取内部寄存器数据
    //------------------------------------
    void Delay5us();
    void Delay5ms();
    void BH1750_Start();                    //起始信号
    void BH1750_Stop();                     //停止信号
    void BH1750_SendACK(bit ack);           //应答ACK
    bit  BH1750_RecvACK();                  //读ack
    void BH1750_SendByte(BYTE dat);         //IIC单个字节写
    BYTE BH1750_RecvByte();                 //IIC单个字节读
    
    //-----------------------------------
    
    //*********************************************************
    void conversion(uint temp_data)  //  数据转换出 个,十,百,千,万
    {  
        wan=temp_data/10000+0x30 ;
        temp_data=temp_data%10000;   //取余运算
            qian=temp_data/1000+0x30 ;
        temp_data=temp_data%1000;    //取余运算
        bai=temp_data/100+0x30   ;
        temp_data=temp_data%100;     //取余运算
        shi=temp_data/10+0x30    ;
        temp_data=temp_data%10;      //取余运算
        ge=temp_data+0x30;         
    }
    
    //毫秒延时**************************
    void delay_nms(unsigned int k)        
    {                                                
    unsigned int i,j;                                
    for(i=0;i<k;i++)
    {                        
    for(j=0;j<121;j++)                        
    {;}}                                                
    }
    
    /*******************************/
    void WaitForEnable(void)        
    {                                        
    DataPort=0xff;                
    LCM_RS=0;LCM_RW=1;_nop_();
    LCM_EN=1;_nop_();_nop_();
    while(DataPort&0x80);        
    LCM_EN=0;                                
    }                                        
    /*******************************/
    void WriteCommandLCM(uchar CMD,uchar Attribc)
    {                                        
    if(Attribc)WaitForEnable();        
    LCM_RS=0;LCM_RW=0;_nop_();
    DataPort=CMD;_nop_();        
    LCM_EN=1;_nop_();_nop_();LCM_EN=0;
    }                                        
    /*******************************/
    void WriteDataLCM(uchar dataW)
    {                                        
    WaitForEnable();                
    LCM_RS=1;LCM_RW=0;_nop_();
    DataPort=dataW;_nop_();        
    LCM_EN=1;_nop_();_nop_();LCM_EN=0;
    }                
    /***********************************/
    void InitLcd()                                
    {                        
    WriteCommandLCM(0x38,1);        
    WriteCommandLCM(0x08,1);        
    WriteCommandLCM(0x01,1);        
    WriteCommandLCM(0x06,1);        
    WriteCommandLCM(0x0c,1);
    }                        
    /***********************************/
    void DisplayOneChar(uchar X,uchar Y,uchar DData)
    {                                                
    Y&=1;                                                
    X&=15;                                                
    if(Y)X|=0x40;                                        
    X|=0x80;                        
    WriteCommandLCM(X,0);                
    WriteDataLCM(DData);                
    }                                                
    
    /**************************************
    延时5微秒(STC90C52RC@12M)
    不同的工作环境,需要调整此函数,注意时钟过快时需要修改
    当改用1T的MCU时,请调整此延时函数
    **************************************/
    void Delay5us()
    {
        _nop_();_nop_();_nop_();_nop_();
        _nop_();_nop_();_nop_();_nop_();
            _nop_();_nop_();_nop_();_nop_();
            _nop_();_nop_();_nop_();_nop_();
    }
    
    /**************************************
    延时5毫秒(STC90C52RC@12M)
    不同的工作环境,需要调整此函数
    当改用1T的MCU时,请调整此延时函数
    **************************************/
    void Delay5ms()
    {
        WORD n = 560;
    
        while (n--);
    }
    
    /**************************************
    起始信号
    **************************************/
    void BH1750_Start()
    {
        SDA = 1;                    //拉高数据线
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SDA = 0;                    //产生下降沿
        Delay5us();                 //延时
        SCL = 0;                    //拉低时钟线
    }
    
    /**************************************
    停止信号
    **************************************/
    void BH1750_Stop()
    {
        SDA = 0;                    //拉低数据线
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SDA = 1;                    //产生上升沿
        Delay5us();                 //延时
    }
    
    /**************************************
    发送应答信号
    入口参数:ack (0:ACK 1:NAK)
    **************************************/
    void BH1750_SendACK(bit ack)
    {
        SDA = ack;                  //写应答信号
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        SCL = 0;                    //拉低时钟线
        Delay5us();                 //延时
    }
    
    /**************************************
    接收应答信号
    **************************************/
    bit BH1750_RecvACK()
    {
        SCL = 1;                    //拉高时钟线
        Delay5us();                 //延时
        CY = SDA;                   //读应答信号
        SCL = 0;                    //拉低时钟线
        Delay5us();                 //延时
    
        return CY;
    }
    
    /**************************************
    向IIC总线发送一个字节数据
    **************************************/
    void BH1750_SendByte(BYTE dat)
    {
        BYTE i;
    
        for (i=0; i<8; i++)         //8位计数器
        {
            dat <<= 1;              //移出数据的最高位
            SDA = CY;               //送数据口
            SCL = 1;                //拉高时钟线
            Delay5us();             //延时
            SCL = 0;                //拉低时钟线
            Delay5us();             //延时
        }
        BH1750_RecvACK();
    }
    
    /**************************************
    从IIC总线接收一个字节数据
    **************************************/
    BYTE BH1750_RecvByte()
    {
        BYTE i;
        BYTE dat = 0;
    
        SDA = 1;                    //使能内部上拉,准备读取数据,
        for (i=0; i<8; i++)         //8位计数器
        {
            dat <<= 1;
            SCL = 1;                //拉高时钟线
            Delay5us();             //延时
            dat |= SDA;             //读数据               
            SCL = 0;                //拉低时钟线
            Delay5us();             //延时
        }
        return dat;
    }
    
    //*********************************
    
    void Single_Write_BH1750(uchar REG_Address)
    {
        BH1750_Start();                  //起始信号
        BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号
        BH1750_SendByte(REG_Address);    //内部寄存器地址,请参考中文pdf22页 
      //  BH1750_SendByte(REG_data);       //内部寄存器数据,请参考中文pdf22页 
        BH1750_Stop();                   //发送停止信号
    }
    
    //********单字节读取*****************************************
    /*
    uchar Single_Read_BH1750(uchar REG_Address)
    {  uchar REG_data;
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress);           //发送设备地址+写信号
        BH1750_SendByte(REG_Address);                   //发送存储单元地址,从0开始        
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
        REG_data=BH1750_RecvByte();              //读出寄存器数据
            BH1750_SendACK(1);   
            BH1750_Stop();                           //停止信号
        return REG_data; 
    }
    */
    //*********************************************************
    //
    //连续读出BH1750内部数据
    //
    //*********************************************************
    void Multiple_read_BH1750(void)
    {   uchar i;        
        BH1750_Start();                          //起始信号
        BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
            
             for (i=0; i<3; i++)                      //连续读取6个地址数据,存储中BUF
        {
            BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据
            if (i == 3)
            {
    
               BH1750_SendACK(1);                //最后一个数据需要回NOACK
            }
            else
            {                
              BH1750_SendACK(0);                //回应ACK
           }
       }
    
        BH1750_Stop();                          //停止信号
        Delay5ms();
    }
    
    
    //初始化BH1750,根据需要请参考pdf进行修改****
    void Init_BH1750()
    {
       Single_Write_BH1750(0x01);  
    
    }
    //*********************************************************
    //主程序********
    //*********************************************************
    void main()
    {  
       float temp;
       delay_nms(200);            //延时200ms        
       InitLcd();           //初始化LCD
       Init_BH1750();       //初始化BH1750
    
      while(1)              //循环
      { 
    
        Single_Write_BH1750(0x01);   // power on
        Single_Write_BH1750(0x10);   // H- resolution mode
    
         delay_nms(180);              //延时180ms
    
        Multiple_Read_BH1750();       //连续读出数据,存储在BUF中
    
        dis_data=BUF[0];
        dis_data=(dis_data<<8)+BUF[1];//合成数据 
    
        temp=(float)dis_data/1.2;
    
        conversion(temp);         //计算数据和显示
            DisplayOneChar(0,0,'L'); 
            DisplayOneChar(1,0,'i'); 
    

     

    展开全文
  • 使用C语言编写的,用来测试cc2530单片机测光功能的代码,需使用IAR来打开,单片机需连接光敏传感器模块,使用串口调试助手调试。
  • 光敏二极管 光敏二极管简介 光敏传感器是最常见的传感器之一,它的种类繁多,主要有:光电管、光电倍增管、光敏电阻、光敏三极管、太阳能电池、红外线传感器、紫外线传感器、光纤式光电传感器、色彩传感器、CCD和...
  • 串行通信协议是用于工业设备之间数据通信的应用最广泛的通信协议。绝大多数工业设备都有串行接口。并且,目前是互联网的时代,因为许多用户的功能或服务都是通过互联网实现的。比如,诸如电视,DVD和影音系统等消费...
  • 功能 实现可见光通信。(具体私聊) 实物图 联系方式: QQ:353700750 WeChat:15527961008 请务必备注来意!!!
  • 硬件部分:先来看硬件连接图,此次实验选择ADC3的通道7,硬件原理图如图1所示,光敏电阻的原理在图1中已经说明,这里就不再多说。图2是stm32的部分引脚图。图1图 3软件部分:软件部分主要是三个方面,一是使用ADC时...
  • 220V AC全波检测电路,只需要一个光耦就可以了。 R1很重要一定要用大功率的。并且阻值尽可能大,取100K~330K都可以,因为R1在这里限流作用,如果去掉,光耦很容易损坏。 当220V有电时,通过全波整流后,光耦就会导...
  • 写在前面最近在从零开始写一个移动端的AR系统,坑实在是太多了!!!整个项目使用了OpenCV第三方库,但对于摄像机来说,和原生Camera的方法基本相同。实现以OpenCV的JavaCameraView为例,首先需要定制自己的Camera,...
  • 记录一下IIC比较典型应用 传感器相关介绍 //引脚定义 硬件IC--》复用开漏 普通IO---》通用推挽 #define B_LUX_V20_SCL0_O {\ GPIO_InitTypeDef GPIO_ST; \ GPIO_ST.GPIO_Pin = GPIO...
  • 一、摄影基础知识 相机 有使用胶卷的(FC):胶卷单反照相机、胶卷便携式照相机 和使用数码的(DC):数码单反照相机、数码便携式照相机 镜头的焦距:7.58mm-32mm 1:2.6-5.1 (最大光圈值) ...
  • 若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 本文章博客地址:... 目录 前话 Demo:摄像头CSI的拍照程序 树莓派摄像头 ......
  • 1. 引言 随着国内经济的迅猛发展,全国的大小城市也在迅速扩大,大量人口快速地涌入和人口出行的需求也出现几何的增长,这就导致了城市交通运输的日益紧张。发展公共交通是缓解城市交通运输压力的有效方法。...
  • 本文写于2010年暑假,是针对10年的省电设写的,马上电子设计竞赛又要来了,算是一点小的经验分享,希望对大家能有所帮助。 emouse   参加过这么次比赛,尤其是去年的全国大学生电子设计竞赛,让我感受深刻,因此...
1
收藏数 20
精华内容 8
关键字:

单片机测光强