zoukankan      html  css  js  c++  java
  • STM32移植uCGUI+触摸屏显示,没有加入uCOS Ⅱ

    实验板子 ——李想STM32开发板   

    开发工具—— keil uVision5.0 for MDK

    本次终极任务为显示示波器的GUI界面,此文章只是简单总结移植uCGUI+触摸屏,之后会加入视窗管理器及uCOSⅡ。

    下面说说移植步骤,会穿插一些个人简单的理解,为像我一样的新手提供方便。

    步骤分为三大步:

    一、移植uCGUI  

    二、显示汉字    

    三、移植触摸屏

    一、移植uCGUI

    1、建立工程模版。

    个人会先建立一个工程模板,里边只包含系统的一些文件,主函数是while(1);的循环。每次项目用到就直接复制,添加文件即可。(假设大家都知道在工程中正确添加.c与.h文件的方法)工程目录如下:

                                         

    CMSIS——CM3中断相关及启动的文件

    delay——延时相关的文件(大多数工程都需要。因此放在顶层目录了)

    library——ST提供的各种库文件分为inc和src两个文件夹

    MDK-ARM——编译产生的中间文件即输出文件

    my_driver——自己的驱动文件主要是彩屏驱动文件、个人字库文件和其他工程需要的文件,如spi、iic相关文件

    USER——main.c及其它未添加的库文件

    2、添加彩屏驱动。

    每个人的开发板配套的彩屏及驱动芯片都不一定一样,要根据自己的情况,保证在没移植uCGUI之前情况下,彩屏能够正常显示任意能显示的图案,(不一定要显示汉字)。此处使用李想stm32教程STM32 理想智芯科技(库函数)里的ILI93xx.c文件,将其头文件LCD.h改名为ILI93xx.h文件。并将STM32 理想智芯科技(库函数)里的mian文件替换到工程,删除修改不必要的头文件,删除主函数的全部内容。

    主要应包含三个函数:

    1)彩屏初始化文件 LCD_MyInit() ;由原来ILI93xx.c里的LCD_Init()更改名称而来;

    2)画点函数,原函数LCD_DrawPoint();因为要横屏显示更改为如下模式:竖屏保留原来的函数

    void LCD_DrawPoint(u16 x,u16 y,u16 color)
    {

    LCD_WriteReg(0x004e,239-y); 
    LCD_WriteReg(0x004f,x); 
    LCD_WR_REG(0x22); //LCD_WriteCMD(GRAMWR);

    LCD_WR_DATA(color);
    }

    3)读点函数,返回设定坐标点的颜色值。即ILI93xx.c文件里的LCD_ReadPoint();

    三、下载uCGUI的源码。

    本次使用的是3.98的版本,uCGUI的文件目录如下。可以只移植自己需要的文件,怕麻烦或者工程最后会用到的文件也可以全部添加进去。

                  

    将uCGUI源码中的config及GUI文件夹复制到工程目录,添加需要的.c文件以及.h文件的目录。完成如下:

    4、配置uCGUI文件

    1)打开config下的LCDConf.h,全部注释,改为如下内容(显示为横屏模式)

    #ifndef LCDCONF_H
    #define LCDCONF_H

    /*********************************************************************
    *
    *                   General configuration of LCD
    *
    **********************************************************************
    */

    #define LCD_XSIZE (320) /* X-resolution of LCD, Logical coor. *///竖屏改为240
    #define LCD_YSIZE (240) /* Y-resolution of LCD, Logical coor. *///竖屏改为320


    #define LCD_BITSPERPIXEL (16) //16位色
    #define LCD_CONTROLLER (-1) //缺省驱动(即采用自己的驱动函数)
    #define LCD_FIXEDPALETTE (565) //调色板565格式
    #define LCD_SWAP_RB (1) //红蓝反色交换
    #define LCD_INIT_CONTROLLER()     LCD_MyInit() ; //LCD_MyInit();为你自己的彩屏初始化函数4

    2)修改GUIConf.h文件

    #ifndef GUICONF_H
    #define GUICONF_H

    #define GUI_OS (0) /* Compile with multitasking support */ //操作系统的支持
    #define GUI_SUPPORT_TOUCH (1) /* Support a touch screen (req. win-manager) */ // 触摸屏
    #define GUI_SUPPORT_MOUSE (1)//鼠标
    #define GUI_SUPPORT_UNICODE (1) /* Support mixed ASCII/UNICODE strings */ //UNICODE支持,显示汉字

    #define GUI_DEFAULT_FONT &GUI_Font6x8 //GUI默认字体
    #define GUI_ALLOC_SIZE 5000 /* Size of dynamic memory ... For WM and memory devices*///动态内存

    /*********************************************************************
    *
    * Configuration of available packages
    */

    #define GUI_WINSUPPORT 1 /* Window manager package available */ //´窗口控件支持
    #define GUI_SUPPORT_MEMDEV 1 /* Memory devices available */ //内存设备支持
    #define GUI_SUPPORT_AA 0 /* Anti aliasing available */ //抗锯齿形。打开刷新速率会差

    #endif /* Avoid multiple inclusion */

    3)替换uCGUI函数体:

    因为uCGUI的显示是基于点的显示,即uCGUI会调用你自己驱动的画点操作完成图案的显示,因此需要将为我们的三个主要的驱动函数复制到uCGUI的内部。

    I、打开LCDDriver下的LCDDummy.c文件将LCD_L0_SetPixelIndex的函数体该为LCD_DrawPoint(x,y,PixelIndex);

    II、将LCD_L0_GetPixelIndex的函数体该为return LCD_ReadPoint(x,y);并且包含ILI93xx.h

    III、修改主函数

    RCC_Configuration();
    GPIO_Configuration();
    delay_init(72);
    GUI_Init();
    GUI_SetBkColor(GUI_BLUE);
    GUI_SetColor(GUI_RED);
    GUI_DispStringAt("Hello My World! ",150,150);

    5、编译下载,即可横屏显示。

    二、显示汉字

    汉字的显示需要字库文件,标准字库文件太大,很多字体都用不到,会浪费很大的内存空间。因此一般选择定制自己的字库。一个小软件ucgui_font.exe。

    1、打开软件,之后选择字体,选择你所需要的字体格式,确定,在文本框输入自己定义的字体名称,不能含中文,指定范围导出GBK码,输入你需要显示的汉字字符,确定等待完成。之后文件夹会多一个文件。比如将字体名称定义为My_Font,包含“汉字显示测试”几个文字,会产生一个My_Font.c的文件,将文件复制到工程目录,添加进Font目录。

    2、复制extern GUI_FLASH const GUI_FONT GUI_FontHZ_My_Font;

    改为extern const GUI_FONT GUI_FontHZ_My_Font;

    3、修改主函数

    RCC_Configuration();
    GPIO_Configuration();
    delay_init(72);
    GUI_Init();
    GUI_SetBkColor(GUI_BLUE);
    GUI_SetColor(GUI_RED);
    GUI_DispStringAt("Hello My World! ",150,150);
    GUI_SetFont(&GUI_FontHZ_My_Font);
    GUI_DispStringAt("汉字显示测试",50,50);

    4、编译下载,显示成功

    三、移植触摸屏

    1、将智芯一号触摸屏测试程序中的LIXIANG文件夹下的按需要添加到工程,如:

                          

    2、修改配置及驱动文件

    1)因为原工程为寄存器版本,现在为库函数版本,将所有的头文件stm32f10x_lib.h改为stm32f10x.h

    2)将sys.c文件下

    MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)

    函数最后一句IPR改为IP即NVIC->IP[IPRADDR]|=temp<<IPROFFSET;//设置响应优先级可抢占优先级

    在touch.c文件中,将 MY_NVIC_Init(2,0,EXTI1_IRQChannel,2);改为MY_NVIC_Init(2,0,EXTI1_IRQn,2);

    3)因为横屏驱动,将touch.c文件下Drow_Touch_Point(u8 x,u16 y);改为Drow_Touch_Point(u16 x,u8 y);并且

    修改相应的声明,Draw_Big_Point(u8 x,u16 y)函数同理,并且这两个函数的函数体可以改为使用uCGUI画,比如将LCD_DrawLine(x-12,y,x+13,y);//横线      

     改为LCD_L0_DrawHLine(x-12,y,x+13);//横线

    4)因为没有移植ucosⅡ,不支持任务,需要靠GUI_TOUCH_Exec() 这个函数是定时刷新,驱动函数获取坐标值重绘窗口。即设置完窗口,并不会马上生效,必须重绘才能显示。

    因此在定时器中断EXTI1_IRQHandler中加入GUI_TOUCH_Exec();实现坐标获取。

    5)横屏显示,LCD坐标的系数及偏移需要重新设置,并且实际检测中,右上角触屏不灵敏,校准出现失败,因此将较准点改到屏幕中间部分在Touch_Adjust中

    将屏幕上现实的四个点坐标改为  (50,50),(270,50),(50,190),(270,190)

    并且将

    Pen_Point.xfac=(float)200/(pos_temp[1][0]-pos_temp[0][0]);
    Pen_Point.xoff=(240-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;
    Pen_Point.yfac=(float)280/(pos_temp[2][1]-pos_temp[0][1]);
    Pen_Point.yoff=(320-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;

     改为

    Pen_Point.xfac=(float)220/(pos_temp[1][0]-pos_temp[0][0]);
    Pen_Point.xoff=(320-Pen_Point.xfac*(pos_temp[1][0]+pos_temp[0][0]))/2;
    Pen_Point.yfac=(float)140/(pos_temp[2][1]-pos_temp[0][1]);
    Pen_Point.yoff=(240-Pen_Point.yfac*(pos_temp[2][1]+pos_temp[0][1]))/2;

    6)在GUI_X_Touch.c改为如下程序:

    #include "GUI.h"
    #include "GUI_X.h"
    #include "touch.h"

    void GUI_TOUCH_X_ActivateX(void) {

    }

    void GUI_TOUCH_X_ActivateY(void) {
    }
    /***************************************

    *******************************************/
    int GUI_TOUCH_X_MeasureX(void) {

    u16 x,y;
    Read_ADS2(&x,&y);
    return x;
    }

    int GUI_TOUCH_X_MeasureY(void) {
    u16 x,y;
    Read_ADS2(&x,&y);
    return y;
    }

    7)main文件改为

    #include "stm32f10x.h"
    #include <stdio.h>
    #include "delay.h"
    #include "ILI93xx.h"
    #include "gui.h"
    #include "touch.h"
    #include "24cxx.h"

    //const unsigned char my_space[]="自定义汉字库";
    /*************************************************
    函数名称:  void RCC_Configuration(void)
    函数功能: 复位及时钟配置
    参数:无
    返回:无

    **************************************************/
    void RCC_Configuration(void)
    {
    ErrorStatus HSEStartUpStatus; 
    RCC_DeInit(); 
    RCC_HSEConfig(RCC_HSE_ON); 
    HSEStartUpStatus = RCC_WaitForHSEStartUp(); 
    if(HSEStartUpStatus == SUCCESS)
    {
    FLASH_PrefetchBufferCmd(FLASH_PrefetchBuffer_Enable);
    FLASH_SetLatency(FLASH_Latency_2); 

    RCC_HCLKConfig(RCC_SYSCLK_Div1); 
    RCC_PCLK2Config(RCC_HCLK_Div1); 
    RCC_PCLK1Config(RCC_HCLK_Div2);

    RCC_PLLConfig(RCC_PLLSource_HSE_Div1, RCC_PLLMul_9); 
    RCC_PLLCmd(ENABLE); 

    while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET) 
    {
    }
    RCC_SYSCLKConfig(RCC_SYSCLKSource_PLLCLK);
    while(RCC_GetSYSCLKSource() != 0x08) 
    {
    }
    }

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE, ENABLE);  

    }

    /*************************************************

    函数名称: void GPIO_Configuration(void)
    函数功能:GPIO配置
    参数:无
    返回:无
    **************************************************/
    void GPIO_Configuration(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure; 


    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15 ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_Init(GPIOD, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_All ;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode =GPIO_Mode_Out_PP ;
    GPIO_Init(GPIOE, &GPIO_InitStructure);
    }

    /*************************************************

    函数名称: void GPIO_Configuration_key(void)
    函数功能:按键配置
    参数:无
    返回:无
    **************************************************/

    void GPIO_Configuration_key(void)
    {
    GPIO_InitTypeDef GPIO_InitStructure;

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;
    GPIO_Init(GPIOD, &GPIO_InitStructure); /* PC6 */
    }

    void Load_Drow_Dialog(void)
    {
    LCD_Clear(WHITE);//清屏,白色  
    GUI_SetFont(&GUI_FontHZ_My_Font);
    GUI_SetColor(GUI_RED);
    GUI_DispStringAt( "清除",0,0); //需要添加汉字字库
    // POINT_COLOR=RED;//设置画笔颜色
    }


    /*************************************************
    函数名称: int main(void)
    函数功能: main主函数
    参数:无
    返回:无
    **************************************************/
    int main(void)
    {
    RCC_Configuration();
    GPIO_Configuration();
    delay_init(72);
    GUI_Init();
    Touch_Init();
    delay_ms(1500);
    Load_Drow_Dialog();

    GPIO_Configuration_key();
    while(1)
    {
    if(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_7) == Bit_RESET)
    {
    delay_ms(10);
    if(GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_7) == Bit_RESET)
    {
    Touch_Adjust(); //屏幕校准
    Save_Adjdata();
    Load_Drow_Dialog();
    }
    while((GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_7) == Bit_RESET));
    }
    else if(Pen_Point.Key_Sta==Key_Down)//触摸屏被按下
    {
    Pen_Int_Set(0);//关中断
    do
    {
    Convert_Pos();
    Pen_Point.Key_Sta=Key_Up;
    if(Pen_Point.X0<40&&Pen_Point.Y0<20)Load_Drow_Dialog();//清除
    else
    {
    Draw_Big_Point(Pen_Point.X0,Pen_Point.Y0);//画图 
    GPIOC->ODR|=1<<1; //pc1上拉   
    }
    }while(PEN==0);//若PEN一直有效,则一直执行
    Pen_Int_Set(1);//开启中断
    }else delay_ms(10);

    }
    }

    7)编译下载,触摸屏能用了。

      后续会加入视窗管理及ucos Ⅱ,希望能给初学者参考。

  • 相关阅读:
    JDK5并发(5) Semaphore
    JDK5并发(2) Locks-ReentrantLock
    Java Thread.interrupt interrupted
    Java Magic. Part 4: sun.misc.Unsafe
    Java Magic. Part 3: Finally
    Java Magic. Part 2: 0xCAFEBABE
    JDK5并发(1) Locks-AQS
    JDK Timer & TimerTask
    Git reset head revert 回滚
    c#解析Josn(解析多个子集,数据,可解析无限级json)
  • 原文地址:https://www.cnblogs.com/soloman/p/3959511.html
Copyright © 2011-2022 走看看