本帖最后由 jinglixixi_457498010 于 2021-10-7 09:26 编辑

      K32W061开发板是一款面向智能照明、智能门锁、温控器、智能家居领域及无线传感网的开发板,它以超低功耗高性能的 Arm®Cortex®-M4 无线微控制器为内核,含有640KB片上 Flash、152KB SRAM  、128KB ROM,且含有 2.4GHz BLE5 和 IEEE 802.15.4 收发器。该开发板体型小巧,为便于扩展使用它配有Arduino 接口的转接板。
       最初的设想是在该开发板的基础上设计一个可以无线通讯来传递数据的家居环境状态检测器,因初期在开发环境的构建上消耗了大量的时间,使得后续的开发时间相对紧张,为此只能调整设计的目标来实现一个基于模拟信号采集的状态检测器,其具体的功能为:
       以OLED屏为显示器件,由于其采样I2C接口来工作,故十分节省I/O引脚。另外,为了配合A/D的数据采集,选取RTC来辅助进行采样时间点的标记。在需要时,利用RTC还可独立的以电子时钟来使用。
       在以A/D来采集数据时,可配以相应的传感器来获取环境的状态信息。此外,可以串行通讯的方式将采集的数据存储到相应的文本文件中。
       当初是将数字式传感器也纳入其中的,如以DHT22来检测温湿度、以BH1750检测光照强度、以BMP085来检测大气压等,无奈时间紧只好看时间紧可能的补上。
该检测器的整体构成如图1所示,其处理流程如图2所示。

u.jpg
图1整体构成

d.jpg
图2处理流程

界面形式:
3.jpg
记录格式:
4.jpg
程序设计:
详细内容参见以下介绍:
1. 开箱及开发环境构建
https://mbb.eet-china.com/forum/topic/94054_1_1.html
2.I/O口使用及OLED屏显示驱动
https://mbb.eet-china.com/forum/topic/94165_1_1.html
3.片内功能的使用
https://mbb.eet-china.com/forum/topic/94248_1_1.html
测试效果:
5.jpg
图3 主界面
6.jpg
图4 电子时钟
7.jpg
图5电位器模拟测试
8.jpg
图6火焰传感器检测
9.jpg
图7土壤湿度传感器
10.jpg
图6实际检测

经改进采用0.96'的双色屏替代了原0.91'的单色屏,新的显示效果如图7至图10所示。
a.jpg
图7 新界面
b.jpg
图8 RTC电子时钟与A/D采集
c.jpg
图9 光强检测
y.jpg
图10气压检测

0.96'显示屏的初始化函数为:
  1. void OLED_Init(void)
  2. {
  3.        Write_IIC_Command(0xae);
  4.         Write_IIC_Command(0x02);
  5.         Write_IIC_Command(0x10);
  6.         Write_IIC_Command(0x40);
  7.         Write_IIC_Command(0x81);
  8.         Write_IIC_Command(0xff);  
  9.         Write_IIC_Command(0xa1);
  10.         Write_IIC_Command(0xc8);
  11.         Write_IIC_Command(0xa6);
  12.         Write_IIC_Command(0xa8);
  13.         Write_IIC_Command(0x3f);
  14.         Write_IIC_Command(0xd3);
  15.         Write_IIC_Command(0x00);
  16.         Write_IIC_Command(0xd5);
  17.         Write_IIC_Command(0x80);
  18.         Write_IIC_Command(0xd9);
  19.         Write_IIC_Command(0xf1);
  20.         Write_IIC_Command(0xda);
  21.         Write_IIC_Command(0x12);
  22.         Write_IIC_Command(0xdb);
  23.         Write_IIC_Command(0x40);
  24.         Write_IIC_Command(0x20);
  25.         Write_IIC_Command(0x02);
  26.         Write_IIC_Command(0x8d);
  27.         Write_IIC_Command(0x14);
  28.         Write_IIC_Command(0xa4);
  29.         Write_IIC_Command(0xa6);
  30.         Write_IIC_Command(0xaf);
  31.         Write_IIC_Command(0xaf);
  32.         OLED_Clear();
  33. }
读取光强的函数为:
  1. void Get_Sunlight_Value()
  2. {
  3.     int dis_data=0;
  4.     float temp;
  5.     char i=0;
  6.     unsigned int sd;
  7.     Single_Write_BH1750(0x01);
  8.     Single_Write_BH1750(0x10);
  9.     SysTick_DelayTicks(180U);
  10.     Multiple_Read_BH1750();
  11.     for(i=0;i<3;i++)   dis_data=BUF[0];
  12.     dis_data=(dis_data <<8)+BUF[1];
  13.     temp=(float)dis_data/1.2;
  14.     sd=temp;
  15.     OLED_ShowString(0,2,"Sunlight=     lx",16);
  16.     OLED_ShowNum(72,2,sd,5,16);
  17. }
