搜索

[活动专区] 【赛元SC95F】+ 测试各种传感器和OLED显示(三)

[复制链接]
619|6
 楼主 | 2020-3-31 20:53 | 显示全部楼层 |阅读模式
本次测试测试了:DS18B20温度传感器,DHT11温湿度传感器,人体红外感应和VS1838B红外按键解码。
DS18B20:Pin---》P12
DHT11:   Pin---》P54
红外人体感应:Pin-----》P17
VS1838B解码:Pin-----》P16
OLED屏:
OLED_RES_PIN     (P47)        // 复位                                       
OLED_DC_PIN      (P06)        // 数据/命令控制               
OLED_CS_PIN      (P46)        // 片选                                       
OLED_DIN_PIN     (P05)        // D1(MOSI)数据               
OLED_CLK_PIN     (P04)     // D0(SCLK) 时钟                
  1. /*=============================================================================
  2. * filename:        DHT11.c
  3. * author:                Wood Wang
  4. * date:                2020.03
  5. * describe:       
  6. *===========================================================================*/
  7. /* Includes -----------------------------------------------------------------*/
  8. #include "main.h"


  9. //=================================================================
  10. //        DHT11温湿度传感器
  11. //=================================================================
  12. sbit DHT_Pin = P5^4;

  13. #define                PinSet()                DHT_Pin = 1
  14. #define                PinClr()                DHT_Pin = 0
  15. #define                PinDirIn()                P5CON &= ~0x10;P5PH |= 0x10;
  16. #define                PinDirOut()                   P5CON |= 0x10;P5PH &= ~0x10;       
  17. #define                PinGet()                DHT_Pin       


  18. //============================================       
  19. uint8_t  DHTReadData(void)
  20. {
  21.         uint8_t i;
  22.         uint8_t RHdata,Timeout;

  23.         RHdata = 0;
  24.         for(i=0;i<8;i++)          
  25.         {               
  26.                  //等待从机50us低电平
  27.                 Timeout = 2;         
  28.                    while((!PinGet()) && Timeout++)        Delay_us(1); //
  29.                 if(Timeout == 1)        break;         //超时则跳出for循环       

  30.                 RHdata <<= 1;
  31.                 Delay_us(4);//等待30us到50us
  32.             if(PinGet())        RHdata |= 0x01;          //判断数据位是0还是1
  33.        
  34.                  //等待数据高电平结束
  35.                 Timeout = 2;                 
  36.                    while((PinGet()) && Timeout++)        Delay_us(1); //                          
  37.                    if(Timeout == 1)        break;         //超时则跳出for循环       


  38.         }       
  39.         return RHdata;          
  40. }

  41. uint8_t RH_Read(uint8_t * rh,uint8_t * t)
  42. {
  43.         unsigned char RHdata[5],Timeout;
  44.        
  45.         *rh = 0;
  46.         *t = 0;
  47.         PinDirOut();
  48.     PinClr();
  49.         Delay_ms(20);  //主机拉低>18ms
  50.         PinSet();       
  51.         Delay_us(2);//总线拉高 主机延时20us-40us

  52.         //主机设为输入 判断从机响应信号
  53.         PinDirIn();       
  54.         PinSet();
  55.         Delay_us(4);
  56.         //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行          
  57.         if(!PinGet())  
  58.         {          
  59.                  //判断从机是否发出 80us 的低电平响应信号是否结束
  60.                 Timeout = 2;         
  61.                    while((!PinGet()) && Timeout++)        Delay_us(1);        //等待IO从低电平到高电平退出  
  62.                    if(Timeout == 1)        return 3;        //超时       

  63.                  //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态
  64.                 Timeout = 2;         
  65.                    while((PinGet()) && Timeout++)        Delay_us(1)        ;                //等待IO从高电平到低电平退出       
  66.                 if(Timeout == 1)        return 3;        //超时

  67.                  //准备数据接收                 
  68.                    RHdata[0] = DHTReadData();
  69.                 RHdata[1] = DHTReadData();
  70.                 RHdata[2] = DHTReadData();
  71.                 RHdata[3] = DHTReadData();
  72.                 RHdata[4] = DHTReadData();

  73.                    PinSet();

  74. //                Uart0SendStrlen(RHdata, 5);
  75.                  //数据校验
  76.                 Timeout = RHdata[0]+RHdata[1]+RHdata[2]+RHdata[3];
  77. //                Uart0Send(0xa1);
  78.                    if(Timeout == RHdata[4])
  79.                    {
  80.                          //数据正确
  81.                         *rh = RHdata[0];
  82.                         *t  = RHdata[2];
  83.                         return 0;
  84.                   }else return 2;
  85.         }
  86. //        Uart0Send(0xa2);
  87.         return 1;
  88. }

  89. uint8_t DHT11_Init(void)
  90. {
  91.         return 0;
  92. }
