前言
软件要求:Keil MDK v5.24
硬件要求:STM32F429I Discovery开发板
创建工程
打开Keil MDK,创建一个名称为:STM32F429_LedGUI的项目。
选择芯片
处理器选择:STM32F429ZITx。
配置工程
在“Manager Run-Time Environment”中选择好“DeviceàStartup”和“DeviceàSTM32Cube FrameworkàClassic”
选择“Board SupportàLED(API)àLED”, “Board SupportàTouchscreen(API)àTouchscreen”,“Board SupportàemWin LCD(API)àemWin LCD”,再点击“Resolve”完成相关组件的添加
选择“GraphicsàInput DevideàTouchscreen”和 “GraphicsàToolsàGUIBuilder”组件
编写代码
使用模板
添加工程的主控程序:main.c
添加GUI文件
添加一个GUI的控制线程文件:GUI_SingleThread.c
初始化LED引脚
在“main.c”中引用“Board_LED.h”头文件,调用“LED_Initialize”函数,并申明一下“Init_GUIThread”程序,调用该程序,保存工程
编写用户代码
在“GUI_SingleThread.c”中添加如下语句:GUI_DispString(“Hello World!”)
注:设置线程的优先级别设为: osPriorityNormal.如: osThreadDef (GUIThread, osPriorityNormal, 1, 2048)
编写LCD屏驱动代码
打开“system_stm32f4xx.c”文件,在如下图的位置
添加如下LCD驱动代码
#if defined (STM32F429I_DISCOVERY)
/* Enable GPIOB, GPIOC, GPIOD, GPIOE, GPIOF and GPIOG interface
clock */
RCC->AHB1ENR |= 0x0000007E;
/* Connect PBx pins to FMC Alternate function */
GPIOB->AFR[0] = 0x0CC00000;
GPIOB->AFR[1] = 0x00000000;
/* Configure PBx pins in Alternate function mode */
GPIOB->MODER = 0x00002800;
/* Configure PBx pins speed to 50 MHz */
GPIOB->OSPEEDR = 0x00002800;
/* Configure PBx pins Output type to push-pull */
GPIOB->OTYPER = 0x00000000;
/* No pull-up, pull-down for PHx pins */
GPIOB->PUPDR = 0x00000000;
/* Connect PCx pins to FMC Alternate function */
GPIOC->AFR[0] = 0x0000000C;
GPIOC->AFR[1] = 0x00000000;
/* Configure PCx pins in Alternate function mode */
GPIOC->MODER = 0x00000002;
/* Configure PCx pins speed to 50 MHz */
GPIOC->OSPEEDR = 0x00000002;
/* Configure PCx pins Output type to push-pull */
GPIOC->OTYPER = 0x00000000;
/* No pull-up, pull-down for PIx pins */
GPIOC->PUPDR = 0x00000000;
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x000000CC;
GPIOD->AFR[1] = 0xCC000CCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xA02A000A;
/* Configure PDx pins speed to 50 MHz */
GPIOD->OSPEEDR = 0xA02A000A;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00000CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA800A;
/* Configure PEx pins speed to 50 MHz */
GPIOE->OSPEEDR = 0xAAAA800A;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0x00CCCCCC;
GPIOF->AFR[1] = 0xCCCCC000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0x00CC00CC;
GPIOG->AFR[1] = 0xC000000C;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x80020A0A;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0x80020A0A;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FMC Configuration ------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Configure and enable SDRAM bank2 */
FMC_Bank5_6->SDCR[0] = 0x00002C00;
FMC_Bank5_6->SDCR[1] = 0x000001D4;
FMC_Bank5_6->SDTR[1] = 0x01010361;
FMC_Bank5_6->SDTR[0] = 0x00106000;
/* SDRAM initialization sequence */
/* Clock enable command */
FMC_Bank5_6->SDCMR = 0x00000009;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index<1000; index++);
/* PALL command */
FMC_Bank5_6->SDCMR = 0x0000000A;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
FMC_Bank5_6->SDCMR = 0x0000006B;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
FMC_Bank5_6->SDCMR = 0x0004620C;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR;
FMC_Bank5_6->SDRTR = (tmpreg | (1292<<1));
/* Disable write protection */
tmpreg = FMC_Bank5_6->SDCR[1];
FMC_Bank5_6->SDCR[1] = (tmpreg & 0xFFFFFDFF);
#else
/* 根据需要自行添加其他代码*/
#endif
修改相关宏定义
在MDK的工程C/C++使用全局宏,使用对应芯片功能
界面设计
使用界面设计工具——emWin
打开emWin
从“ToolsàGUIBuilder”打开GUIBuilder工具
设计GUI界面
添加一个Framewin和两个Checkbox,属性如下,保存文件,退出GUIBuilder
注意:在制作界面时窗体大小,应该按照实际的屏幕大小来设置。
添加GUI文件
把“LEDCtrlDLG.c”文件添加到项目中
打开“GUI_SingleThread.c”文件,引用“dialog.h”头文件,申明“CreateLEDCtrl”函数并调用该函数
打开“LEDCtrlDLG.c”文件,引用“Board_LED.h”头文件
在“LEDCtrlDLG.c”文件中添加如下代码:就是在相关控件的事件中调用LED控制程序来控制LED.
注:这里只是部分代码,你需要找到相应代码然后添加LED控制代码即可
case WM_NOTIFY_PARENT:
Id = WM_GetId(pMsg->hWinSrc);
NCode = pMsg->Data.v;
switch(Id) {
case ID_CHECKBOX_0: // Notifications sent by 'LED0box'
switch(NCode) {
case WM_NOTIFICATION_CLICKED:
// USER START (Optionally insert code for reacting on notification message)
LED_On(0);
// USER END
break;
case WM_NOTIFICATION_RELEASED:
// USER START (Optionally insert code for reacting on notification message)
LED_Off(0);
// USER END
break;
case WM_NOTIFICATION_VALUE_CHANGED:
// USER START (Optionally insert code for reacting on notification message)
// USER END
break;
// USER START (Optionally insert additional code for further notification handling)
// USER END
}
break;
case ID_CHECKBOX_1: // Notifications sent by 'LED1box'
switch(NCode) {
case WM_NOTIFICATION_CLICKED:
// USER START (Optionally insert code for reacting on notification message)
LED_On(1);
// USER END
break;
case WM_NOTIFICATION_RELEASED:
// USER START (Optionally insert code for reacting on notification message)
LED_Off(1);
// USER END
break;
case WM_NOTIFICATION_VALUE_CHANGED:
// USER START (Optionally insert code for reacting on notification message)
// USER END
break;
// USER START (Optionally insert additional code for further notification handling)
// USER END
}
break;
具体如以下截图所示:
配置RTX
打开“RTX_Conf_CM.c”文件,具体设置如下
根据硬件的实际的情况设置好与LCD和Touch相关的端口
配置GUI文件
打开“GUIConf.c”文件,把”GUI_NUMBYTES”设置为:0x4000
添加预定义宏
在项目设置的“C/C++”中设置几个宏:HSE_VALUE=8000000 DATA_IN_ExtSDRAM STM32F429I_DISCOVERY
配置仿真器
在“Debug”中选择“ST-Link Debugger”仿真器
效果
编译工程并下载到目标板,则在目标板上就可以看到LCD上会显示刚才创建的GUI界面,当按到LED0或LED1时,目标板上的LED会点亮