wenyangzeng 发表于 2017-4-4 14:35:21

【NUCLEO-L496ZG评测】评测4:USB_FS_OTG

本帖最后由 wenyangzeng 于 2017-4-11 15:41 编辑

【NUCLEO-L496ZG评测】评测1:编译环境建立

【NUCLEO-L496ZG评测】评测2:Coremark跑分

【NUCLEO-L496ZG评测】评测3:低功耗测试

【NUCLEO-L496ZG评测】评测5:过采样ADC

【NUCLEO-L496ZG评测】评测6:可编程运放PGA

【NUCLEO-L469ZG评测】评测4:USB_FS_OTG
   在NUCLEO-L469ZG板上的USB_FS_OTG评测主要参考《STM32CubeMX教程26》进行的。
在STM32CubeMX中的配置已经有许多大侠高手发了帖,也可以参考附件内容,配置过程本贴就不再上图了。主要设置:
1、USB_HOST选择Mass Storage Host;
2、FATFS选择 USB Disk;
3、USB_TOG_FS选择Host_Only
4、系统时钟源选择 MSI RC
5、HCLK设定为80MHZ;
6、To USB时钟设定为48MHZ
7、FATFS Configuration->CODE_PAGE选择Simplified Chinese
8、USE_LFN选择Enabled with dunaic working buffer on the STACK
9、USB_HOST Configuration-Platform Settings配置GPIO:Outpit PG6
10、堆栈设定Happ=0x400,Stack=0x800
   本次评测为NUCLEO-L469ZG开发板配置了OLED显示屏用于USB_HOST操作信息的显示:


按照教程推荐下载ST官方移植文件进行修改

该下载压缩文件有3个文件:
file_operations.c
explorer.c
menu.c
将它们添加进工程中,并针对OLED显示方式进行移植修改。
   编译下载。预先格式化一个U盘,连接到开发板的CN14,运行,首先初始化USB口,成功后会自动在U盘里创建一个“USBHost.txt"的文件。接着读该文件并把文件名在屏幕上显示。


                           启动


                           初始化成功


                         建立文件


                  读取文件名成功并显示
//main.c
#include "main.h"
#include "stm32l4xx_hal.h"
#include "fatfs.h"
#include "usb_host.h"
#include "gpio.h"
#include "oled.h"
void SystemClock_Config(void);
void Error_Handler(void);
void MX_USB_HOST_Process(void);
void LCD_Init(void);
void MSC_MenuProcess(void);
void MX_DriverVbusFS( uint8_t state) ;
volatilelong timer=0;
extern ApplicationTypeDef Appli_state;
FIL PBFile;
FATFS fatfs;
void Menu_Init(void);
int main(void)
{
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USB_HOST_Init();
MX_FATFS_Init();
      MX_DriverVbusFS(0);
      timer=HAL_GetTick();
      LCD_Init();
      Menu_Init();
      if(f_mount(&fatfs, "",0)!=FR_OK)
                {
                LCD_Print(0,20,"Initialize Error",TYPE16X16,TYPE8X16);
                }
                else
                {
                LCD_Print(0,0,"STM32L496-Nucleo",TYPE16X16,TYPE8X16);
                LCD_Print(0,18,"USB_FS_OTG",TYPE16X16,TYPE8X16);
                LCD_Print(0,36,"   DEMO",TYPE16X16,TYPE8X16);      
                }
while (1)
{
    MX_USB_HOST_Process();
      if(HAL_GetTick()-timer>=2000)
         {
         MSC_MenuProcess();
         timer=HAL_GetTick();
         }
    }
}
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
RCC_OscInitStruct.LSEState = RCC_LSE_OFF;
RCC_OscInitStruct.MSIState = RCC_MSI_ON;
RCC_OscInitStruct.MSICalibrationValue = 0;
RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 40;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
    Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4) != HAL_OK)
{
    Error_Handler();
}
PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
PeriphClkInit.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI;
PeriphClkInit.PLLSAI1.PLLSAI1M = 1;
PeriphClkInit.PLLSAI1.PLLSAI1N = 24;
PeriphClkInit.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
PeriphClkInit.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_48M2CLK;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
    Error_Handler();
}
if (HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1) != HAL_OK)
{
    Error_Handler();
}
HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
HAL_RCCEx_EnableMSIPLLMode();
HAL_NVIC_SetPriority(SysTick_IRQn, 0, 0);
}


//MENU.C
#include "stm32l4xx_hal.h"
#include "usbh_msc.h"
#include "OLED.h"
#include "usb_host.h"
#include "ff.h"
#include "gpio.h"
typedef enum {
MSC_DEMO_START = 0,
MSC_DEMO_FILE_OPERATIONS,
MSC_DEMO_EXPLORER,
}MSC_Demo_State;
typedef struct _DemoStateMachine {
__IO MSC_Demo_State state;
__IO uint8_t      select;
}MSC_DEMO_StateMachine;
MSC_DEMO_StateMachine msc_demo;
extern ApplicationTypeDef Appli_state;
extern void MSC_File_Operations(void);
extern FRESULT Explore_Disk(char *path, uint8_t recu_level);
void Menu_Init(void)

