【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
1、USB_HOST选择Mass Storage Host;
2、FATFS选择 USB Disk;
3、USB_TOG_FS选择Host_Only
这个不是按照配置顺序写的吧??
我比较好奇的是OLED怎么接到这个位置上的?我也想直接查到板子上 本帖最后由 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
wenyangzeng 发表于 2017-4-4 15:05
OLED不是接这里,这些是USB在STM32CubeMXl里的配置
我正在更新OLED插图。OLED接PC8-PC11
...
我好像明白了。vcc/gnd是飞线过去的。scl和sda接在PC8和PC9上了。 斜阳__ 发表于 2017-4-4 16:04
我好像明白了。vcc/gnd是飞线过去的。scl和sda接在PC8和PC9上了。
是的,1楼图片已经修改过。
页:
[1]