读取温度的函数为:
  1. long bmp085ReadTemp(void)
  2. {
  3.       BMP085_Start();
  4.       BMP085_Send_Byte(BMP085_SlaveAddress);
  5.       while(BMP085_Wait_Ack()){}
  6.       BMP085_Send_Byte(0xF4);
  7.       while(BMP085_Wait_Ack()){}
  8.       BMP085_Send_Byte(0x2E);
  9.       while(BMP085_Wait_Ack()){}
  10.       BMP085_Stop();
  11.       SysTick_DelayTicks(10U);
  12.       return (long) Multiple_read(0xF6);
  13. }

读取气压的函数为:
  1. long bmp085ReadPressure(void)
  2. {
  3.     long pressure = 0;
  4.     BMP085_Start();
  5.     BMP085_Send_Byte(BMP085_SlaveAddress);
  6.     while(BMP085_Wait_Ack()){}
  7.     BMP085_Send_Byte(0xF4);
  8.     while(BMP085_Wait_Ack()){}
  9.     BMP085_Send_Byte(0x34);
  10.     while(BMP085_Wait_Ack()){}
  11.     BMP085_Stop();
  12.     SysTick_DelayTicks(10U);
  13.     pressure = Multiple_read(0xF6);
  14.     pressure &= 0x0000FFFF;
  15.     return pressure;
  16. }
相应的关键处理程序如下:
  1. while (1)
  2. {
  3.         if(GPIO_PinRead(GPIO, 0, 5)==0)
  4.         {
  5.               OLED_Clear();
  6.              m=(m+1)%2;
  7.              if(m==0)
  8.              {
  9.                          OLED_ShowNum(10,0,date.year,2,16);
  10.                          OLED_ShowNum(34,0,date.month,2,16);
  11.                          OLED_ShowNum(58,0,date.day,2,16);
  12.                          OLED_ShowChar(26,0,'-',16);
  13.                          OLED_ShowChar(50,0,'-',16);
  14.              }
  15.              while(GPIO_PinRead(GPIO, 0, 5)==0);
  16.         }
  17.         RTC_GetDatetime(RTC, &date);
  18.         if(t!=date.second)
  19.         {
  20.                     if(d!=date.day)
  21.                     {
  22.                         OLED_ShowNum(10,0,date.year,2,16);
  23.                         OLED_ShowNum(34,0,date.month,2,16);
  24.                         OLED_ShowNum(58,0,date.day,2,16);
  25.                     }
  26.                     if(m==0)
  27.                     {
  28.                        OLED_ShowChar(26,0,'-',16);
  29.                       OLED_ShowChar(50,0,'-',16);
  30.                       OLED_ShowChar(26,2,':',16);
  31.                       OLED_ShowChar(50,2,':',16);
  32.                       OLED_ShowNum(10,2,date.hour,2,16);
  33.                       OLED_ShowNum(34,2,date.minute,2,16);
  34.                       OLED_ShowNum(58,2,date.second,2,16);
  35.                       PRINTF("%d:%d:%d- ", date.hour,date.minute,date.second);
  36.                       ADC_DoSoftwareTriggerConvSeqA(DEMO_ADC_BASE);
  37.                       while (!ADC_GetChannelConversionResult(DEMO_ADC_BASE, DEMO_ADC_SAMPLE_CHANNEL_NUMBER, &adcResultInfoStruct))
  38.                       {
  39.                       }
  40.                      PRINTF("ADC: %d\r\n", adcResultInfoStruct.result);
  41.                      OLED_ShowString(10,4,"CH1=    ",16);//ch1
  42.                      OLED_ShowNum(60,4,adcResultInfoStruct.result,4,16);
  43.                      OLED_ShowString(10,6,"CH2=    ",16);//ch2
  44.             }
  45.             if(m==1)
  46.             {
  47.                 OLED_ShowString(10,0,"BMP085:     ",16);
  48.                 OLED_ShowString(10,2,"BH1750:     ",16);
  49.                 OLED_ShowString(10,4,"temp:       ",16);
  50.                 OLED_ShowString(10,6,"humi:       ",16);
  51.                 Get_Sunlight_Value();
  52.                 bmp085Convert();
  53.                 OLED_ShowNum(66,0,pressure/100,5,16);
  54.                 DHT11_Read_Data(&temperature1,&humidity1);
  55.                 OLED_ShowNum(66,4,temperature1,2,16);
  56.                 OLED_ShowNum(66,6,humidity1,2,16);
  57.            }
  58.           t=date.second;
  59.        }
  60. }
此外,在上位机接收串口发送数据的情况下还可以如下的界面来显示检测数据。
1.jpg
图11 界面设计
2.jpg
图12 初始状态
3.jpg
图13 接受数据后

视频:
环境状态检测器的实现.mp4
https://u.eet-china.com/video/me/time_467667/1
改进方向:
后续的改进方向是增添新的数字式传感器检测及无线传输数据功能。