新闻中心

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

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

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

四、软件设计

本文引用地址://m.amcfsurvey.com/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*)&adr,sizeof(uint32_t));

idx+=sizeof(uint32_t);


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

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

idx+=2;

send_buf[idx++] =0xcc;

send_buf[idx++] =0x33;

send_buf[idx++] =0xc3;

send_buf[idx++] =0x3c;

send_data1(send_buf,idx);

}


左推进写曲线数据


/**

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*)&adr,sizeof(uint32_t));

idx+=sizeof(uint32_t);


adr_curve=ntohs(adr_curve);

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

idx+=sizeof(uint16_t);


dt=ntohs(dt);

memcpy((uint8_t*)&send_buf[idx], (uint8_t*)&dt,sizeof(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_buf,idx);

}


跳转页面的驱动


/**

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*)&page,sizeof(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_buf,idx);

}


设置时间的驱动


/**

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_rtc,sizeof(MYRTC));

idx+=sizeof(MYRTC);


send_buf[idx++] =0xcc;

send_buf[idx++] =0x33;

send_buf[idx++] =0xc3;

send_buf[idx++] =0x3c;

send_data1(send_buf,idx);

}


读取时间的驱动


/**

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_buf,idx);

}


接收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_buff,0,lcd_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_buff,0,lcd_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(&hadc1,50);//等待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_value,vol);

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_buf,FILTER_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=0;i<FILTER_N;i++)

{

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

}

pv.te=MedianFilter(te_buf,FILTER_N);//中值平均滤波

lcd_send_pv16(0x080002,pv.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=0;i<FILTER_N;i++)

{

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

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

}

pv.tem=MedianFilter(tem_buf,FILTER_N);//中值平均滤波

pv.hum=MedianFilter(hum_buf,FILTER_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 下一页

关键词:TOPWAYLCD水质仪

评论


相关推荐

技术专区

关闭