打印
[STM32F4]

【STM32F469I试用】学习记录4.FreeRTOS+STemwin+FatFS(SD)工作建立

[复制链接]
4250|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
pingis58|  楼主 | 2015-12-30 22:31 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 pingis58 于 2015-12-31 22:05 编辑

   虽然功能完成,但有个问题解决不掉。GUI_Init函数在启动任务前调用会使systick中断不触发,请大家帮我分析下。
   为了加快以后的开发速度,及管理自己的框架工程,都般要建立一个自己风格的工程,并容入更多自己需要的驱动框架。在一个平台上日积月累,是一笔财富,减少以后的重复劳动。此次记录自己的移植过程,没有使用STM32CubeMX自动生成,但用的是HAL库,有了STM32CubeF4的文件,省了很多麻烦和驱动移植,直接搬运就OK了。
   建立好这个模板,为随后的多媒体浏览器做准备(TEXT,图片,MP3,视频格式待定)。正好也了解下库及工程的结构。
   STemwin界面的创建先参考上一篇的设计,未完善的后续再完善。https://bbs.21ic.com/icview-1246502-1-1.html
屏幕左上角显示,文件写成功,File system is ok。
板子写完后,读卡器插入脑读出的数据,正好是64个可打印字符的2次循环。
工程链接:stm32f469proj
1,工具准备
获取方式,参见第一篇。所有的驱动及中间件来自STM32CubeF4的压缩包中。
2,初步建立目录
      
    A) BSP文件夹,需要添加板级支持包,此为STM32F469Discovery板,所以复制该文件夹至BSP目录下,如果是自己设计的板子,也添加板级的驱动这里。另外还有LCD及触摸屏组件库
      
  B),Doc文件夹,存放Readme等工程说明类的文档,随后根据需要添加。
  C),Drivers文件夹。
   Drivers/CMSIS   内拷贝下面三图中选中的.c .h 文件。
      
      
      
     Drivers/StartUP中添加 下图选中文件
      
  在Drivers/HAL_Driver 中添加下图两个文件夹
      
    D),STemwin 文件夹,复制下图两个文件夹
   
   STemwin 文件夹下新建lib文件夹,复下图选中的两个文件
   E),FreeRTOS文件夹  复制下图中选中的文件夹
    新建目录portable  添加下图选中文件
   在此文件夹中再添加下面两图文件
  FreeRTOS文件夹下新建目录 src  添加
   F),GUIResource 文件夹中添加LCD显示资源相关的东西。先添加字体
     
   随后我们还有创建主界面图标相关的文件及其他资源都添加在这里。
G),FatFS文件夹添加下图,基本上里面的文件都要,虽然有些是配置支持UNICODE码,不同语言支持的,虽然根据不同配置使用语言不一样,暂时没细看配置全带。
     
   HConfig 存放整个工程的配置文件
   
      
      
    IUser文件夹,是用户应用程序目录,暂时先添加FreeRTOS的示例程序,整个工程通了后,根据自己需要添加界面应用等。
创建inc文件夹,添加
  
     创建src文件夹,添加
  
3,建立模板工程
  工程的创建过程就不细说,主要把包含的文件及要修改的地方做个记录。
  1),在工程属性设置,C/C++ 栏中 Misc Controls 中添加 --c99否则编译会报变量定义在程序后的错
  2),stm32f4xx_hal_conf.h把用到的模块全开了,不然会提示未定议的错误。
     #define HAL_MODULE_ENABLED  
     #define HAL_DMA_MODULE_ENABLED
     #define HAL_DMA2D_MODULE_ENABLED
     #define HAL_FLASH_MODULE_ENABLED
     #define HAL_SRAM_MODULE_ENABLED
     #define HAL_SDRAM_MODULE_ENABLED
     #define HAL_GPIO_MODULE_ENABLED
     #define HAL_I2C_MODULE_ENABLED
     #define HAL_LTDC_MODULE_ENABLED
     #define HAL_DSI_MODULE_ENABLED
     #define HAL_PWR_MODULE_ENABLED
      #define HAL_RCC_MODULE_ENABLED
     #define HAL_SD_MODULE_ENABLED   
     #define HAL_UART_MODULE_ENABLED
     #define HAL_USART_MODULE_ENABLE
     #define HAL_CORTEX_MODULE_ENABLED

  3),main.h中添加
     #include "stm32f4xx_hal.h"
     #include "stm32469i_discovery.h"
     #include "stm32469i_discovery_lcd.h"
     #include "stm32469i_discovery_ts.h"
     #include "stm32469i_discovery_sdram.h"
  4),工程包含的头文件路径都设置到头文件具体路径,所以库中含有相对路径寻找头文件的地方,全去除相对路径
  5),除以下图片中添加文件有选择外,其他的Group下所有的C文件都添加
   
        至此,基本上可编译通过,下载程序,可正常运行。可能还有些小细节遗漏的问题都好找了。
