1 功能确定
首先来看一下科学计算器的样子。这是市面上CASIO计算器,可谓功能十分强大,我们要用labview实现这样的功能,就跟现实中的计算器功能一样,就不赘述了。
![](https://i-blog.csdnimg.cn/blog_migrate/cc0bdbc32e967994c67ac2e0fd4799ec.png)
2 程序设计分析
在Labview程序开发时,无论功能简单还是复杂,在明确后一定要进行程序设计过程,而不要一上来就堆程序叠加功能。程序设计分析更多的考察个人的编程思想,与采用什么编程语言不是太相关,即使是开发java、C#等其他语言也是如此。
首先看输入与输出。输入是数字键+运算符键+功能键;输出即结果显示。将这些内容细化为如图:
![](https://i-blog.csdnimg.cn/blog_migrate/30cede52a262174fe77f1638ee66d484.png)
其次,是程序结构框图。我们来分析一下:输入是以“按键”的方式进行输入,输出是以“数值”+“字符”的形式显示,先考虑Labview中如何实现这样的功能,然后再考虑程序逻辑问题。
A.功能实现
首先来看控件的类型,在前面板空白处右键,弹出控件工具箱,可以看到有数值、布尔、字符串、数组等,可以自行点进去看看每种控件下包含的子控件及功能。
![](https://i-blog.csdnimg.cn/blog_migrate/06e9fefedbef9f16feed711b982e71c7.png)
接着来看,输入端都是按键,我们选用“布尔”控件。仔细分析一下布尔控件:在控件中选择布尔——随便选择一个拉出来,然后右键该控件,选择属性——操作选项卡,如下图。
![](https://i-blog.csdnimg.cn/blog_migrate/664bed41035ac66a2eed71be27d14128.png)
布尔控件虽然类型众多,但除外观不同外,其最大的区别在于触发和响应方式不同,如上“按钮动作”中所列,分别对应不同方式下触发;“动作解释”是响应的文字和图形说明。
另外,布尔型数据只有两个值:“真”或“假”。该控件是没有局部变量或者具体的“值”,只能作为控制控件,类似开关控制一样模拟不同种类开关的行为。
这里选择方块形状的按钮,以“释放时触发”,先按照计算器的布局将按键都排布好。
打开软件——新建项目——保存为“Calculator”——新建VI(Ctrl+N)——保存为“Panel”。
先为计算器界面放一个背景图,背景图我用Ai绘制了一个,感兴趣的朋友可以参考教程自行绘制https://zhuanlan.zhihu.com/p/157327602
在前面板上右键,添加下拉控件——图片下拉列表
![](https://i-blog.csdnimg.cn/blog_migrate/943dd2947b507b86c31e95597469fbc9.png)
选择编辑——导入图片至剪切板,选中图片
![](https://i-blog.csdnimg.cn/blog_migrate/c9f8f1f7e4095fcea21d7569d16d3925.png)
在控件右键,选择剪贴板导入图片
![](https://i-blog.csdnimg.cn/blog_migrate/320001e9809b4bdec527d81651b757ea.png)
最后形成的效果如图所示
![](https://i-blog.csdnimg.cn/blog_migrate/15f1a72c07d6e259eb9627e9cdd5fe00.png)
在该图片上添加控件——布尔——确定按钮,然后右键控件修改大小、标签、文本显示等
![](https://i-blog.csdnimg.cn/blog_migrate/0c7aa90da4eaecb0581ac1a34303345c.png)
按照计算器的显示样式依次设置,最终效果如图所示
![](https://i-blog.csdnimg.cn/blog_migrate/c562b84ff92e52c9a5a828a4f57110af.png)
对于输出,选择字符串——显示控件,右键修改标签不可见,名称为“显示面板”
![](https://i-blog.csdnimg.cn/blog_migrate/1f4279354c36f5c6ac7aeab149cd1d4b.png)
至此,我们仅仅完成了主界面或者说面板的界面设计,但这只是个空架子,背后每个控件如何实现功能,我们在程序逻辑中讲述。
B.程序逻辑
在叙述之前,先了解子VI,通俗来说,子VI相当于一个子函数或者程序包,可以供主函数或者主程序调用。
主界面要实现的功能是输入数字+运算符,在显示面板响应键盘输入内容。其次,各个按键的功能是实现运算,可以把运算功能全部封装为子VI,主界面只要直接调用即可。最后,功能键合报错机制需要进行补充考虑。
按照上述逻辑做一个程序框图如下:
容我喘口气,未完待续....
过了大半年,我又回来了。这段时间断断续续有朋友催我更新,因为贪玩很抱歉没有及时推文,今天把这块儿补上。
(续上)
3.子功能实现
3.1 乘除的实现
(1)理论基础
首先学习一下“字符串/数值转换函数”,实现的功能是 从偏移量位置开始,使字符串中的下列字符:0-9、加号、减号、e、E、小数点(通常是句点)解析为工程、科学或分数格式的浮点数,通过数字返回。
![](https://img-blog.csdnimg.cn/img_convert/dbc87b16c960acc8d45f0139e47b4653.jpeg)
然后是“创建数组”, 连接多个数组或向N维数组添加元素
![](https://img-blog.csdnimg.cn/img_convert/b5ed542550d70990e0db1294a7462d61.jpeg)
再然后是删除数组元素,在n维数组的索引位置开始删除一个元素或指定长度的子数组。 返回已删除元素的数组子集,删除的元素或数组子集在已删除的部分中显示。 连线数组至该函数时,函数可自动调整大小以显示数组各个维度的索引。
![](https://img-blog.csdnimg.cn/img_convert/c6f7165f777ac4cf2307c90fa4dc91df.jpeg)
字符串数值转换函数:使数字转换为小数(分数)格式的浮点型字符串,至少为宽度个字符,还可依据需要适当加宽。
![](https://img-blog.csdnimg.cn/img_convert/51428813758c15053b300a20c6f82399.jpeg)
(2)程序思路
以“乘除”为例,输入条件为“数值+运算符”,先判断运算符,然后执行
![](https://img-blog.csdnimg.cn/img_convert/b38be4b1bcc7481f6c0c9c7260d9179e.jpeg)
(3)功能实现
首先在前面板放置数组(右键——数组——第一个;然后再右键——数值——数值输入控件),这样就形成了数组
![](https://img-blog.csdnimg.cn/img_convert/c17f1aed66b3edb05e7e43616fd54e55.jpeg)
依次放入两个数组,1个字符串输入,1个数值输出控件,1个字符串输出控件。
![](https://img-blog.csdnimg.cn/img_convert/ade88442b4c069b0cd4400e7a47598c4.jpeg)
然后进入程序设计部分,字符串输入控件用于输入计算式,如:“10*12”,输入的字符串进入循环检索程序,先识别字符串中的运算符是“*”还是“/”,用匹配模式(使用方式见3.6)进行识别。
![](https://img-blog.csdnimg.cn/img_convert/50210ba64f903b1aeead1939c6601b79.jpeg)
例如“10*12”输入后,匹配模式检索到“*”,第一个匹配模式输出“10”、“*12”、“3”;第二个匹配模式检索不到“/”,因此输出“10*12”、“ ”、“-1”;匹配模式的偏移量进入第二个条件结构,3 & -1 输出为“假”,3直接输出;而-1 & -1 输出为“真”,输出“5”。因为3<5,故进入乘法条件结构中;具体的程序说明文字表达有点费劲且难以理解,可以私信小编进行讲解。
3.2 其他运算
![](https://img-blog.csdnimg.cn/img_convert/fc4921cc03e042545531d583c298f793.jpeg)
其他运算中包括三角函数、开方乘方等
![](https://img-blog.csdnimg.cn/img_convert/602d00e4bfc4b7ad4240cbde775054e7.jpeg)
具体的其他运算私戳小编。
3.3 括号运算
![](https://img-blog.csdnimg.cn/img_convert/ea44ed212d0354e6b948b8032a1333a9.jpeg)
程序实现如下:
![](https://img-blog.csdnimg.cn/img_convert/56d2614c4d17457de147b0545cc209de.jpeg)
3.4 加减运算
![](https://img-blog.csdnimg.cn/img_convert/f84abe6a51275f30c2a9dfc6c0aaf089.jpeg)
程序如下:
![](https://img-blog.csdnimg.cn/img_convert/d8aafe2de6d6a07c825297ce9e409b37.jpeg)
3.5弧度角度转换
(1)控件
前面板上一个输入一个输出,以及能够判断弧度角度转换的控件。
![](https://img-blog.csdnimg.cn/img_convert/f10e7f452812dc0733006d20fa62e74e.jpeg)
(2)程序实现
使用条件结构,双击选择框中的内容可以修改条件。将弧度/角度选择控件作为条件判断,弧度转角度,则进入角度计算部分,即输入×π/180,然后输出。
![](https://img-blog.csdnimg.cn/img_convert/8026d21a56792394d24122b409bdc6ec.jpeg)
如果是弧度,可以直接输出(默认为弧度输入)
![](https://img-blog.csdnimg.cn/img_convert/4894ad682dbbb86dfa4daffbac7d97b7.jpeg)
(3)改进
其中,弧度/角度输入输出用的是单选按钮,我们换成开关切换两者的转换,如下:
![](https://img-blog.csdnimg.cn/img_convert/7d4e2d5718bc531fb9731fcd27c582b5.jpeg)
![](https://img-blog.csdnimg.cn/img_convert/f68fd639182faee30c1d0194c4cc0623.jpeg)
3.6 去除结果中多余的0
(1)理论基础
首先学习下“匹配模式”,在程序视图中右键——字符串——匹配模式,下图给了每一个连线端代表的含义
![](https://img-blog.csdnimg.cn/img_convert/b2cae89302775b49905771ddc77ca1bb.jpeg)
接下来看看这个匹配模式能实现什么功能:我们在前面板上放这几个控件:1个字符串输入,3个字符串显示出,1个数值显示
![](https://img-blog.csdnimg.cn/img_convert/352eb887a241501e6eaeed934d2d978b.jpeg)
在程序框图中,添加一个字符串常量,写入“[0-9]+”再按照匹配模式的说明图进行连线。
![](https://img-blog.csdnimg.cn/img_convert/6f916104ff9aaa7b565bbc6b94aa8237.jpeg)
万事具备后,来说明一下它的功能:输入字符串中我们随便输入一串字符,比如“a-b1252a%+d”很随便的一串乱码,匹配模式用来匹配正则表达式规定的字符,我们正则表达式中写入的是“[0-9]+”,查询下面正则表达式含义,第4行可以看到,是指“一位或多位数序列”。偏移量没有连接,默认为“0”,那么从刚才那串字符串里从左到右依次检索,检索到多位数开始,到不是多位数时结束,也就是识别到“1252”这部分。所以,在输出的字符串2中会显示“a-b”,是匹配到的字符前的字符串;字符串3中会显示“1252”,是匹配到的字符,字符串4中会显示“a%+d”,而匹配后偏移量是“7”,因为最后一位“2”是在“a-b1252”这串字符的第7位。
![](https://img-blog.csdnimg.cn/img_convert/dc1b285e6f3d22b73179beaf3b314b5c.jpeg)
运行后的结果如图,这样就很清楚地了解了这个匹配模式每一个输入输出的含义了。
![](https://img-blog.csdnimg.cn/img_convert/e5c67e96dfd1bbacf6f71e0c863770b4.jpeg)
需要注意的是,如果匹配不到,则匹配后偏移量返回“-1”。这是后面作为条件判断的关键。
(2)编程分析
去除多余的0要实现的功能是诸如“12.0000”,“12.43000”这样的数字,去除其后的0.由于这是对结果去0,结果一般是数值或者错误字符提醒,因此考虑的情况比较单一,思路如下:
![](https://img-blog.csdnimg.cn/img_convert/94a957ecde32cbcf258d33c980bb2603.jpeg)
(3)具体实现方式
在前面板上,放置两个控件,一个是字符串输入,一个是字符串显示
![](https://img-blog.csdnimg.cn/img_convert/562b418a1f6a52d8a86e9c268c8e6b31.jpeg)
在程序框图中首先判断输入的字符串是否为一位或多位数字,若不是,直接输出;
![](https://img-blog.csdnimg.cn/img_convert/1fe0a80dd99c34ee9f95efada8fde473.jpeg)
如果输入的字符串是一位或多位数字,则开始提取字符,将“.”前、“.”和“.”后的数字提取出来,即途中红色框的部分;
![](https://img-blog.csdnimg.cn/img_convert/7fa734e396931e470030c7ac7c5accfe.jpeg)
“.”后的数字若存在,则进入“去0”功能,用一个While循环执行,从字符串的最后一位起每次判断是否是“0”(通过偏移字符串长度实现),若是0,则只输出0前面的数字;若不是,则继续循环,直到检测不到“0”停止,具体细节如下图红色框部分所示:
![](https://img-blog.csdnimg.cn/img_convert/c0e34d408cdf12d9ddd86810d6ff5600.jpeg)
“.”后的数字经过去0之后输出的是“.”后没有0的数字,然后需要和“.”前面的数字连接起来共同输出,这时可以进行“空字符”的判断,如果经过去0处理后为空,则直接输出“.”前的数字;
![](https://img-blog.csdnimg.cn/img_convert/41dd6b38e7b6f6d2d051c170101b8f15.jpeg)
如果不为空,则将“.”、“.”前和处理后的数字全部叠加起来再输出,整体实现如下:
![](https://img-blog.csdnimg.cn/img_convert/f3e08a7ab3a1bc35e38957ea63eba4be.jpeg)
(4)VI封装
进行到上面就结束了吗?不,良好的编程习惯还需要对VI图标和接线端进行设计加工,以方便整个项目的管理。双击前面板的图标,如下图右上角,是我已经改动过的。
![](https://img-blog.csdnimg.cn/img_convert/fc528ef373f9d9291d8d34c6304bf132.jpeg)
(5)运行验证
点击实时运行,在输入框输入各种数值进行验证,看输出是否为理想状态。
![](https://img-blog.csdnimg.cn/img_convert/e9dc5d57a5a0b321f3e6921359ad08f3.jpeg)
4 主功能实现
(1)控件
主功能需要在计算器的面板上集成各个子功能,其中,控件面板在前述已经绘制完毕,示意图如下:
![](https://img-blog.csdnimg.cn/img_convert/7078b18019558c7c16ad0d358d613181.jpeg)
(2)程序实现
整体采用事件结构,当检测到按键时实现按键代表的子功能:
需要说明几个结构——a. 属性节点
获取(读取)和/或设置(写入)引用的属性。 通过属性节点对本地或远程应用程序实例、VI或对象获取或设置属性和方法 也可通过属性节点访问LabVIEW类的私有数据。属性节点可自动调整为用户所引用的对象的类。 LabVIEW的属性节点可访问XML属性、VISA属性、.NET属性和ActiveX属性。
![](https://img-blog.csdnimg.cn/img_convert/95645a8b5b4664edae3bf85fbce1c66a.jpeg)
b. 事件结构
等待事件发生,并执行相应条件分支,处理该事件。 事件结构包括一个或多个子程序框图或事件分支,结构处理时间时,仅有一个子程序框图或分支在执行。 等待事件通知时,该结构可超时。 连线事件结构边框左上角的“超时”接线端,指定事件结构等待事件发生的时间,以毫秒为单位。 默认值为-1,表示永不超时。
![](https://img-blog.csdnimg.cn/img_convert/a35e4203424566968a341ef132c5843e.jpeg)
c.控件引用——局部变量
(3)功能验证
打开“Panel”文件,点击运行
![](https://img-blog.csdnimg.cn/img_convert/e9c8dfb2d946f1c1b395ba68c5550827.jpeg)
![](https://img-blog.csdnimg.cn/img_convert/339e601a28565a4500348a63a86c7815.jpeg)
——————
文末说明:
(1)使用的软件是Labview 2018
(2)采用的程序框架学习自Labview论坛
(3)理论学习图片来自软件的“帮助”文档
(4)程序代码去公众号“挽风笔谈”,回复“计算器”自行获取。
(5)代码讲解的交流可以加SonnyID_2020