msc_demo.state = MSC_DEMO_START;
}
void MSC_MenuProcess(void)
{
switch(msc_demo.state)
{
case MSC_DEMO_START:
    if(Appli_state == APPLICATION_READY)
    {
                        LCD_CLS();
                        LCD_Print(0,20,"USBHost Init OK!",TYPE16X16,TYPE8X16);
                        HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_7);
                        HAL_Delay(400);
                        HAL_Delay(400);
      msc_demo.state = MSC_DEMO_FILE_OPERATIONS;
    }
    break;
   
case MSC_DEMO_FILE_OPERATIONS:
    if(Appli_state == APPLICATION_READY)
    {
      MSC_File_Operations();
      HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_14);
                        LCD_CLS();
                        LCD_Print(10,30,"Create File",TYPE16X16,TYPE8X16);
      HAL_Delay(400);
                        HAL_Delay(400);
                        HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_7);
      msc_demo.state = MSC_DEMO_EXPLORER;
      HAL_Delay(400);
    }
    break;
case MSC_DEMO_EXPLORER:
    if(Appli_state == APPLICATION_READY)                        
    {
      LCD_CLS();
      Explore_Disk("0:/", 1);

      HAL_Delay(400);
      HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_7);
    }
    break;
   
default:
    break;
}

if(Appli_state == APPLICATION_DISCONNECT)
{
    Appli_state = APPLICATION_IDLE;
                LCD_CLS();
                LCD_Print(0, 0,"MSC device disconnected!",TYPE16X16,TYPE8X16);
               
    msc_demo.state = MSC_DEMO_START;
    msc_demo.select = 0;
}
}

//explorer.c
#include "stm32l4xx_hal.h"
#include "ff.h"
#include "usb_host.h"
#include "oled.h"
#include "gpio.h"
extern USBH_HandleTypeDef hUsbHostFS;
extern ApplicationTypeDef Appli_state;

FRESULT Explore_Disk(char *path, uint8_t recu_level)
{
FRESULT res = FR_OK;
FILINFO fno;
DIR dir;
char *fn;
char tmp;
uint8_t line_idx = 0;
uint8_t i=0;
#if _USE_LFN
static char lfn;   /* Buffer to store the LFN */
fno.lfname = lfn;
fno.lfsize = sizeof lfn;
#endif
res = f_opendir(&dir, path);
if(res == FR_OK)
{
    while(USBH_MSC_IsReady(&hUsbHostFS))
    {
      res = f_readdir(&dir, &fno);
      if(res != FR_OK || fno.fname == 0)
      {
      break;
      }
      if(fno.fname == '.')
      {
      continue;
      }
   
#if _USE_LFN
      fn = *fno.lfname ? fno.lfname : fno.fname;
#else
      fn = fno.fname;
#endif
      strcpy(tmp, fn);
      
      line_idx++;
      if(line_idx > 9)
      {
      line_idx = 0;
      LCD_Print(0,0," Press button",TYPE16X16,TYPE8X16);
         while(HAL_GPIO_ReadPin(GPIOC,GPIO_PIN_13)==0)
      {
      }

      }

      if((fno.fattrib & AM_MASK) == AM_DIR)
      {
                              
      strcat(tmp, "\0");
      LCD_Print(0,0,(void *)tmp,TYPE8X16,TYPE8X16);
      Explore_Disk(fn, 2);
      }
      else
      {
      strcat(tmp, "\0");
      LCD_Print(0,i,(void *)tmp,TYPE8X16,TYPE8X16);

               
      if(((fno.fattrib & AM_MASK) == AM_DIR)&&(recu_level == 2))
      {
      Explore_Disk(fn, 2);
      }
    }
    f_closedir(&dir);
}
return res;
}






http://player.youku.com/player.php/sid/XMjY4NjY4NjY1Mg==/v.swf



开发板介绍
http://www.stmcu.com.cn/Product/pro_detail/cat_code/STM32L4x6/family/81/sub_family/131/sub_child_family/172/layout/product

设计文档
http://www.stmcu.com.cn/Product/pro_detail/cat_code/STM32L4x6/family/81/sub_family/131/sub_child_family/172/layout/design_resource

参考设计
http://www.stmcu.com.cn/Product/pro_detail/cat_code/STM32L4x6/family/81/sub_family/131/sub_child_family/172/layout/APPLICATIONCASE

斜阳__ 发表于 2017-4-4 14:58:56

1、USB_HOST选择Mass Storage Host;
2、FATFS选择 USB Disk;
3、USB_TOG_FS选择Host_Only
这个不是按照配置顺序写的吧??
我比较好奇的是OLED怎么接到这个位置上的?我也想直接查到板子上

wenyangzeng 发表于 2017-4-4 15:05:56

本帖最后由 wenyangzeng 于 2017-4-4 15:11 编辑

斜阳__ 发表于 2017-4-4 14:58
1、USB_HOST选择Mass Storage Host;
2、FATFS选择 USB Disk;
3、USB_TOG_FS选择Host_Only

OLED不是接这里,这些是USB在STM32CubeMXl里的配置
我正在更新OLED插图。OLED接PC8-PC11

斜阳__ 发表于 2017-4-4 16:04:43

wenyangzeng 发表于 2017-4-4 15:05
OLED不是接这里,这些是USB在STM32CubeMXl里的配置
我正在更新OLED插图。OLED接PC8-PC11
...

我好像明白了。vcc/gnd是飞线过去的。scl和sda接在PC8和PC9上了。

wenyangzeng 发表于 2017-4-4 16:31:14

斜阳__ 发表于 2017-4-4 16:04
我好像明白了。vcc/gnd是飞线过去的。scl和sda接在PC8和PC9上了。

是的,1楼图片已经修改过。
页: [1]
查看完整版本: 【NUCLEO-L496ZG评测】评测4:USB_FS_OTG