先上代码:

void Draw_Keyboard_Layout(void)
{LCD_ShowString(5,25,200,16,16,"Power by Vincent-NJW");LCD_DrawRectangle(5,110,234,314);//矩形框LCD_DrawLine(62,110,62,314);//三条竖线LCD_DrawLine(119,110,119,314);LCD_DrawLine(177,110,177,314);LCD_DrawLine(5,161,234,161);//三条横线LCD_DrawLine(5,212,234,212);LCD_DrawLine(5,263,234,263);LCD_ShowString(31,131,200,16,16,"1");//写数字和符号LCD_ShowString(88,131,200,16,16,"2");LCD_ShowString(145,131,200,16,16,"3");LCD_ShowString(202,131,200,16,16,"+");LCD_ShowString(31,182,200,16,16,"4");LCD_ShowString(88,182,200,16,16,"5");LCD_ShowString(145,182,200,16,16,"6");LCD_ShowString(202,182,200,16,16,"-");LCD_ShowString(31,233,200,16,16,"7");LCD_ShowString(88,233,200,16,16,"8");LCD_ShowString(145,233,200,16,16,"9");LCD_ShowString(202,233,200,16,16,"*");LCD_ShowString(31,280,200,16,16,".");LCD_ShowString(88,284,200,16,16,"0");LCD_ShowString(145,284,200,16,16,"=");LCD_ShowString(202,284,200,16,16,"/");LCD_DrawLine(5,68,234,68);LCD_ShowString(5,50,200,16,16,"process:");LCD_ShowString(5,75,200,16,16,"answer:");LCD_DrawLine(5,93,234,93);
}//触摸扫描函数 .:10  =:11  +:12  -:13  *:14  /:15 ,没有触摸或者触摸到键盘以外的位置返回16
int Touch_Return(void)
{tp_dev.scan(0);         if(tp_dev.sta&TP_PRES_DOWN)            //触摸屏被按下{       if(tp_dev.x[0]>=5&&tp_dev.x[0]<=62&&tp_dev.y[0]>=110&&tp_dev.y[0]<=161)//按键按下会执行的操作{vTaskResume(Calculate_Task_Handler);return 1;}if(tp_dev.x[0]>=5&&tp_dev.x[0]<=62&&tp_dev.y[0]>=161&&tp_dev.y[0]<=212){vTaskResume(Calculate_Task_Handler);return 4;}if(tp_dev.x[0]>=5&&tp_dev.x[0]<=62&&tp_dev.y[0]>=212&&tp_dev.y[0]<=263){vTaskResume(Calculate_Task_Handler);return 7;}if(tp_dev.x[0]>=5&&tp_dev.x[0]<=62&&tp_dev.y[0]>=263&&tp_dev.y[0]<=314){vTaskResume(Calculate_Task_Handler);return 10;}if(tp_dev.x[0]>=62&&tp_dev.x[0]<=119&&tp_dev.y[0]>=110&&tp_dev.y[0]<=161)//第二列{vTaskResume(Calculate_Task_Handler);return 2;}if(tp_dev.x[0]>=62&&tp_dev.x[0]<=119&&tp_dev.y[0]>=161&&tp_dev.y[0]<=212){vTaskResume(Calculate_Task_Handler);return 5;}if(tp_dev.x[0]>=62&&tp_dev.x[0]<=119&&tp_dev.y[0]>=212&&tp_dev.y[0]<=263){vTaskResume(Calculate_Task_Handler);return 8;}if(tp_dev.x[0]>=62&&tp_dev.x[0]<=119&&tp_dev.y[0]>=263&&tp_dev.y[0]<=314){vTaskResume(Calculate_Task_Handler);return 0;}if(tp_dev.x[0]>=119&&tp_dev.x[0]<=177&&tp_dev.y[0]>=110&&tp_dev.y[0]<=161)//第三列{vTaskResume(Calculate_Task_Handler);return 3;}if(tp_dev.x[0]>=119&&tp_dev.x[0]<=177&&tp_dev.y[0]>=161&&tp_dev.y[0]<=212){vTaskResume(Calculate_Task_Handler);return 6;}if(tp_dev.x[0]>=119&&tp_dev.x[0]<=177&&tp_dev.y[0]>=212&&tp_dev.y[0]<=263){vTaskResume(Calculate_Task_Handler);return 9;}if(tp_dev.x[0]>=119&&tp_dev.x[0]<=177&&tp_dev.y[0]>=263&&tp_dev.y[0]<=314){vTaskResume(Calculate_Task_Handler);return 11;}if(tp_dev.x[0]>=177&&tp_dev.x[0]<=234&&tp_dev.y[0]>=110&&tp_dev.y[0]<=161)//第四列{vTaskResume(Calculate_Task_Handler);return 12;}if(tp_dev.x[0]>=177&&tp_dev.x[0]<=234&&tp_dev.y[0]>=161&&tp_dev.y[0]<=212){vTaskResume(Calculate_Task_Handler);return 13;}if(tp_dev.x[0]>=177&&tp_dev.x[0]<=234&&tp_dev.y[0]>=212&&tp_dev.y[0]<=263){vTaskResume(Calculate_Task_Handler);return 14;}if(tp_dev.x[0]>=177&&tp_dev.x[0]<=234&&tp_dev.y[0]>=263&&tp_dev.y[0]<=314){vTaskResume(Calculate_Task_Handler);return 15;}elsereturn 16;}else //没有按键按下的时候{delay_ms(10);   return 16;     }
}void calculate_task(void *pvParameters)
{int stage=0;//stage:用于判断第一个输入数的小数点前部分和后部分,输入第一个数时按下小数点置1。int stage2=0;//stage:用于判断第二个输入数的小数点前部分和后部分,输入第一个数时按下小数点置1。int stage1=0;//用于判断输入的是第几个数,按下+-*/时置1。int stage3=0;//按下=置1int Number_Distance=68;int Number2_Distance=60;int Number_Before_Point=0;//记录第一个数小数点后多少位,用于算number大小int Number1_Before_Point=0;//记录第一个数小数点后多少位,用于算number大小int Calculate_Stage;//存储按的是+-*/,+:1  -:2  *:3  /:4double number=0;//第一个数存储double number1=0;//第二个数存储double number2=0;//结果存储int Number2_Int=1;//记录number2整数部分有几位int Number2_Int1;//记录number2整数部分有几位时的中间变量int Number2_Float;//显示number2小数部分while(1){if(stage1==0&&(Touch_Return_Number==0||Touch_Return_Number==1||Touch_Return_Number==2||Touch_Return_Number==3||Touch_Return_Number==4||Touch_Return_Number==5||Touch_Return_Number==6||Touch_Return_Number==7||Touch_Return_Number==8||Touch_Return_Number==9||Touch_Return_Number==10))//第一个数处理{if(stage==0)//小数点前面部分{if(Touch_Return_Number==10){stage=1;//按小数点stage置1LCD_ShowString(Number_Distance,50,200,16,16,".");Number_Distance+=8;vTaskSuspend(Calculate_Task_Handler);}else{  LCD_ShowNum(Number_Distance,50,Touch_Return_Number,1,16);Number_Distance+=8;number=number*10+Touch_Return_Number;//printf("%d\r\n",number);vTaskSuspend(Calculate_Task_Handler);}}else//小数点后面部分{Number_Before_Point++;LCD_ShowNum(Number_Distance,50,Touch_Return_Number,1,16);Number_Distance+=8;number=number+Touch_Return_Number/(10.0*Number_Before_Point);vTaskSuspend(Calculate_Task_Handler);}}if(stage3==0&&stage1==0&&(Touch_Return_Number==12||Touch_Return_Number==13||Touch_Return_Number==14||Touch_Return_Number==15))//按下+-*/之后把stage1置1{stage1=1;if(Touch_Return_Number==12){   LCD_ShowString(Number_Distance,50,200,16,16,"+");Calculate_Stage=1;vTaskSuspend(Calculate_Task_Handler);}if(Touch_Return_Number==13){     LCD_ShowString(Number_Distance,50,200,16,16,"-");Calculate_Stage=2;vTaskSuspend(Calculate_Task_Handler);}if(Touch_Return_Number==14){  LCD_ShowString(Number_Distance,50,200,16,16,"*");Calculate_Stage=3;vTaskSuspend(Calculate_Task_Handler);}if(Touch_Return_Number==15){  LCD_ShowString(Number_Distance,50,200,16,16,"/");Calculate_Stage=4;vTaskSuspend(Calculate_Task_Handler);}Number_Distance+=8;}if(stage3==0&&stage1==1&&(Touch_Return_Number==0||Touch_Return_Number==1||Touch_Return_Number==2||Touch_Return_Number==3||Touch_Return_Number==4||Touch_Return_Number==5||Touch_Return_Number==6||Touch_Return_Number==7||Touch_Return_Number==8||Touch_Return_Number==9||Touch_Return_Number==10))//第二个数处理{if(stage2==0)//小数点前面部分{if(Touch_Return_Number==10){stage2=1;//按小数点stage置1LCD_ShowString(Number_Distance,50,200,16,16,".");Number_Distance+=8;vTaskSuspend(Calculate_Task_Handler);}else{   LCD_ShowNum(Number_Distance,50,Touch_Return_Number,1,16);Number_Distance+=8;number1=number1*10+Touch_Return_Number;//printf("%d\r\n",number);vTaskSuspend(Calculate_Task_Handler);}}else//小数点后面部分{Number1_Before_Point++;LCD_ShowNum(Number_Distance,50,Touch_Return_Number,1,16);Number_Distance+=8;number1=number1+Touch_Return_Number/(10.0*Number1_Before_Point);vTaskSuspend(Calculate_Task_Handler);}}if(Touch_Return_Number==11&&stage1==1&&stage3==0)//按下={stage3=1;if(Calculate_Stage==1)number2=number+number1;if(Calculate_Stage==2)number2=number-number1;if(Calculate_Stage==3)number2=number*number1;if(Calculate_Stage==4){if(number1==0){LCD_ShowString(Number2_Distance,75,200,16,16,"error");vTaskSuspend(Calculate_Task_Handler);}elsenumber2=number/number1;}Number2_Int1=(int)number2;while(1){if((Number2_Int1/10)==0)break;else{Number2_Int++;Number2_Int1/=10;}}    printf("%d\r\n",Number2_Int);printf("%d\r\n",(int)number2);printf("%f\r\n",number);printf("%f\r\n",number1);printf("%f\r\n",number2);if(number2<0){LCD_ShowString(Number2_Distance,75,200,16,16,"-");    Number2_Distance+=8;number2=-number2;}LCD_ShowNum(Number2_Distance,75,(int)number2,Number2_Int,16);Number2_Distance=Number2_Distance+8*Number2_Int;LCD_ShowString(Number2_Distance,75,200,16,16,".");Number2_Distance+=8;if((((int)(number2*10))%10)==0){LCD_ShowNum(Number2_Distance,75,0,1,16);Number2_Distance+=8;}Number2_Float=(int)((number2-(int)number2)*1000);LCD_ShowNum(Number2_Distance,75,Number2_Float,3,16);vTaskSuspend(Calculate_Task_Handler);}}
}   

