当前位置: 首页 > news >正文

做一个中文域名购物网站要多少钱应用网站制作

做一个中文域名购物网站要多少钱,应用网站制作,商务信息网,做的网站电脑上跟手机上不一样KEIL开发 51 单片机程序 算法处理过程中遇到的问题 ...... by 矜辰所致前言 因为产品的更新换代, 把所有温湿度传感器都换成 SHT40 ,替换以前的 SHT21。在 STM32 系列产品上的替换都正常,但是在一块 51 内核的无线产品上面,数据…
KEIL开发 51 单片机程序 算法处理过程中遇到的问题  ...... by 矜辰所致

前言

因为产品的更新换代, 把所有温湿度传感器都换成 SHT40 ,替换以前的 SHT21。在 STM32 系列产品上的替换都正常,但是在一块 51 内核的无线产品上面,数据莫名其妙的总会遇到异常的情况,弯弯绕绕了好一阵子,最后才发现是程序在执行一个不算复杂的算法的时候会出错。

那么本文的目的就是说明这个问题,以及如何解决这个问题,同时也想向大家请教这个问题出现的原因。 因为到最后,没有花时间去过多的研究到底是怎么出的问题。

我是矜辰所致,全网同名,尽量用心写好每一系列文章,不浮夸,不将就,认真对待学知识的我们,矜辰所致,金石为开!

目录

  • 前言
  • 一、 SHT40 温湿度读取
  • 二、51 上的数据异常
    • 2.1 程序移植
    • 2.2 问题分析
    • 2.3 问题解决
  • 结语

一、 SHT40 温湿度读取

本来 SHT40 其实特别简单, 简单的 I2C 通讯,简单的计算公式,在 SHT40 数据手册上面,只要看一个地方基本就能把 SHT40 用起来了,如下图:

在这里插入图片描述

硬件电路,和算法手册都给出来了,实际上在使用 STM32 的时候确实是真简单就可以正确的读取到数据,代码如下:

/*
SHT40
地址和 SHT30 一样 0x44
*/
Readthstruct SHT40_read_result(u8 addr)
{u16 tem,hum;u16 buff[6] = {0};float Temperature=0;float Humidity=0;Readthstruct sensordata;I2C_Start();I2C_Send_Byte(addr<<1 | write);//写7位I2C设备地址加0作为写取位,1为读取位I2C_Wait_Ack();I2C_Send_Byte(0xFD);    //  SHT 40 只需要一个 0xFDI2C_Wait_Ack();// I2C_Send_Byte(0x06);// I2C_Wait_Ack();I2C_Stop();HAL_Delay(20);I2C_Start();I2C_Send_Byte(addr<<1 | read);//写7位I2C设备地址加0作为写取位,1为读取位if(I2C_Wait_Ack()==0){buff[0]=I2C_Read_Byte(1);buff[1]=I2C_Read_Byte(1);        buff[2]=I2C_Read_Byte(1);        buff[3]=I2C_Read_Byte(1);buff[4]=I2C_Read_Byte(1);buff[5]=I2C_Read_Byte(0);I2C_Stop();}tem = ((buff[0]<<8) | buff[1]);//温度拼接hum = ((buff[3]<<8) | buff[4]);//湿度拼接/*转换实际温度*/Temperature= (175.0*(float)tem/65535.0-45.0) ;// T = -45 + 175 * tem / (2^16-1)/**humi = (1.0 * 125 * (readData[3] * 256 + readData[4])) / 65535.0 - 6.0;rh_pRH = -6 + 125 * rh_ticks/65535*/Humidity= (125.0*(float)hum/65535.0-6.0); // sprintf(humiture_buff1,"%6.2f*C %6.2f%%",Temperature,Humidity);//111.01*C 100.01%(保留2位小数)// printf("温湿度:%s\n",humiture_buff1);if((Temperature>=-20)&&(Temperature<=80)&&(Humidity>=0)&&(Humidity<=100))//过滤错误数据{sensordata.tem_100 = (u16)(Temperature*100);sensordata.hum_100 = (u16)(Humidity*100);}else{//重新通讯读取一遍}// printf("温度100倍:%d\n湿度100倍:%d\n",sensordata.tem_100,sensordata.hum_100);hum=0;tem=0;if(sensordata.tem_100>4000) sensordata.tem_100=4000;              //A5-04-01 0~40du else if(sensordata.tem_100<0) sensordata.tem_100=0;if(sensordata.hum_100>10000) sensordata.hum_100=10000;              //prevent temperature over-/underflowelse if(sensordata.hum_100<0) sensordata.hum_100=0;return sensordata;
}

