新闻中心

EEPW首页 > 光电显示 > 业界动态 > 基于TOPWAY液晶屏的水质检测仪设计

基于TOPWAY液晶屏的水质检测仪设计

作者:shihengrui 时间:2022-04-13 来源:电子产品世界 收藏

四、软件设计

本文引用地址:https://www.eepw.com.cn/article/202204/433019.htm

1、驱动编写

根据协议内容,编写写16位数字变量的驱动


/**

brief 发送16位变量

param adr:变量地址

param dt:发送的变量

return 无

*/

voidlcd_send_pv16(uint32_tadr,uint16_tdt)

{

    uint8_tsend_buf[32];

    uint8_tidx = 0;


    send_buf[idx++] = 0xaa;

    send_buf[idx++] = 0x3d;

    adr = ntohl(adr);//大小端转换

    memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&adrsizeof(uint32_t));

    idx += sizeof(uint32_t);


    dt = ntohs(dt);//大小端转换

    memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&dt2);

    idx += 2;

    send_buf[idx++] = 0xcc;

    send_buf[idx++] = 0x33;

    send_buf[idx++] = 0xc3;

    send_buf[idx++] = 0x3c;

    send_data1(send_bufidx);

}


左推进写曲线数据


/**

brief LCD左推进写曲线数据

param adr:变量地址

param adr_curve:插入位置

param dt:发送的变量

return 无

*/

voidlcd_send_curve(uint32_tadr,uint16_tadr_curve,uint16_tdt)

{

    uint8_tsend_buf[64];

    uint8_tidx = 0;


    send_buf[idx++] = 0xaa;

    send_buf[idx++] = 0x4e;

    adr = ntohl(adr);

    memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&adrsizeof(uint32_t));

    idx += sizeof(uint32_t);


    adr_curve = ntohs(adr_curve);

    memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&adr_curvesizeof(uint16_t));

    idx += sizeof(uint16_t);


    dt = ntohs(dt);

    memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&dtsizeof(uint16_t));

    idx += sizeof(uint16_t);


    send_buf[idx++] = 0xcc;

    send_buf[idx++] = 0x33;

    send_buf[idx++] = 0xc3;

    send_buf[idx++] = 0x3c;

    send_data1(send_bufidx);

}


跳转页面的驱动


/**

brief LCD跳转页面

param page:页面地址

return 无

*/

voidlcd_send_page(uint16_tpage)

{

    uint8_tsend_buf[64];

    uint8_tidx = 0;


    send_buf[idx++] = 0xaa;

    send_buf[idx++] = 0x70;

    page = ntohs(page);

    memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&pagesizeof(uint16_t));

    idx += sizeof(uint16_t);

    send_buf[idx++] = 0xcc;

    send_buf[idx++] = 0x33;

    send_buf[idx++] = 0xc3;

    send_buf[idx++] = 0x3c;

    send_data1(send_bufidx);

}


设置时间的驱动


/**

brief LCD设置时间

param page 无

return 无

*/

voidlcd_send_time(void)

{

    uint8_tsend_buf[64];

    uint8_tidx = 0;


    send_buf[idx++] = 0xaa;

    send_buf[idx++] = 0x9c;


    memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&my_rtcsizeof(MYRTC));

    idx += sizeof(MYRTC);


    send_buf[idx++] = 0xcc;

    send_buf[idx++] = 0x33;

    send_buf[idx++] = 0xc3;

    send_buf[idx++] = 0x3c;

    send_data1(send_bufidx);

}


读取时间的驱动


/**

brief LCD读取时间

param page 无

return 无

*/

voidlcd_read_time(void)

{

    uint8_tsend_buf[64];

    uint8_tidx = 0;


    send_buf[idx++] = 0xaa;

    send_buf[idx++] = 0x9b;

    send_buf[idx++] = 0xcc;

    send_buf[idx++] = 0x33;

    send_buf[idx++] = 0xc3;

    send_buf[idx++] = 0x3c;

    send_data1(send_bufidx);

}


接收LCD数据的程序

voidlcd_pro(void)

{

    staticuint32_ttimer_lcd = 0;

    if (timer6 - timer_lcd<9)

        return;

    timer_lcd = timer6;

    if (lcd_rx.len<5)

        return;

    if (lcd_rx.rx_buff[0] != 0xaa)

    {

        memset((uint8_t*)&lcd_rx.rx_buff0lcd_rx.len);

        lcd_rx.len = 0;

        return;

    }

    else

    {

        switch (lcd_rx.rx_buff[1])

        {

        case0x79://触摸

            lcd.page = lcd_rx.rx_buff[3];

            lcd.touch_id = lcd_rx.rx_buff[4];

            break;

        case0x77://下发数据

            if(lcd_rx.rx_buff[3] == 0x08)

            {

                if(lcd_rx.rx_buff[5] == 0x0A)//年

                {

                    my_rtc.year = lcd_rx.rx_buff[7];

                }

                elseif(lcd_rx.rx_buff[5] == 0x0C)//月

                {

                    my_rtc.month = lcd_rx.rx_buff[7];

                }

                elseif(lcd_rx.rx_buff[5] == 0x0E)//日

                {

                    my_rtc.day = lcd_rx.rx_buff[7];

                }

                elseif(lcd_rx.rx_buff[5] == 0x10)//时

                {

                    my_rtc.hour = lcd_rx.rx_buff[7];

                }

                elseif(lcd_rx.rx_buff[5] == 0x12)//分

                {

                    my_rtc.min = lcd_rx.rx_buff[7];

                }

                elseif(lcd_rx.rx_buff[5] == 0x14)//秒

                {

                    my_rtc.sec = lcd_rx.rx_buff[7];

                }

                lcd_send_time();

            }

            break;

        case0x9B://读取时间

            memcpy((uint8_t*)&my_rtc, (uint8_t*)&lcd_rx.rx_buff[2], sizeof(MYRTC));

            break;

        default:

            break;

        }

        memset((uint8_t*)&lcd_rx.rx_buff0lcd_rx.len);

        lcd_rx.len = 0;

    }

}