以上展示的是最主要的三个函数,第一个是画页面布局,第二个是按下触摸屏的返回值,第三个是简易计算器的逻辑。

首先第一点我要说明的是我的代码是在正点原子的mini板上跑的,对于硬件的连接和驱动协议上面我这里就不在过多的解释。第一点原因是mini板的原理图大家在正点原子的官网上都可以下的到,第二点是在正点原子给出的官方历程库里面包含了板载全部硬件的驱动程序。虽然对于我们来说驱动程序的编写和理解也是非常重要的,但是作者在写程序的时候只有一下午时间,由于时间比较紧迫,我们就保持着拿来主义的态度,先基本实现自己的功能,对于驱动程序的理解后期可以在慢慢深究。

第二点我要说的是我的代码都是放到freertos里面跑的,我创建了两个任务,第一个是触摸屏的扫描返回,第二个是计算器的逻辑。通过触摸一个数字或者符号来实现对计算器逻辑任务的解挂让计算器逻辑函数一次执行,这样做的好处是会让整个逻辑看起来更加的清晰和简单。

接下来我来讲一下三个函数功能,第一个void Draw_Keyboard_Layout(void)是在触摸屏上画一个4*4的方格以及内部填充的符号合数字以及计算的过程和结果的显示,操作比较简单就是调用LCD的API函数。效果如下:

第二个函数是触摸扫描函数int Touch_Return(void)原理是在触摸屏的扫描任务中不断检测用户按下位置的坐标,在检测到用户按下后把坐标存放在tp_dev.x[0]和tp_dev.y[0]里面,然后与我画的框格的范围做比较,根据不同的范围先解挂计算器任务然后返回对应的值。具体的操作流程我在代码栏都有注释。第三个函数也是最核心的部分void calculate_task(void *pvParameters)计算器的逻辑函数,大概思路是这样的,我用了一个全局变量Touch_Return_Number来实现两个任务之间的通信。当Touch_Return_Number的值符合我在计算器的逻辑函数设定的标准和一系列的标志位都符合条件之后会进入到不同的if语句里面去实现不同的功能。当执行完一个操作之后,我会把计算器逻辑任务挂起,等待用户按下按键之后,触摸屏返回任务会解挂计算器逻辑任务。从而实现,按一个按键执行一次计算器逻辑操作(对应一个if语句)。对应的逻辑大家可以看我代码的注释部分,我写的比较详细,应该可以理解,如果有疑问的话可以加作者的QQ,QQ在文章末尾有给出。

由于作者只有一下午的时间写这些代码,加上触摸的界面比较的简单,所以就没有用STemwin等GUI库。由于开发时间短也导致一些bug我没有来的急及时的更改,第一个就是浮点数的精度问题,由于计算机对浮点数的存储并不是准确的,所以导致在做小数位数比较多的浮点数乘法的时候会有一定的误差,其实可以用一些简单的算法和小技巧提高精度,但是目前程序的效果对于作者来说已经足够了。第二个就是在结果是整数的时候,小数点后面的零会有两个单位的间隔,但是考虑到不影响结果的观察所以就没有更改。还有一些小bug希望读者在实践过程中发现,写的逻辑不是那么的严谨,希望见谅!