复制代码
  1. /*=============================================================================
  2. * filename:        DS18B20.c
  3. * author:                Wood Wang
  4. * date:                2020.03
  5. * describe:       
  6. *===========================================================================*/
  7. /* Includes -----------------------------------------------------------------*/
  8. #include "main.h"

  9. //读传感器 端口位定义,可修改
  10. sbit DS18B20_Pin = P1^2;

  11. #define DS18B20_PIN_H()                  DS18B20_Pin = 1;
  12. #define DS18B20_PIN_L()                  DS18B20_Pin = 0;
  13. #define DS18B20_IN()                         DS18B20_Pin
  14. #define DS18B20_DIR_In()                  P1CON &= ~0x04;P1PH |= 0x04;
  15. #define DS18B20_DIR_Out()                  P1CON |= 0x04;P1PH &= ~0x04;
  16.           


  17. void DS18B20_Rst(void)          
  18. {                 
  19.     DS18B20_DIR_Out();                 //SET OUTPUT
  20.     DS18B20_PIN_H();                 //
  21.         DS18B20_PIN_L();                 //低
  22.         Delay_us(80);                    //          0 >480us
  23.         DS18B20_PIN_H();                 //高
  24.         Delay_us(1);                     //
  25. }

  26. U8 DS18B20_Check(void)                                             
  27. {   
  28.         U8 retry=0;

  29.         DS18B20_Rst();
  30.         DS18B20_DIR_In();//SET INPUT         
  31.         while (DS18B20_IN() && retry<200)         
  32.         {
  33.                 retry++;
  34.                 Delay_us(1);
  35.         };         
  36.         if(retry >= 200)        return 1;
  37.         else         retry=0;
  38.    
  39.         while (!DS18B20_IN() && retry<240) //0: 60-240us
  40.         {
  41.                 retry++;
  42.                 Delay_us(1);
  43.         };
  44.         if(retry >= 240)        return 1;            
  45.         return         0;
  46. }

  47. U8 DS18B20_Read_Byte(void)    // read one byte
  48. {        
  49.         U8         i,Data;

  50.         Data=0;
  51.     DS18B20_DIR_Out();//SET OUTPUT
  52.     DS18B20_PIN_H();

  53.         for (i=0;i<8;i++)
  54.         {
  55.         DS18B20_PIN_L();
  56.         Data >>= 1;
  57.         Delay_us(1);
  58.         DS18B20_PIN_H();
  59.         Delay_us(1);

  60.             DS18B20_DIR_In();
  61.         if(DS18B20_IN())   Data|=0x80;

  62.         Delay_us(10);
  63.         DS18B20_DIR_Out();//SET OUTPUT
  64.         DS18B20_PIN_H();                
  65.         }                                                    
  66.         return Data;
  67. }

  68. void DS18B20_Write_Byte(U8 Data)     
  69. {            
  70.         U8 i;
  71.         U8 testb;

  72.         DS18B20_DIR_Out();//SET OUTPUT

  73.         for (i=0;i<8;i++)
  74.         {
  75.                 testb = Data&0x01;
  76.                 Data=Data>>1;
  77.                 if (testb)
  78.                 {
  79.                         DS18B20_PIN_L();
  80.                         Delay_us(1);                           
  81.                         DS18B20_PIN_H();
  82.                         Delay_us(10);            
  83.                 }else
  84.                 {
  85.                         DS18B20_PIN_L();
  86.                         Delay_us(1);            
  87.                         DS18B20_PIN_L();
  88.                         Delay_us(10);                          
  89.                 }
  90.                 DS18B20_PIN_H();
  91.     }
  92. }

  93. U16 DS18B20_Temp_Raw(void)
  94. {
  95.         U8         tl,th;
  96.         U16 tem;

  97.         DS18B20_Rst();          
  98.         if(DS18B20_Check())        return 0;         
  99.         DS18B20_Write_Byte(0xcc);        // skip rom
  100.         DS18B20_Write_Byte(0x44);        // convert

  101.         DS18B20_Rst();
  102.         if(DS18B20_Check())        return 0;         
  103.         DS18B20_Write_Byte(0xcc);// skip rom
  104.         DS18B20_Write_Byte(0xbe);// convert         
  105.           
  106.         tl=DS18B20_Read_Byte(); // LSB   
  107.         th=DS18B20_Read_Byte(); // MSB  
  108.                             
  109.         tem=(th<<8)|tl; //

  110. //        Uart0Send(0xF0);
  111. //        Uart0Send(th);
  112. //        Uart0Send(tl);

  113.         return tem;
  114. }

  115. float DS18B20_TempValue(U16 tem)
  116. {
  117.         if(tem&0xF800)        return -(((~tem)+1)*0.0625); //返回温度值
  118.         else                 return                 (tem*0.0625);  
  119. }

  120. U8 DS18B20_Init(void)     
  121. {
  122.         DS18B20_Rst();
  123.         if(DS18B20_Check())        return 1;
  124.         DS18B20_Temp_Raw();
  125.         return 0;
  126. }


