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 Ⅱ,希望能給初學者參考。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM