STM32F4应用笔记(六)UCGUI+uC/OS-II+支持触摸屏——触屏计算器

最终实现的效果是一个触屏计算器,在上一篇博客的工程基础下改变主程序即可,用的是4.3寸屏幕,如果不是4.3寸屏幕,就需要自己该改参数,Calculator_Init函数中的界面参数也要重新设置,最终实现的效果如下:

这里写图片描述
主程序

#include "sys.h"
#include "delay.h"  
#include "usart.h"   
#include "led.h"
#include "beep.h"
#include "ili93xx.h" 
#include "touch.h"
#include "gui.h"
#include    "24cxx.h"
#include  "ucos_ii.h"  
#include  "string.h"  //需要用到字符串处理函数
#include  "stdio.h" //sprintf转换要用到

#include  "FRAMEWIN.h" 
#include  "BUTTON.h"  
#include  "EDIT.h" 
#include  "LISTBOX.h" 


int t;

//计算器的模块构建部分!定义为全局变量,省去了传递参数的麻烦,当然,这不够规范
FRAMEWIN_Handle  hFrame;  
//FRAMEWIN_Handle在#include  "FRAMEWIN.h" 当中
BUTTON_Handle  hButton1; 
BUTTON_Handle  hButton2; 
BUTTON_Handle  hButton3; 
BUTTON_Handle  hButton4; 
BUTTON_Handle  hButton5; 
BUTTON_Handle  hButton6; 
BUTTON_Handle  hButton7; 
BUTTON_Handle  hButton8; 
BUTTON_Handle  hButton9; 
BUTTON_Handle  hButton0; 
BUTTON_Handle  hButton_jia; 
BUTTON_Handle  hButton_jian; 
BUTTON_Handle  hButton_chen; 
BUTTON_Handle  hButton_chu; 
BUTTON_Handle  hButton_equal; 
BUTTON_Handle  hButton_backspace;
BUTTON_Handle  hButton_dort; 
BUTTON_Handle  hButton_ac; 

EDIT_Handle hEdit;
LISTBOX_Handle hListBox;
GUI_PID_STATE Button_State; //输入设备状态


char num1[10]={""};   
char num2[10]={""};
char temp1[50]={""}; //临时数组1——放第一个运算数
char temp2[50]={""}; //临时数组1——放第二个运算数
double a=0.0;   //妈的,必须用double,一开始用的float有时好用有时不好用
//还以为自己程序写错了
double b=0.0;
static int middle_flag=0; //中间运算符标志
double f=0.0; //存放最终结果
int len;//获取字符串长度
int Type=0; //默认是=0,表示没有运算符按下
//=1:加;=2:减;=3:乘;=4:除
/////////////////////////UCOSII任务设置///////////////////////////////////
//START 任务
//设置任务优先级
#define START_TASK_PRIO                 10 //开始任务的优先级设置为最低
//设置任务堆栈大小
#define START_STK_SIZE                  64
//任务堆栈  
OS_STK START_TASK_STK[START_STK_SIZE];
//任务函数
void start_task(void *pdata);   