4,创建STemwin线程
        STemwin的界面创建资源参见。https://bbs.21ic.com/icview-1246502-1-1.html
        文件添加:      在GUIResourc文件夹中添加所有的图标,与链接中给的路径一样。原代码文件也在上篇贴子中。
      WindowDLG.c窗体文件放在USER文件夹中,导入工程。
       其他需添加的代码。
1),从STM32F4Cube的STemwin应用工程拷贝初始化代码,新建以下几个函数。添加在main.c中。main.c是上面有解释,是从STM32F4Cube中拷贝的。路径:\stm32cubef4\STM32Cube_FW_F4_V1.10.0\Projects\STM32469I-Discovery\Applications\FreeRTOS\FreeRTOS_ThreadCreation\Src
void init_gui(void)
{
        GUI_Init();

  GUI_SetFont(&GUI_Font32_ASCII);

  GUI_DispStringAt("Starting...", 0, 0);
  
  /* Initialize LCD and LEDs */
  GUI_DispStringAt("Initializing lcd...", 0, 32);
  BSP_Config();
  
  GUI_Initialized = 1;
  
  /* Initialize RTC and Backup */
  GUI_DispStringAt("Initializing rtc and backup...", 0, 64);
  RTC_Init();
  
  /* Activate the use of memory device feature */
  WM_SetCreateFlags(WM_CF_MEMDEV);

  /* Do the calibration if needed */
  CALIBRATION_Check();
}
void BSP_Config(void)
{
        /* Initializes the SDRAM device */
  BSP_SDRAM_Init();
  
  /* Initialize the Touch screen */
  BSP_TS_Init(800, 480);
        //BSP_TS_Init(320, 240);
  
  /* Enable the CRC Module */
  __HAL_RCC_CRC_CLK_ENABLE();
        __HAL_RCC_BKPSRAM_CLK_ENABLE();
        /* Compute the prescaler value to have TIM3 counter clock equal to 10 KHz */
  uwPrescalerValue = (uint32_t) ((SystemCoreClock /2) / 10000) - 1;
  
  /* Set TIMx instance */
  TimHandle.Instance = TIM3;
   
  /* Initialize TIM3 peripheral as follows:
       + Period = 500 - 1
       + Prescaler = ((SystemCoreClock/2)/10000) - 1
       + ClockDivision = 0
       + Counter direction = Up
  */
2)stm32f4xx_it.c 文件也是同main.c相同地方拷贝来,添加代码
void TIM3_IRQHandler(void)
{
  HAL_TIM_IRQHandler(&TimHandle);
}

void LTDC_IRQHandler(void)
{
  HAL_LTDC_IRQHandler(&hltdc_eval);
}
3)添加新的GUI任务文件。添加到Usre文件夹中,并包含。除了维护GUI任务运行,还包含了LCD初始化调和,屏幕校准方面的代码。
uint8_t GUI_Initialized;
extern WM_HWIN CreateWindow(void);
extern void init_gui(void);
void GUI_Thread(void const *argument)
{
  //uint32_t count = 0;  
        (void) argument;
        
        init_gui();
        
        CreateWindow();
  
  for(;;)
  {

                GUI_Exec(); /* Do the background work ... Update windows etc.) */
                osDelay(10); /* Nothing left to do for the moment ... Idle processing */
  }
}

void BSP_Pointer_Update(void)
{
  GUI_PID_STATE TS_State;
  static TS_StateTypeDef prev_state;
  TS_StateTypeDef  ts;
  uint16_t xDiff, yDiff;  
  
  BSP_TS_GetState(&ts);
  
  TS_State.Pressed = ts.touchDetected;
  
  xDiff = (prev_state.touchX[0] > ts.touchX[0]) ? (prev_state.touchX[0] - ts.touchX[0]) : (ts.touchX[0] - prev_state.touchX[0]);
  yDiff = (prev_state.touchY[0] > ts.touchY[0]) ? (prev_state.touchY[0] - ts.touchY[0]) : (ts.touchY[0] - prev_state.touchY[0]);
  
  if((prev_state.touchDetected != ts.touchDetected )||
     (xDiff > 3 )||
       (yDiff > 3))
  {
    prev_state.touchDetected = ts.touchDetected;
   
    if((ts.touchX[0] != 0) &&  (ts.touchY[0] != 0))
    {
      prev_state.touchX[0] = ts.touchX[0];
      prev_state.touchY[0] = ts.touchY[0];
    }
      
    if(CALIBRATION_IsDone())
    {
      TS_State.Layer = 0;
      TS_State.x = CALIBRATION_GetX (prev_state.touchX[0]);
      TS_State.y = CALIBRATION_GetY (prev_state.touchY[0]);
    }
    else
    {
      TS_State.Layer = 0;
      TS_State.x = prev_state.touchX[0];
      TS_State.y = prev_state.touchY[0];
    }
   
    GUI_TOUCH_StoreStateEx(&TS_State);
  }
}
void BSP_Background(void)
{
   /* toggle LED1 each 100ms */
  BSP_LED_Toggle(LED1);
  
  /* Capture input event and update cursor */
  if(GUI_Initialized == 1)
  {
    BSP_Pointer_Update();
  }
}
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
  BSP_Background();
}

  4)在main.c中创建任务,标准的创建,参见示例工作中的代码,随后也开放工程代码。
    osThreadDef(GUI_TASKID, GUI_Thread, osPriorityNormal, 0, 2048);
    GUIThreadHandle  = osThreadCreate (osThread(GUI_TASKID), NULL);  
   至此,整个工程创建完。已有上贴中的显示效果。走了点弯路。一开始中断忘添了,代码跑飞,找方向找错了,死在启动代码的空中断中死循环。GUI的初始化代码,在启动任务前调用了,也导至死掉,还没解决,看贴头指示,重开一贴请教各位。
5,添加FatFS代码
  1)头文件
#include "ff_gen_drv.h"
#include "sd_diskio.h"

  2)在static void SystemClock_Config(void)中添加时钟初始化部分。在HAL_PWREx_EnableOverDrive()后添加
 RCC_PeriphCLKInitTypeDef RCC_PeriphClkInitStruct;
3)测试代码
FATFS SDFatFs;  /* File system object for SD disk logical drive */
FIL MyFile;     /* File object */
char SDPath[4]; /* SD disk logical drive path */
uint8_t wtext[128];
int FatFS_Init(void)
{
        int i;
        FRESULT res;
        /*##-1- Link the SD disk I/O driver ########################################*/
  if(FATFS_LinkDriver(&SD_Driver, SDPath) == 0)
  {
    /*##-2- Register the file system object to the FatFs module ##############*/
    if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) != FR_OK)
    {
      /* FatFs Initialization Error */
      return -1;
    }
    else
    {
      /*##-3- Create a FAT file system (format) on the logical drive #########*/
      if(f_mkfs((TCHAR const*)SDPath, 0, 0) != FR_OK)
      {     
        return -1;
      }
    }
  }else
        {
                return -1;
        }

        /*##-4- Create and Open a new text file object with write access #####*/
                if(f_open(&MyFile, "test.bin", FA_CREATE_ALWAYS | FA_WRITE) != FR_OK)
                {
                        return -1;
                }
                else
                {
                        for(i=0;i<128;i++)
                        {
                                wtext[i] =(i%64) + 0x30;
                        }
                        /*##-5- Write data to the text file ################################*/
                        res = f_write(&MyFile, wtext, sizeof(wtext), (void *)&i);
                        
                        if((i != sizeof(wtext)) || (res != FR_OK))
                        {
                                /* 'STM32.TXT' file Write or EOF Error */
                                return -1;
                        }
                        f_close(&MyFile);
                }
                return 0;
}
4)调用
    初始化时调用 。file_isok = FatFS_Init();
    进主界面时候显示成功或失败,即在WindowDLG.c中,添加位置在
switch (pMsg->MsgId) {
                case WM_PAINT:
                        //hItem = WM_GetDialogItem(pMsg->hWin, ID_IMAGE_0);
                        //pData = _GetImageById(ID_IMAGE_0_IMAGE_0, &FileSize);
                        //IMAGE_SetBMP(hItem, pData, FileSize);
                        GUI_DrawBitmap(&bmdesk,0,0);
                        GUI_SetFont(&GUI_Font24_ASCII);
                        GUI_SetColor(GUI_WHITE);
                        GUI_SetTextMode(GUI_TEXTMODE_TRANS);
                  if(file_isok == 0)
                        {
                                GUI_DispStringAt("File system is ok", 0, 0);
                        }
                        else
                        {
                                GUI_DispStringAt("File system is not ok", 0, 0);
                        }
                        break;
整个工程18M太大了,分享百度网盘链接
stm32f469proj


沙发
玛尼玛尼哄| | 2015-12-30 22:58 | 只看该作者
看了楼主的另外一个帖子,感觉不错,没想到,又一贴这么给力的,搬个板凳,继续看楼主讲课。

使用特权

评论回复
板凳
pingis58|  楼主 | 2015-12-31 20:56 | 只看该作者
调式过程中遇到个问题,已在这贴最开头描述,GUI_Init在启动任务头调和会使systick 中断不工作,详细描述请见https://bbs.21ic.com/icview-1252738-1-1.html,请大家帮忙分析下,查了两天找不到问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

21

主题

131

帖子

3

粉丝