[MM32软件] 【EV Board (MM32L0136C7P)测评】+环境状态检测记录器

[复制链接]
985|6
 楼主| jinglixixi 发表于 2022-12-17 22:04 | 显示全部楼层 |阅读模式
本帖最后由 jinglixixi 于 2022-12-21 22:39 编辑

#申请原创#
MM32L0136开发板为核心,实现环境状态检测记录器的整体构成如图1所示,其中传感器BH1750用于光照强度的接触,传感器BMP085用于温度和大气压的检测,OLED屏用于数据显示,串行数据记录模块用于数据记录。
4个外设中,除数据记录模块是串行设备外,其它3个均为I2C接口的外设。
1.jpg
1  整体构成

对于这4个外设,其引脚连接情况如下:
OLED:
SCL---B9
SDA---B10

BH1750
SCL---B11
SDA---B12

记录仪:
RX---PA2_TX
BMP085:
SCL---D5
SDA---A8

1. 传感器BMP085
BMP085在检测过程中,主要依赖的是字节收发函数,其具体的内容如下:
  1. void BMP085_Send_Byte(char txd)
  2. {
  3.     char t;
  4.     OUTPUT_MODE_SET();
  5.     SCL_Clr1();
  6.     for(t=0;t<8;t++)
  7.     {
  8.         if((txd&0x80)>>7)
  9.         {
  10.             SDA_Set1();
  11.         }
  12.         else
  13.         {
  14.             SDA_Clr1();
  15.         }
  16.         txd<<=1;
  17.         del_t(20);
  18.         SCL_Set1();
  19.         del_t(20);
  20.         SCL_Clr1();
  21.         del_t(20);
  22.     }
  23. }

  24. char BMP085_Read_Byte(unsigned char ack)
  25. {
  26.       unsigned char i,receive=0;
  27.       INPUT_MODE_SET();
  28.       for(i=0;i<8;i++)
  29.       {
  30.         SCL_Clr1();
  31.         del_t(20);
  32.         SCL_Set1();
  33.         receive<<=1;
  34.         if(SDA_IN) receive++;
  35.         del_t(20);
  36.     }
  37.     if(!ack)
  38.         BMP085_NAck();
  39.     else
  40.         BMP085_Ack();
  41.     return receive;
  42. }

通过以上2个函数的支持,读取温度和大气压的函数分别为:
  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.     del_t(10000); ;
  12.     return (long) Multiple_read(0xF6);
  13. }

  14. long bmp085ReadPressure(void)
  15. {
  16.     long pressure = 0;
  17.     BMP085_Start();
  18.     BMP085_Send_Byte(BMP085_SlaveAddress);
  19.     while(BMP085_Wait_Ack()){}
  20.     BMP085_Send_Byte(0xF4);
  21.     while(BMP085_Wait_Ack()){}
  22.     BMP085_Send_Byte(0x34);
  23.     while(BMP085_Wait_Ack()){}
  24.     BMP085_Stop();
  25.     del_t(10000); ;
  26.     pressure = Multiple_read(0xF6);
  27.     pressure &= 0x0000FFFF;
  28.     return pressure;
  29. }

最终实现温度与气压值转换的函数为:
  1. void bmp085Convert()
  2. {
  3.       unsigned int ut;
  4.       unsigned long up;
  5.       long x1, x2, b5, b6, x3, b3, p;
  6.       unsigned long b4, b7;
  7.       ut = bmp085ReadTemp();
  8.       up = bmp085ReadPressure();
  9.       x1 = (((long)ut - (long)ac6)*(long)ac5) >> 15;
  10.       x2 = ((long) mc << 11) / (x1 + md);
  11.       b5 = x1 + x2;
  12.       temperature1 = ((b5 + 8) >> 4);
  13.       b6 = b5 - 4000;
  14.       x1 = (b2 * (b6 * b6)>>12)>>11;
  15.       x2 = (ac2 * b6)>>11;
  16.       x3 = x1 + x2;
  17.       b3 = (((((long)ac1)*4 + x3)<<OSS) + 2)>>2;
  18.       x1 = (ac3 * b6)>>13;
  19.       x2 = (b1 * ((b6 * b6)>>12))>>16;
  20.       x3 = ((x1 + x2) + 2)>>2;
  21.       b4 = (ac4 * (unsigned long)(x3 + 32768))>>15;
  22.       b7 = ((unsigned long)(up - b3) * (50000>>OSS));
  23.       if (b7 < 0x80000000)
  24.         p = (b7<<1)/b4;
  25.       else
  26.         p = (b7/b4)<<1;
  27.       x1 = (p>>8) * (p>>8);
  28.       x1 = (x1 * 3038)>>16;
  29.       x2 = (-7357 * p)>>16;
  30.       pressure = p+((x1 + x2 + 3791)>>4);
  31. }


这样在使用温度和大气压检测值时,通过读取变量temperature1pressure就可以了。