//触摸屏任务
//设置任务优先级
#define TOUCH_TASK_PRIO             7 
//设置任务堆栈大小
#define TOUCH_STK_SIZE                      256
//任务堆栈
OS_STK TOUCH_TASK_STK[TOUCH_STK_SIZE];
//任务函数
void touch_task(void *pdata);


 /***************************************************************************
* 计算器框架的初始化部分 *
***************************************************************************/
void Calculator_Init(void) 
{
  hFrame = FRAMEWIN_Create("Calculator", NULL, WM_CF_SHOW, 0,0,480,800);
    //WM_CF_SHOW/* Show window after creation */
  FRAMEWIN_SetActive(hFrame, 1);
  FRAMEWIN_SetMoveable(hFrame, 1);    //设置为可移动的
  FRAMEWIN_SetFont(hFrame, &GUI_Font16B_ASCII);
  FRAMEWIN_SetTextColor(hFrame, GUI_RED);
  FRAMEWIN_SetBarColor(hFrame, 0, GUI_GREEN);
  FRAMEWIN_SetTextAlign(hFrame, GUI_TA_HCENTER);
  FRAMEWIN_AddMaxButton(hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
  FRAMEWIN_AddMinButton(hFrame, FRAMEWIN_BUTTON_RIGHT, 0);
  hButton1 = BUTTON_CreateAsChild(10,120,70, 70,hFrame,101,WM_CF_SHOW);  
    //注意这里的ID,每一个空间都有自己的一个ID
  hButton2 = BUTTON_CreateAsChild(10,200,70, 70,hFrame,102,WM_CF_SHOW);
  hButton3 = BUTTON_CreateAsChild(10,280,70, 70,hFrame,103,WM_CF_SHOW);
  hButton4 = BUTTON_CreateAsChild(90,120,70, 70,hFrame,104,WM_CF_SHOW);
  hButton5 = BUTTON_CreateAsChild(90,200,70, 70,hFrame,105,WM_CF_SHOW);
  hButton6 = BUTTON_CreateAsChild(90,280,70, 70,hFrame,106,WM_CF_SHOW);
  hButton7 = BUTTON_CreateAsChild(170,120,70, 70,hFrame,107,WM_CF_SHOW);
  hButton8 = BUTTON_CreateAsChild(170,200,70, 70,hFrame,108,WM_CF_SHOW);
  hButton9 = BUTTON_CreateAsChild(170,280,70, 70,hFrame,109,WM_CF_SHOW);
  hButton0 = BUTTON_CreateAsChild(250,120,70, 70,hFrame,100,WM_CF_SHOW);
  hButton_jia = BUTTON_CreateAsChild(250,200,70, 70,hFrame,110,WM_CF_SHOW);
  hButton_jian = BUTTON_CreateAsChild(250,280,70, 70,hFrame,111,WM_CF_SHOW);
  hButton_chen = BUTTON_CreateAsChild(330,120,70, 70,hFrame,112,WM_CF_SHOW);
  hButton_chu = BUTTON_CreateAsChild(330,200,70, 70,hFrame,113,WM_CF_SHOW);
  hButton_equal = BUTTON_CreateAsChild(330,280,70, 70,hFrame,114,WM_CF_SHOW);
    hButton_dort = BUTTON_CreateAsChild(410,200,70, 70,hFrame,115,WM_CF_SHOW);
  hButton_backspace = BUTTON_CreateAsChild(410,120,70, 70,hFrame,116,WM_CF_SHOW);
    hButton_ac = BUTTON_CreateAsChild(410,280,70, 70,hFrame,117,WM_CF_SHOW);
  BUTTON_SetText(hButton0, "0");
    BUTTON_SetFont(hButton0, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton1, "1");
    BUTTON_SetFont(hButton1, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton2, "2");
    BUTTON_SetFont(hButton2, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton3, "3");
    BUTTON_SetFont(hButton3, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton4, "4");
    BUTTON_SetFont(hButton4, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton5, "5");
    BUTTON_SetFont(hButton5, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton6, "6");
    BUTTON_SetFont(hButton6, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton7, "7");
    BUTTON_SetFont(hButton7, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton8, "8");
    BUTTON_SetFont(hButton8, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton9, "9");
    BUTTON_SetFont(hButton9, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_jia, "+");
    BUTTON_SetFont(hButton_jia, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_jian, "-");
    BUTTON_SetFont(hButton_jian, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_chen, "x");
    BUTTON_SetFont(hButton_chen, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_chu, "/");
    BUTTON_SetFont(hButton_chu, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_equal, "=");
    BUTTON_SetFont(hButton_equal, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_ac, "AC");
    BUTTON_SetFont(hButton_ac, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_dort, ".");
    BUTTON_SetFont(hButton_dort, &GUI_Font32B_ASCII);
  BUTTON_SetText(hButton_backspace, "Del");
    BUTTON_SetFont(hButton_backspace, &GUI_Font32B_ASCII);
  hEdit=EDIT_CreateAsChild(10, 30, 460, 80,hFrame, 118, WM_CF_SHOW, 20);
  EDIT_SetDefaultTextAlign(GUI_TA_RIGHT);
    EDIT_SetFont(hEdit, &GUI_Font24B_ASCII);
  EDIT_SetValue(hEdit,'0');
}

int main(void)
{ 
     Stm32_Clock_Init(336,8,2,7);//设置时钟,168Mhz
     delay_init(168);           //初始化延时函数
     LED_Init();                    //初始化LED时钟 
   BEEP_Init();         //蜂鸣器初始化    
     uart_init(84,115200);      //初始化串口波特率为115200——必须要有这句话 
     LCD_hard_Init();
     TP_Init();             //触摸屏初始化 
     GUI_Init();
     Calculator_Init();

     OSInit();                  //初始化UCOSII
     OSTaskCreate(start_task,(void *)0,(OS_STK *)&START_TASK_STK[START_STK_SIZE-1],START_TASK_PRIO );//创建起始任务
     OSStart();                 //启动UCOSII
}


//开始任务
void start_task(void *pdata)
{
  OS_CPU_SR cpu_sr=0;
    pdata = pdata; 
  OS_ENTER_CRITICAL();          //进入临界区(无法被中断打断)    
    OSTaskCreate(touch_task,(void *)0,(OS_STK*)&TOUCH_TASK_STK[TOUCH_STK_SIZE-1],TOUCH_TASK_PRIO);                     
    OSTaskSuspend(START_TASK_PRIO); //挂起起始任务.
    OS_EXIT_CRITICAL();             //退出临界区(可以被中断打断)
} 

//TOUCH任务
void touch_task(void *pdata)
{   
    int i;
    while(1)
    {
        t++;
        if(t==100)
        {
            LED0=~LED0;
            t=0;
        }
        GUI_TOUCH_Exec();                               
        GUI_TOUCH_GetState(&Button_State);    //得到输入设备状态                                             //
    GUI_TOUCH_StoreStateEx(&Button_State);//存储输入设备状态                                             //
        GUI_Exec();  //刷新显示——得有它,不然就是黑屏
        delay_ms(5);//——这个延时越长,触屏反应越不灵敏,不加也可以。
        if(middle_flag==0) //说明中间运算符是第一次按下
        {
        switch(GUI_GetKey())
            {  
            case 100:
                  strcat(num1,"0"); //num1数组加上字符0

               //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); //没问题试过了
                  a=atof(temp1);  //把字符串temp1转换成float——没问题

                EDIT_SetText(hEdit,num1);
                    BEEP=1;   //每次按键都会有蜂鸣器响声,表示按键动作的进行
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 101:
                  strcat(num1,"1"); 

                //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 102:
                  strcat(num1,"2"); 

                //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 103:
                  strcat(num1,"3"); 

                    //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 104:
                  strcat(num1,"4"); 

                    //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 105:
                  strcat(num1,"5"); 

                  //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 106:
                  strcat(num1,"6"); 

                    //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 107:
                  strcat(num1,"7"); 

                    //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 108:
                  strcat(num1,"8"); 

                    //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 109:
                  strcat(num1,"9"); 

                    //如果按完一个数直接按等号,必须显示数本身,这时候这2句代码就有用了
                    strcpy(temp1,num1); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a

                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 110:
                  Type=1; //+号按下
                    strcpy(temp1,num1);//将num1复制到temp1中——此时的temp1不包含运算符
                  strcat(num1,"+"); 
                  a=atof(temp1);  //把字符串temp1转换成浮点数a
                middle_flag=1;  //表示有运算符按下(除了=号)
                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 111:
                  Type=2; //-号按下
                    strcpy(temp1,num1);
                  strcat(num1,"-"); 
                  a=atof(temp1);  //把字符串转换成浮点数a
                middle_flag=1;  //表示有运算符按下(除了=号)
                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 112:
                    Type=3; //*号按下
                    strcpy(temp1,num1);
                  strcat(num1,"*"); 
                  a=atof(temp1);  //把字符串转换成浮点数a
                middle_flag=1;  //表示有运算符按下(除了=号)
                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 113:
                    Type=4; // /号按下
                    strcpy(temp1,num1);
                  strcat(num1,"/"); 
                  a=atof(temp1);  //把字符串转换成浮点数a
                middle_flag=1;  //表示有运算符按下(除了=号)
                EDIT_SetText(hEdit,num1);   
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 114:  //在没有中间运算符的情况下,等号按下,执行这段程序
                  //相当于输完一个数直接按=;
                middle_flag=0;  //中间运算标志标志清零
                f=a+b;//存放最终运算结果
                a=f;  //把结果保存到a
                sprintf(num1,"%10.2f",f ); //转换成字符串
                EDIT_SetText(hEdit,num1);   //显示出来
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 115:   //小数点按下
                  strcat(num1,".");
                EDIT_SetText(hEdit,num1);   //显示出来
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 116:  //删除键按下
                  len=strlen(num1);
                num1[len-1]='\0'; //删掉最后一个字符
                EDIT_SetText(hEdit,num1);   //显示出来
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;  
            case 117:  //清零键按下——所有都清零
                  len=strlen(num1);
                for(i=0;i<len;i++)
            {
                num1[i]='\0';
            }
                len=strlen(num2);
                for(i=0;i<len;i++)
            {
                num2[i]='\0';
            }
                    len=strlen(temp1);
                for(i=0;i<len;i++)
            {
                temp1[i]='\0';
            }
                    len=strlen(temp2);
                for(i=0;i<len;i++)
            {
                temp2[i]='\0';
            }           
                a=b=0;
                    middle_flag=0; //中间运算符标志
                    f=0.0; //存放最终结果

                EDIT_SetText(hEdit,num1);   //显示出来
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;              
            default:
                break;
        }
    }

        /**************************************************************/
    if(middle_flag==1) //中间运算符已经按下过一次,那么第二次按下的运算符不管是不是等号,都起到等号的作用
                {
                    switch(GUI_GetKey())
                        {  
                        case 100:
                            strcat(num1,"0"); //num1数组加上字符0
                          strcat(num2,"0"); //num2数组加上字符0   

                          strcpy(temp2,num2); 
                      b=atof(temp2);  

                          EDIT_SetText(hEdit,num1); //最后显示还是用num1
                          BEEP=1;     //每次按键都会有蜂鸣器响声,表示按键动作的进行
                          delay_ms(10);
                        BEEP=0;
                        break;
                        case 101:
                            strcat(num1,"1"); 
                          strcat(num2,"1"); 

                          strcpy(temp2,num2); 
                      b=atof(temp2); 

                    EDIT_SetText(hEdit,num1);   
                        BEEP=1;   
                        delay_ms(10);
                        BEEP=0;
                        break;
                        case 102:
                            strcat(num1,"2"); 
                          strcat(num2,"2"); 

                            strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
                        case 103:
                            strcat(num1,"3"); 
                          strcat(num2,"3");

                            strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
                        case 104:
                            strcat(num1,"4"); 
                          strcat(num2,"4"); 

                            strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
                        case 105:
                            strcat(num1,"5"); 
                          strcat(num2,"5"); 

                          strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
                        case 106:
                            strcat(num1,"6"); 
                          strcat(num2,"6"); 

                            strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
                        case 107:
                            strcat(num1,"7"); 
                          strcat(num2,"7");

                            strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
                        case 108:
                            strcat(num1,"8"); 
                          strcat(num2,"8"); 

                            strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
                        case 109:
                            strcat(num1,"9"); 
                          strcat(num2,"9"); 

                            strcpy(temp2,num2); 
                      b=atof(temp2); 

                            EDIT_SetText(hEdit,num1);   
                            BEEP=1;   
                            delay_ms(10);
                            BEEP=0;
                        break;
            case 114:
                middle_flag=0;  //中间运算标志标志清零
            switch(Type)
            {
                case 1:  //加法运算
                    f=a+b;
                break;
                case 2:  
                    f=a-b;
                break;
                case 3:  
                    f=a*b;
                break;
                case 4:  
                    f=a/b;
                break;      
                default:
        break;                  
            }
                middle_flag=0;  //中间运算标志标志清零
                    sprintf(num1,"%10.2f",f ); //转换成字符串
                EDIT_SetText(hEdit,num1);   //显示出来
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 115:   //小数点按下
                  strcat(num1,".");
                EDIT_SetText(hEdit,num1);   //显示出来
                    strcat(num2,".");                       
                    strcpy(temp2,num2); 
                  b=atof(temp2);
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;
            case 116:  //删除键按下
                  len=strlen(num1);
                num1[len-1]='\0'; //删掉最后一个字符
                EDIT_SetText(hEdit,num1);   //显示出来

                    len=strlen(num2);
                num2[len-1]='\0'; //删掉最后一个字符
                //temp也要删,不然会出错
                    strcpy(temp2,num2); 
                  b=atof(temp2);

                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;  
            case 117:  //清零键按下——所有都清零
                  len=strlen(num1);
                for(i=0;i<len;i++)
            {
                num1[i]='\0';
            }
                len=strlen(num2);
                for(i=0;i<len;i++)
            {
                num2[i]='\0';
            }
                    len=strlen(temp1);
                for(i=0;i<len;i++)
            {
                temp1[i]='\0';
            }
                    len=strlen(temp2);
                for(i=0;i<len;i++)
            {
                temp2[i]='\0';
            }           
                a=b=0;
                    middle_flag=0; //中间运算符标志
                    f=0.0; //存放最终结果
                EDIT_SetText(hEdit,num1);   //显示出来
                    BEEP=1;   
                    delay_ms(10);
                    BEEP=0;
                    break;              
            default:
                break;
        }
    }
}
}

程序的不足
1、自己规定输出数据小数只能是2位,而且无意义的0无法去掉。
2、只能一次运算2个数,多了就出错。
3、即使运算2个数之后,将得数作为新的运算数再进行运算也会出错——必须按下AC(清零)。然后重新一次运算2个数,才不会出错。
4、就这样吧,主要是编一个界面。

猜你喜欢

转载自blog.csdn.net/u014751607/article/details/72722629