2、PH值采集

这里用的传感器是模拟信号,可以直接使用单片机的AD去采集值,转化为电压之后,根据拟合后的公式直接转换为PH值,程序如下


voidph_pro(void)

{

  staticuint32_ttimer_ph = 0;

  uint16_tadc_value = 0;

  floatvol = 0.0;

  if (timer6 - timer_ph>PH_COLLECT_TIME)

  {

    HAL_ADC_Start(&hadc1);                  //启动ADC单次转换

    HAL_ADC_PollForConversion(&hadc150);  //等待ADC转换完成

    if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1), HAL_ADC_STATE_REG_EOC))

    {

      adc_value = HAL_ADC_GetValue(&hadc1);   //读取ADC转换数据

      vol = ((double)adc_value/4096)*3.3*2;//转化为实际电压值

      printf("sensor log:adc_value = %d, vol = %.2fV.n"adc_valuevol);

      ph_buf[FILTER_N] = (uint16_t)((5.9647*vol+22.255)*10);//转换为PH值

      for (i = 0; i <FILTER_N; i++)

      {

          ph_buf[i] = ph_buf[i + 1];   // 所有数据左移,低位仍掉

      }

      pv.ph = MedianFilter(ph_bufFILTER_N); //中值平均滤波

      printf("sensor log:ph %drn"pv.ph);

    }

    lcd_send_pv16(0x080000,pv.ph);//给LCD发送数据

    lcd_send_curve(0x060000,224,pv.ph);//给LCD左推进发送曲线

    timer_ph += PH_COLLECT_TIME;

  }

}


3、池水温度值采集

使用的是经典的DS18B20,单总线获取温度,程序如下

voidds18b20_pro(void)

{

  uint16_ti = 0;

  staticuint32_ttimer_ds18b20 = 0;

  if (timer6 - timer_ds18b20>DS_COLLECT_TIME)

  {

    te_buf[FILTER_N] = DS18B20_Get_Temp();

    for (i = 0i<FILTER_Ni++)

    {

        te_buf[i] = te_buf[i + 1];   // 所有数据左移,低位仍掉

    }

    pv.te = MedianFilter(te_bufFILTER_N); //中值平均滤波

    lcd_send_pv16(0x080002pv.te);//给LCD发送数据

    lcd_send_curve(0x0600e0,224,pv.te+100);//给LCD左推进发送曲线

    printf("sensor log:te %drn"pv.te);

    timer_ds18b20 += DS_COLLECT_TIME;

  }

}

4、环境温湿度值采集

使用的是国产的AHT10,IIC协议获取温湿度,程序如下

voidaht_pro(void)

{

  uint16_ti = 0;

  staticuint32_ttimer_aht = 0;

  if (timer6 - timer_aht>AHT_COLLECT_TIME)

  {

    AHT10ReadData(&tem_buf[FILTER_N], &hum_buf[FILTER_N]);

    for (i = 0i<FILTER_Ni++)

    {

        hum_buf[i] = hum_buf[i + 1];   // 所有数据左移,低位仍掉

        tem_buf[i] = tem_buf[i + 1];   // 所有数据左移,低位仍掉

    }

    pv.tem = MedianFilter(tem_bufFILTER_N); //中值平均滤波

    pv.hum = MedianFilter(hum_bufFILTER_N); //中值平均滤波


    printf("sensor log:tem %drn"pv.tem);

    printf("sensor log:hum %drn"pv.hum);

   


    lcd_send_curve(0x0602a0,224,pv.tem+100);//给LCD左推进发送曲线

    lcd_send_curve(0x0601c0,224,pv.hum);//给LCD左推进发送曲线

   

    lcd_send_pv16(0x080004,pv.hum);//给LCD发送数据

    lcd_send_pv16(0x080006,pv.tem);//给LCD发送数据


    timer_aht += AHT_COLLECT_TIME;

  }

}


5、LCE操作流程图

五、展示

主界面

水质曲线界面

环境温湿度曲线界面

效果杠杠的,大屏高分辨率,操作简单高效,真是一次完美的开发体验!!!


上一页 1 2 下一页

关键词: TOPWAY LCD 水质仪

评论


相关推荐

技术专区

关闭