2. 数据记录模块
对于数据记录模块它是一种串口设备,在使用时主要符合其波特率9600bps的要求即可,向其发送的数据即被其完整地记录到TF卡的文件中。为进行测试,通过串口可查看到其记录的数据内容,见图2所示。
2.jpg
2  记录数据测试

在接入数据记录模块后,其存入文件的内容如图3所示,说明其完全符合设计的要求。
3.jpg
3  记录文件格式及内容

3. 其它外设

除传感器BMP085和数据记录模块的内容之外,其它外设的使用可参见:

(1)RTC电子时钟
https://bbs.21ic.com/icview-3269248-1-1.html

(2)GPIO口使用及OLED
https://bbs.21ic.com/icview-3269538-1-1.html

(3) 光照强度检测与显示
https://bbs.21ic.com/icview-3269724-1-1.html

4. 主程序

实现环境状态检测记录功能的主程序为:
  1. int main(void)
  2. {
  3.         uint8_t ch,tt,p;
  4.         uint16_t u;
  5.         BOARD_Init();
  6.         Init_oled();
  7.         OLED_Init();
  8.         OLED_Clear();
  9.         OLED_ShowCHinese(8,0,0);
  10.         OLED_ShowCHinese(24,0,1);
  11.         OLED_ShowCHinese(40,0,2);
  12.         OLED_ShowCHinese(56,0,3);
  13.         OLED_ShowCHinese(72,0,4);
  14.         OLED_ShowCHinese(90,0,5);
  15.         OLED_ShowCHinese(106,0,8);
  16.         app_rtc_init();
  17.         OLED_ShowString(0,2,"  :  :     -  ",16);
  18.         app_rtc_get_current_time();
  19.         tt=rtc_time.Months/16*10+rtc_time.Months%16;
  20.         OLED_ShowNum(72,2,tt,2,16);
  21.         tt=rtc_time.Days/16*10+rtc_time.Days%16;
  22.         OLED_ShowNum(96,2,tt,2,16);
  23.         OLED_ShowString(0,4,"Light=     Lx",16);
  24.         OLED_ShowString(0,6,"P=    KP T=  C",16);
  25.         BH1750_Init();
  26.         BMP085_Init();
  27.         Init_BMP085();
  28.         del_t(200);
  29.         p=rtc_time.Secs;
  30.         while (1)
  31.        {
  32.                         app_rtc_get_current_time();
  33.                         if(p<rtc_time.Secs)
  34.                         {
  35.                               p=rtc_time.Secs;
  36.                               printf("%02x:", (unsigned int)(long)rtc_time.Hours);
  37.                               printf("%02x",  (unsigned int)(long)rtc_time.Mins);
  38.                               printf(":%02x ", (unsigned int)(long)rtc_time.Secs);
  39.                               tt=rtc_time.Hours/16*10+rtc_time.Hours%16;        
  40.                               OLED_ShowNum(0,2,tt,2,16);
  41.                               tt=rtc_time.Mins/16*10+rtc_time.Mins%16;
  42.                               OLED_ShowNum(24,2,tt,2,16);
  43.                               tt=rtc_time.Secs/16*10+rtc_time.Secs%16;
  44.                               OLED_ShowNum(48,2,tt,2,16);
  45.                               Get_Sunlight_Value();
  46.                               bmp085Convert();
  47.                               u=temperature1/10;
  48.                               OLED_ShowNum(88,6,u,2,16);
  49.                               printf("temp=%d ",u);
  50.                               u=pressure/100;
  51.                              OLED_ShowNum(16,6,u,4,16);
  52.                              printf("press=%d \r\n",u);
  53.                              del_t(10000);        
  54.                      }
  55.         }
  56. }

从便于设计的角度出发,显示功能和数据记录功能的一部分已被放置到相应的检测程序中,这样就实现了环境状态检测记录器的整体设计目标。

视频演示:
maqianqu 发表于 2023-1-5 13:02 | 显示全部楼层
可以实现联网的吗?              
ccook11 发表于 2023-1-5 13:11 | 显示全部楼层
可以做成物联网的设备了。              
Jacquetry 发表于 2023-1-5 17:06 | 显示全部楼层
联网以后就是物联网设备了
 楼主| jinglixixi 发表于 2023-1-6 11:55 | 显示全部楼层
maqianqu 发表于 2023-1-5 13:02
可以实现联网的吗?

加个串口转以太网模块即可
saservice 发表于 2023-1-6 20:32 | 显示全部楼层
MM32L0136C7P的功耗是多少?
 楼主| jinglixixi 发表于 2023-1-7 00:38 | 显示全部楼层
saservice 发表于 2023-1-6 20:32
MM32L0136C7P的功耗是多少?

这个需要去查相应的手册了
您需要登录后才可以回帖 登录 | 注册

本版积分规则

521

主题

2949

帖子

39

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