复制代码
  1. /*=============================================================================
  2. * filename:        VS1838B.c
  3. * author:                Wood Wang
  4. * date:                2020.03
  5. * describe:       
  6. *===========================================================================*/
  7. /* Includes -----------------------------------------------------------------*/
  8. #include "main.h"


  9. U8                Ir_Status;
  10. U8                Ir_Press;
  11. U8                Ir_receive_ok;
  12. U8                Ir_Receive_Count;
  13. U32                Ir_Receive_Data;
  14. U16                Interval;

  15. sbit        IR_Pin = P1^6;        //int16


  16. /*
  17. ********************************************************************************
  18.                           红外接收数据处理函数
  19. ********************************************************************************
  20. */
  21. U8 IR_Init(void)
  22. {   
  23.         Ir_Status = 0;
  24.         Ir_receive_ok = 0;
  25.         Ir_Receive_Count = 0;
  26.         Interval = 0;
  27.         Ir_Receive_Data = 0;

  28.         return 0;
  29. }


  30. U8 IR_Process(U8 *Ir_num)
  31. {
  32.   U8 Address_H,Address_L;       //地址码,地址反码
  33.   U8 Data_H,Data_L;             //数据码,数据反码
  34.   
  35.   if(Ir_receive_ok==1)          //接收完成
  36.   {
  37.        Address_H=Ir_Receive_Data>>24;                //得到地址码
  38.        Address_L=(Ir_Receive_Data>>16)&0xff;         //得到地址反码
  39.            Ir_receive_ok = 0;
  40.        //if((Address_H==(u8)~Address_L)&&(Address_H==REMOTE_ID))//检验遥控识别码(ID)及地址
  41.        if((Address_H==(U8)~Address_L))//检验遥控识别码(ID)及地址
  42.        {
  43.             Data_H=Ir_Receive_Data>>8;              //得到数据码
  44.             Data_L=Ir_Receive_Data;                 //得到数据反码
  45.             if(Data_H==(U8)~Data_L)                 //接收数据码正确
  46.             {
  47.                      *Ir_num=Data_H;                      //正确键值返回键值
  48.                            Ir_Receive_Data=0;
  49.                                 return 1;
  50.             }
  51.         }  
  52.    }
  53.    if(Ir_Press)
  54.    {
  55.                 return 2;
  56.    }
  57.    return  0;      
  58. }

  59. //外部中断下降沿调用
  60. void IR_Receive_Handler(void)
  61. {
  62.   U16 Interval_tim=0;//两个下降沿间隔时间

  63.   switch(Ir_Status)
  64.   {
  65.     case 0://第一个下降沿,定时器开始计数                    
  66.             Ir_Status=1;
  67.                         Interval = 0;
  68.                         TR1 = 1;
  69.                         Ir_Press = 0;         //无按下
  70.             break;
  71.                         
  72.     case 1://第二个下降沿,定时器关闭,读取定时器计数值            
  73.             //读取定时器计数值
  74.                         Interval_tim = Interval;
  75.                         Interval = 0;
  76.                         //Uart0Send(Interval_tim);
  77.             if( (Interval_tim>=120)&&(Interval_tim<=150) )//判断引导码是否正确9+4.5ms                        
  78.             {
  79.                 Ir_Status=2;         //进入下一状态  
  80.             }else            //引导码错误,从新接收
  81.             {
  82.                 Ir_Status=0;
  83.                                 TR1 = 0;
  84.                 Ir_Receive_Count=0;
  85.             }                                               
  86.             break;
  87.                         
  88.     case 2://开始32位数据的接收
  89.                         //读取定时器计数值  
  90.                         Interval_tim = Interval;
  91.                         Interval = 0;     
  92.             if( (Interval_tim>=9)&&(Interval_tim<=13) )        //间隔1.12ms ->0
  93.             {
  94.                   Ir_Receive_Data=Ir_Receive_Data<<1;
  95.                   Ir_Receive_Count++;                                
  96.             }else if( (Interval_tim>=19)&&(Interval_tim<=26) )   //间隔2.25ms ->1
  97.             {
  98.                   Ir_Receive_Data=Ir_Receive_Data<<1;
  99.                   Ir_Receive_Data=Ir_Receive_Data|0x0001;
  100.                   Ir_Receive_Count++;                                   
  101.             }else//不是0,1 接收错误,从新接收
  102.             {
  103.                   Ir_Status=0;
  104.                                   TR1 = 0;
  105.                   Ir_Receive_Data=0;
  106.                   Ir_Receive_Count=0;
  107.             }

  108.             //超出接收数据位数,接收下一个
  109.                   if(Ir_Receive_Count==32)
  110.             {         
  111.                 Ir_receive_ok=1;//红外接收完成
  112.                                 Ir_Press = 1;         //按下
  113.                 Ir_Status=3;
  114.                                 TR1 = 1;
  115.                 Ir_Receive_Count=0;
  116.             }
  117.             break;
  118.         case        3:
  119.                         //读取定时器计数值  
  120.                         Interval_tim = Interval;
  121.                         Interval = 0;  
  122.                         if(Interval_tim < 1000)         //100ms
  123.                         {
  124.                                 Ir_Press = 1;         //按下       
  125.                         }else
  126.                         {
  127.                                  Ir_Press = 0;
  128.                                 Ir_Status=0;        
  129.                                 TR1 = 0;
  130.                         }
  131.                         break;         
  132.     default :
  133.                         Ir_Status = 0;
  134.                         TR1 = 0;
  135.             break;
  136.     }
  137. }

  138. //100us 一次
  139. void IR_Timer_Handler(void)
  140. {
  141.         if(Interval < 1000)        Interval++;
  142.         else
  143.         {
  144.                 Ir_Status = 0;
  145.                 Ir_Press = 0;               
  146.         }
  147. }