上面的代码是为了得到 温湿度实际数据的100倍的结果, 上面时候因为测试,中途需要打印浮点数,所以中途按照浮点数计算了结果,
其实可以在Temperature= (175.0*(float)tem/65535.0-45.0) 这地方直接得到 100 倍的数值,
而且还可以省去浮点数的计算。

反正到这里一切都是正常的,于情于理挺简单的应用当然不会有问题。

二、51 上的数据异常

2.1 程序移植

在 STM32 上替换很顺利,那么还有一款 51 内核的无线芯片也需要替换,那么其实也就是做了简单的移植,通讯逻辑基本和上面一样:

void SHT40THMeasure()
{sint16 tem,hum;uint16 buff[6] = {0};float Temperature=0;float Humidity=0;time_wait(20);i2c_start();u8Ack = i2c_write(0x94); //SHT40_SOFT_RESETi2c_stop();time_wait(10);	i2c_start();u8Ack = i2c_write(0X44<<1); //I2C_Send_Byte(0x44<<1 | 0);u8Ack = i2c_write(0xFD);i2c_stop();time_wait(20); //HAL_Delay(20);i2c_start();u8Ack = i2c_write((0X44<<1) + 1);if(u8Ack==I2C_ACK){buff[0]= i2c_read(I2C_ACK);	buff[1]= i2c_read(I2C_ACK);	buff[2]= i2c_read(I2C_ACK);	buff[3]= i2c_read(I2C_ACK);buff[4]= i2c_read(I2C_ACK);	buff[5]= i2c_read(I2C_NACK);i2c_stop();} tem = ((buff[0]<<8) | buff[1]);//温度拼接hum = ((buff[3]<<8) | buff[4]);//湿度拼接Temperature= (175.0*(float)tem/65535.0-45.0) ;// T = -45 + 175 * tem / (2^16-1)Humidity= (125.0*(float)hum/65535.0-6.0); if((Temperature>=-20)&&(Temperature<=80)&&(Humidity>=0)&&(Humidity<=100))//过滤错误数据{aTemperature.value = (u16)(Temperature*100);aHumidity.value = (u16)(Humidity*100);}else{//数据出错,再来一遍i2c_start();u8Ack = i2c_write(0x94); //SHT40_SOFT_RESETi2c_stop();// 这里就省略了,就是重复一遍}if(aTemperature.value>4000) aTemperature.value=4000;              //prevent temperature over-/underflowelse if(aTemperature.value<0) aTemperature.value=0;if(aHumidity.value>10000) aHumidity.value=10000;              //prevent temperature over-/underflowelse if(aHumidity.value<0) aHumidity.value=0;}

上面代码其实也不复杂,因为本来就很简单。 但是在测试的时候,总是会出现温湿度数据异常的情况,比如湿度为0 ,温度最最大值等等 。

2.2 问题分析

在最开始的时候,连硬件问题,然后还有因为低功耗需要给传感器断电问题都统统想到过,都先给一一排除了。

最终还是回到程序上来,也尝试过校验,软件复位,多次读取等等方式,发现依然存在问题。

各种可能的不可能的问题估计都想过,最后考虑了一下以前是 32 位的 ARM 内核,现在是 8 位 51 内核,是不是算法有点问题,然后看了下代码,主要集中在算法那两行代码 :

	Temperature= (175.0*(float)tem/65535.0-45.0) ;// T = -45 + 175 * tem / (2^16-1)Humidity= (125.0*(float)hum/65535.0-6.0); 

想着在 51 单片机上进行浮点数运算比较 “困难” 的,如果可以尽量减少浮点数的运算 。

所以为了防止因为浮点数计算导致的问题,直接把浮点数运算也去掉,因为以前 SHT21 在 51 上数据也是正常的,所以参考了一下 以前 SHT21 的算法书写:

sint16 sht21_calcRH(uint16 u16RH)
{sint16 humidityRH;              // variable for resultu16RH &= ~0x0003;          // clear bits [1..0] (status bits)//-- calculate relative humidity [%RH] --humidityRH = (sint16)(-600 + (12500*(sint32)u16RH)/65536 ); // RH = -6 + 125 * SRH/2^16return humidityRH;                                          // Return RH*100
}// -------------------------------------------------------------------
sint16 sht21_calcTemperature(uint16 u16T)
{sint16 temperature;            // variable for resultu16T &= ~0x0003;           // clear bits [1..0] (status bits)//-- calculate temperature [癈] --temperature= (sint16)(-4685 + (17572*(sint32)u16T)/65536); //T = -46.85 + 175.72 * ST/2^16return temperature;                                        //return T*100
}

把算法变成如下:

tem = ((buff[0]<<8) | buff[1]);//温度拼接hum = ((buff[3]<<8) | buff[4]);//湿度拼接aTemperature.value =   (sint16)	(17500*(sint32)tem/65535 - 4500) ;aHumidity.value = (sint16) (12500*(sint32)hum/65535 - 600); ...

上面已经没有了浮点数运算,数据类型也注意到了,感觉应该没什么问题。

但是实际测试下来,结果还是和以前一样。

期间还测试发现当湿度大于接近 40% 的时候,湿度 aHumidity.value 就会变成 0 。

为了排除不是传感器通讯的问题,期间还读取过 tem 和 hum 的值观察,然后自己通过算法计算都能得到准确的数据。

然后自己给一个合理的 tem hum 的值,如下图:

tem = ((buff[0]<<8) | buff[1]);//温度拼接hum = ((buff[3]<<8) | buff[4]);//湿度拼接tem = 0x 78;//写文章的测试例子,当时是多少来着忘记了tem = 0x 78;aTemperature.value =   (sint16)	(17500*(sint32)tem/65535 - 4500) ;aHumidity.value = (sint16) (12500*(sint32)hum/65535 - 600); ...

确实发现只要 aHumidity.value 正确计算结果在接近或者大于 4000 的时候,这个算是结果在程序中就会变成 0 。

对比了一下算法的书写,是在看不出哪里会溢出什么的。

再反复看了以前 SHT21 的算法,明明也是这样的算法,怎么就会不行了呢?

在这里插入图片描述

2.3 问题解决

最后实在是觉得还是不应该出问题,但是明明以前 SHT21 也是在同样的环境,同样的平台下,就是这么写的算式,不应该啊。

最后才看来看去,再看了下以前 SHT21 怎么处理的:

在这里插入图片描述

在文章上面其实我也给出了 SHT21 的这两个计算结果的函数,在以前 I2C 通讯完毕,是通过调用了计算结果的函数得到的数值没有问题。

于是乎,我把 SHT40 也尝试封装成了同样的函数,算法直接复制进去,如下图:

在这里插入图片描述

然后忽然就发现…… 好了…… 数据怎么样都正常了……

这真的是沙比问题,我确实有点懵了,反正最后自己也不知道是什么根本原因。

网上也没有明确的此类问题的,到处查阅了一些资料,有的说是因为编译器的代码优化问题,或者说是因为 51 编译器自己的问题导致的。

结语

其实问题虽然是解决了,但是我还是不知道是因为什么原因,如果有小伙伴知道,还望多多指教,记得留言哦 。

当然出了这个问题,也给我们提了个醒,算法最好是封装成函数,虽然说,函数调用会有一定的开销,但是这样做不仅可读性和维护性强, 在重用,调试等方面也更有优势, 最重要的可以避免编译器对我们的程序进行不理想的优化导致的一些错误 。

那么本文就到这里,谢谢大家!

http://www.yayakq.cn/news/213559/

相关文章:

  • 网站怎么建设好看网页设计图片格式
  • 金融投资管理公司网站源码做3个网站需要多大的服务器
  • 网站开发需求收集手机微信网站模板
  • 爱漫画-只做精品的韩漫网站wordpress 能源插件
  • 网站建设调查报告范文佛山关键词自动排名
  • 内江市规划建设教育培训中心网站wordpress 左右图文排版
  • 实时网站推广的最终目的是老域名做网站好吗
  • storyset自定义插画网站顶呱呱网站建设价格
  • php网站开发面试题龙岗外贸网站建设公司
  • 网站建立不安全怎么设置通过做网站新闻
  • 用什么网站做浏览器主页制作app软件要多少钱一个
  • 那个网站可以做logo网站icp备案信息是什么意思
  • 商丘网站制作案例网站做链接代码
  • 做网站购买服务器吗安阳淘宝网站建设
  • 专业网站建设公司排名如何申请一个网站 新网
  • 介绍几个免费的网站黄岩区建设规划局网站
  • 做模板网站的公司建e室内设计网 3d模型医美前台
  • 有哪些营销型网站新媒体配图的相关知识
  • 佛山外贸网站建设资讯跨境电商怎么做一件代发
  • 西安装修公司网站制作十堰seo优化
  • 个人网站备案 备注网络运营公司的经营范围
  • 网站建设出现401中国镇江网站
  • 婚礼婚庆网站建设网络设计一个月多少钱
  • 静态网页有哪些网站烟台酒店网站建设
  • 龙岩网站建设一般大庆网站建设优化
  • 铝木门窗网站建设网页设计制作网站代码html
  • 游戏开发和网站开发重庆企业年报网上申报入口
  • h5免费建站资阳网站seo
  • 祁东网站设计公司网站制作公司推荐
  • 怎么做免费个人网站江苏省建设厅的官方网站