前面的帖子,我分享了TobudOS与多菜单以及OLED的展示,这里向大家展示如何使用多级菜单来实现sht30的温湿度计的显示。
菜单路径设计:
tools->HUMI->显示温湿度值
1、移植sht30的驱动。我这里选用I2C1来显示,查找数据手册I2C1可以选用PC0(SCL)、PC1(SDA)复用配置为AF4。初始化代码如下:
  1. void sht3x_i2c_init(void)
  2. {
  3.           GPIO_InitTypeDef GPIO_InitStruct;
  4.     I2C_InitTypeDef  I2C_InitStruct;

  5.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);

  6.     I2C_DeInit(I2C1);

  7.     I2C_StructInit(&I2C_InitStruct);
  8.     I2C_InitStruct.I2C_Mode       = I2C_MODE_MASTER;
  9.     I2C_InitStruct.I2C_OwnAddress = I2C_OWN_ADDRESS;
  10.     I2C_InitStruct.I2C_ClockSpeed = 100000;
  11.     I2C_Init(I2C1, &I2C_InitStruct);

  12.     I2C_TargetAddressConfig(I2C1, 0x88);

  13.     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);

  14.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource0, GPIO_AF_4);
  15.     GPIO_PinAFConfig(GPIOC, GPIO_PinSource1, GPIO_AF_4);

  16.     GPIO_StructInit(&GPIO_InitStruct);
  17.     GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_0 | GPIO_Pin_1;
  18.     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
  19.     GPIO_InitStruct.GPIO_Mode  = GPIO_Mode_AF_OD;
  20.     GPIO_Init(GPIOC, &GPIO_InitStruct);

  21.     I2C_Cmd(I2C1, ENABLE);
  22.        
  23. }
然后移植读写驱动,写命令驱动为:
  1. /**
  2. * @brief    向SHT30发送一条指令(16bit)
  3. * @param    cmd —— SHT30指令(在SHT30_MODE中枚举定义)
  4. * @retval    成功返回HAL_OK
  5. */
  6. static uint8_t    SHT30_Send_Cmd(SHT30_CMD cmd)
  7. {
  8.         uint8_t i;
  9.     uint8_t cmd_buffer[2];
  10.     cmd_buffer[0] = cmd >> 8;
  11.     cmd_buffer[1] = cmd;
  12.         for(i=0;i<2;i++)
  13.         {
  14.                 I2C_SendData(I2C1, cmd_buffer[i]);

  15.                 while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE))
  16.                 {
  17.                 }
  18.         }
  19.         I2C_GenerateSTOP(I2C1, ENABLE);

  20.         while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE))
  21.         {
  22.         }
  23.         return 0;
  24. }
读取温湿度CRC的代码如下,就是发送数据后读取6个字节:
  1. /**
  2. * @brief    从SHT30读取一次数据
  3. * @param    dat —— 存储读取数据的地址(6个字节数组)
  4. * @retval    成功 —— 返回HAL_OK
  5. */
  6. uint8_t SHT30_Read_Dat(uint8_t* dat)
  7. {
  8.                 uint8_t i;
  9.     SHT30_Send_Cmd(READOUT_FOR_PERIODIC_MODE);
  10.     for (i = 0; i < 6; i++)
  11.     {
  12.         I2C_ReadCmd(I2C1);
  13.                                
  14.         while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_RFNE))
  15.         {
  16.         }
  17.                                 dat[i] = I2C_ReceiveData(I2C1);
  18.         
  19.     }
  20.                 I2C_GenerateSTOP(I2C1, ENABLE);

  21.                 while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE))
  22.                 {
  23.                 }
  24.                 return 0;
  25. }
到此读取sht30的代码就结束了,下面配置菜单。配置tools下面的第一项为显示HUMI的,对应的函数为temp_sht30
  1. void tools_option(void)
  2. {
  3.         struct option_class option[] = {
  4.                 {"<<<"},
  5.                 {"HUMI", temp_sht30},        //温湿度计
  6.                 {"IC", },                //6-6 输入捕获模式测频率
  7.                 {"PWM_Out", },                        //6-3 PWM驱动LED呼吸灯
  8.                 {"PWM_In", },                        //6-7 PWMI模式测频率占空比
  9.                 {"Encoder", },        //6-8 编码器接口测速
  10.                 {"ADC", },                                //8-2 DMA+AD多通道
  11.                 {"Serial_SR_HEX", },        //9-3 串口收发HEX数据包
  12.                 {"Serial_SR_UTF-8", },        //9-4 串口收发文本数据包
  13.                 {"SPI_RW_W25Q64", },        //11-2 硬件SPI读写W25Q64
  14.                 {"Oscillograph", },                //示波器
  15.                 {".."}
  16.         };
  17.        
  18.         run_play_option_class(option);
  19. }
在sht30x.c中实现其代码如下:
  1. void temp_sht30(void)
  2. {
  3.         uint8_t sht30_dat[6];
  4.         char show_str[32];
  5.         float temperature=15.0, humidity=80.1;
  6.         sht3x_i2c_init();
  7.         SHT30_Init();
  8.         tos_task_delay(1000);
  9.         while(1)
  10.         {
  11.                 OLED_Clear();
  12.                 if(Key_Enter_Get()) {return;} //如果检测到按键,则返回菜单
  13.                         SHT30_Init();
  14.                 tos_task_delay(1000);
  15.                 SHT30_Read_Dat(sht30_dat);
  16.                 SHT30_Dat_To_Float(sht30_dat, &temperature, &humidity);
  17.                 sprintf(show_str,"T:%2.1f  H:%.2f",temperature,humidity);
  18.                 OLED_ShowString(0, 0, show_str, OLED_8X16);

  19.                 OLED_Update();
  20.                 tos_task_delay(1000);
  21.         }
  22. }
这样下载运行后就可以使用菜单项来选择显示温湿度计了。