复制代码
  1. /*=============================================================================
  2. * filename:        main.c
  3. * author:                Wood Wang
  4. * date:                2020.03
  5. * describe:       
  6. *===========================================================================*/
  7. /* Includes -----------------------------------------------------------------*/
  8. #include "main.h"
  9. #include "oled.h"


  10. sbit led1 = P5^2;
  11. sbit led2 = P5^3;
  12. sbit beep = P1^0;

  13. U16                RH_Read_Time;
  14. U8                P_Check;
  15. //=================================================================
  16. //
  17. //=================================================================
  18. volatile unsigned int TimeTick;
  19. volatile unsigned int Time_1ms;
  20. void  Delay_ms(unsigned int ms)
  21. {
  22.         Time_1ms = ms;
  23.         while(Time_1ms);
  24. }

  25. void  Delay_us(unsigned int us)
  26. {
  27.         unsigned char i;
  28.         while(us--)                for(i=30;i>0;i--) ;
  29. }
  30. //=============================================================
  31. void Timer01_Init(void)
  32. {
  33.         TimeTick = 0;

  34.         //Timer0=1ms
  35.         TMOD = 0X11;        //16位定时器
  36.         TCON = 0X00;
  37.         TMCON = 0X00;        //12分频
  38.         TL0 = (65536-(32000/(12*1)));                  //定时1ms
  39.         TH0 = (65536-(32000/(12*1)))>>8;           //
  40.         TR0 = 1;
  41.         ET0 = 1;        //中断

  42.         //Timer1=100us
  43.         TL1 = (65536-(3200/(12*1)));                  //定时100us
  44.         TH1 = (65536-(3200/(12*1)))>>8;           //
  45.         TR1 = 1;
  46.         ET1 = 1;        //中断
  47. }

  48. void GPIO_Init(void)
  49. {
  50.         P0CON = 0x00;  //设置P0为输入带上拉模式
  51.         P0PH  = 0xFF;
  52.         P1CON = 0x01;  //设置P1为高阻输入模式
  53.         P1PH  = 0x00;
  54.         P2CON = 0xFC;  //设置P20,P21为输入带上拉模式,其他推挽输出
  55.         P2PH  = 0x03;
  56.         P3CON = 0xFF;  //设置P3为强推挽模式
  57.         P3PH  = 0x00;
  58.         P4CON = 0xFF;  //设置P4为强推挽模式
  59.         P4PH  = 0x00;
  60.         P5CON = 0xFF;  //设置P5为强推挽模式
  61.         P5PH  = 0x00;

  62.         //P16,P17=外部中断
  63.         P1CON &= 0X3F;     //中断IO口设置为高阻输入
  64.         P1PH  |= 0xC0;     //中断IO口设置为高阻带上拉



  65.         //配置P16下降沿中断、P17边沿中断
  66.     //下降沿设置       
  67.         INT0F = 0X00 ;    //xxxx 0000  0关闭 1使能
  68.         INT1F = 0XC0 ;    //xxxx xxxx  0关闭 1使能
  69.     INT2F = 0X00 ;    //0000 xxxx  0关闭 1使能
  70.     //上升沿设置       
  71.         INT0R = 0X00 ;    //xxxx 0000  0关闭 1使能
  72.         INT1R = 0X80 ;    //xxxx xxxx  0关闭 1使能
  73.         INT2R = 0X00 ;    //0000 xxxx  0关闭 1使能

  74.         //外部中断设置
  75.         IE  &= ~0x01;        //0000 0x0x         INT0使能
  76.         IE  |= 0x04;        //0000 0x0x         INT1使能
  77.         IE1 &= ~0x08;        //0000 x000  INT2使能

  78.         beep = 1;
  79.         led1 = 1;
  80.         led2 = 1;
  81. }

  82. //==============================================
  83. int main(void)
  84. {
  85.         U8         str[16];
  86.         U8         IR_num;
  87.         U8        rh,tem;
  88.         float        t;


  89.         RH_Read_Time = 0;
  90.         P_Check = 0;


  91.         GPIO_Init();
  92.         Timer01_Init();
  93.         BTM_Init();
  94.     EA = 1;


  95.         Uart_Init(0,115200);        //调试
  96.         Uart0SendStr("SinOne SC95F8617 Test. By WoodData.\n");
  97.         OLED_Init();
  98.         LCD12864RAM_ShowString(0,0,"SinOne SC95F8617.By WoodData.");
  99.         LCD12864RAM_DrawRect(0,0,OLED_MAX_X,OLED_MAX_Y,1);
  100.         LCD12864RAM_Refresh();
  101.         Delay_ms(1000);
  102.         LCD12864RAM_Clear();

  103.         if(IR_Init() == 0)        Uart0SendStr("VS1838B IR Init OK.\n");       
  104.         if(DS18B20_Init() == 0)        Uart0SendStr("DS18B20 Init OK.\n");
  105.         if(DHT11_Init() == 0) Uart0SendStr("DHT11 Init OK.\n");


  106.         while(1)       
  107.         {
  108.                 if(IR_Process(&IR_num) == 1)
  109.                 {
  110.                         sprintf(str,"IR Key:%3bu\n",IR_num);
  111.                         LCD12864RAM_ShowString(0,0,str);
  112.                         LCD12864RAM_Refresh();
  113.                         Uart0SendStr(str);                                       
  114.                 }

  115.                 if(RH_Read_Time == 0)
  116.                 {
  117.                         if(RH_Read(&rh,&tem) == 0)
  118.                         {
  119.                                 sprintf(str,"H:%3bu,T:%3bu\n",rh,tem);
  120.                                 LCD12864RAM_ShowString(0,16,str);
  121.                                 LCD12864RAM_Refresh();
  122.                                 Uart0SendStr(str);
  123.                         }
  124.                         t = DS18B20_TempValue(DS18B20_Temp_Raw());
  125.                         sprintf(str,"T:%0.2f",t);
  126.                         LCD12864RAM_ShowString(0,32,str);
  127.                         LCD12864RAM_Refresh();
  128.                         Uart0SendStr(str);
  129.                         RH_Read_Time = 1000;
  130.                 }

  131.                 if(P_Check == 1)
  132.                 {
  133.                         LCD12864RAM_ShowString(0,48,"People In ");
  134.                         LCD12864RAM_Refresh();        
  135.                         P_Check = 0;
  136.                 }else if(P_Check == 2)
  137.                 {
  138.                          LCD12864RAM_ShowString(0,48,"People Out");
  139.                         LCD12864RAM_Refresh();
  140.                         P_Check = 0;
  141.                 }

  142.         }

  143. }


  144. //===============================================
  145. //中断
  146. void Timer0_ISR()        interrupt        1
  147. {
  148.         TL0 = (65536-(32000/(12*1)));                  //定时1ms
  149.         TH0 = (65536-(32000/(12*1)))>>8;           //

  150.         if(Time_1ms)                Time_1ms--;
  151.         if(RH_Read_Time)        RH_Read_Time--;
  152.         TimeTick++;       

  153. }

  154. void Timer1_ISR()        interrupt        3
  155. {
  156.         TL1 = (65536-(3200/(12*1)));                  //定时100us
  157.         TH1 = (65536-(3200/(12*1)))>>8;           //
  158.                
  159.         IR_Timer_Handler();
  160. }


  161. void EX0() interrupt        0
  162. {
  163.         TCON &= 0XFD;
  164. }

  165. void EX1() interrupt        2
  166. {
  167.         TCON &= 0XF7;
  168.         //VS1838B红外解码
  169.         if(P16 == 0)        //下降沿
  170.         {
  171.                 led1 = ~led1;
  172.                 IR_Receive_Handler();
  173.         }

  174.         //人体红外感应
  175.         if(P17 == 0)        //下降沿
  176.         {
  177.                 //beep = 1;
  178.                 led2 = 1;
  179.                 P_Check = 2;

  180.         }else
  181.         {
  182.                 //beep = 0;
  183.                 led2 = 0;
  184.                 P_Check = 1;
  185.         }
  186. }

  187. void EX2() interrupt        10
  188. {
  189. }

复制代码
QQ图片20200331194745.jpg
QQ图片20200331194751.jpg
QQ图片20200331194756.gif
QQ图片20200331194800.gif



使用特权

评论回复
| 2020-4-1 10:49 | 显示全部楼层
感谢分享,奖励100家园币,家园币可以兑换礼品或抽奖,欢迎体验~

使用特权

评论回复
| 2020-4-16 13:00 | 显示全部楼层
非常的好,太好了

使用特权

评论回复
| 2020-5-13 16:29 | 显示全部楼层
非常感谢楼主分享

使用特权

评论回复
| 2020-5-13 16:29 | 显示全部楼层
别的型号可以直接移植吗

使用特权

评论回复
| 2020-5-13 16:30 | 显示全部楼层
好羡慕楼主 真不错啊

使用特权

评论回复
| 2020-5-13 16:30 | 显示全部楼层
楼主辛苦了 能打包一个工程来吗

使用特权

评论回复
扫描二维码,随时随地手机跟帖
您需要登录后才可以回帖 登录 | 注册

本版积分规则

我要发帖 投诉建议 创建版块 申请版主

快速回复

您需要登录后才可以回帖
登录 | 注册
高级模式

论坛热帖

在线客服 快速回复 返回顶部 返回列表