name:Vincent-NJW

QQ:1504012979

stm32基于FreeRtos下的电阻触摸屏简易计算器相关推荐

  1. 基于VC6.0用MFC编写简易计算器

    功能介绍: 1> 标准型:能进行加.减.乘.除四则运算,具有清空.回退功能,还附加了添加小数点.化为百分数的功能. 2> 科学型:新增了求三角函数(sin.cos.tan).反三角函数(a ...

  2. 基于python:利用pyqt5设计简易计算器

    实训内容: 跟随学习,用python写一个能进行简易运算的计算器,并自己设计计算器的UI界面,并根据实际对外观做出一定的美化. 准备过程 本次使用的是Windows11,python环境3.9.15 ...

  3. c51单片机矩阵键盘1602计算器_基于51单片机矩阵键盘的简易计算器制作

    1. 运算过程.符号公式实时显示在显示屏上(I2C 1602). 2. 自带三角函数.开根号.平方运算. 3. 计算得出的结果可设置保存并用以下一次计算. 4. 所有运算结果精确到至少小数点后两位. ...

  4. eclipse调试基于freertos的嵌入式工程

    目录 eclipse调试基于freertos的嵌入式工程 建立开发环境 安装GNU Tools ARM Embedded交叉编译工具链 安装GNU ARM Eclipse Build Tools 安装 ...

  5. 基于FreeRTOS与MQTT的物联网技术应用系列——步进电机控制(四)FreeRTOS系统下LwIP-1.4.1的移植

    本文在前一篇的基础上,进行基于FreeRTOS的LwIP-1.4.1版本移植. 本文使用的网卡PHY芯片型号是DP83848,工作在MII接口模式,时钟频率是25MHz. 现在的LwIP版本已经发展到 ...

  6. 基于STM32、FreeRTOS低功耗设计思路和原理

    关注+星标公众号,不错过精彩内容 作者 | strongerHuang 微信公众号 | 嵌入式专栏 如今电池供电的产品很多,电池供电通常设计到一个问题,那就是低功耗. 本文为大家讲讲基于STM32.F ...

  7. STM32工作笔记0028---上拉电阻,下拉电阻

    技术交流QQ群[JAVA,C++,Python,.NET,BigData,AI]:170933152 用在数字电路中,存在高低电平的场合. 上拉电阻与下拉电阻怎么接线? 上拉电阻:电阻一端接VCC,一 ...

  8. STM32低功耗模式下GPIO如何配置最节能?

    目录 1.将未使用的GPIO 配置为模拟输入模式 2.调节GPIO 速度 3.GPIO不使用时禁用寄存器时钟 4.避免悬空未使用的引脚 STM32低功耗模式下GPIO如何配置最节能,这里总结了一下四点 ...

  9. 【STM32】FreeRTOS简介

    00. 目录 文章目录 00. 目录 01. 什么是FreeRTOS 02. 为什么选择FreeRTOS 03. FreeRTOS特点 04. FreeRTOS商业许可 05. 预留 06. 附录 0 ...

最新文章

  1. Alexa偷录私密对话并发送,继诡笑之后出现又一神举动
  2. 终于放弃了Maven,我选择用Gradle!
  3. python当前日期获取程序_Python获取当前时间日期
  4. dev里timeedit控件如何赋值_抽奖程序里的字节跳动模式和时长控制,让抽奖更有仪式感!...
  5. 【LOJ】#2084. 「NOI2016」网格
  6. VTK:vtkBooleanOperationPolyDataFilter用法实战
  7. 【ArcGIS微课1000例】0018:ArcGIS设置相对路径和数据源
  8. idea java主题_IDEA变身超级形态,需要这个酷炫主题
  9. 打造属于自己的Vim神器
  10. 系统管理员最应该读的5本书_系统管理员的8本书
  11. 在Eclipse里使用代码模板
  12. html5文字云在线制作,tagul – 优秀的中文文字云标签云生成器工具
  13. usb-blaster 驱动在设备管理器处更新且安装成功后仍有黄色感叹号,显示:Windows 无法加载此软件的设备驱动程序。驱动程序可能损坏或丢失(代码:39)
  14. C语言课程设计 雷克子波反射系数 相位移动等
  15. PHP后端接入短信接口为用户发送通知短信
  16. php中Sessionopen,php使用session提示[function.session-start]: open解决方法
  17. 奥丁神叛虚拟机 台服登录不上游戏 账号无法登录游戏解决办法
  18. android开发论坛
  19. sja1000编程c语言,基于51单片机SJA1000 CAN通讯实现(C语言程序)
  20. 老农解决猫狗鱼的问题(黑马基础习题)

热门文章

  1. 【PCL自学:Filtering】PCL中的各类滤波器介绍与使用 (持续更新)
  2. QChart添加跟随鼠标的十字线
  3. 哈佛凌晨4点半【收藏】
  4. 专项测试之Web测试
  5. Android初学 抖音短视频无水印下载APP的实现
  6. android 淘口令,淘口令解析
  7. java实体类转换器,用于基础类向VO类转换
  8. 电话号码或者姓名的隐藏小工具
  9. 微信小程序之订单倒计时实现
  10. AIX6.1上重新安装RAC11G时,ASM无法识别磁盘为Candidate Dsik