基于STM32F103的USB学习笔记4 - 初始化
1. IO初始化
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE);
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
//P12: USB DP, P11: USB DM
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
GPIO_Init(GPIOA, &GPIO_InitStructure);
初始化USB Enable的IO口为输出脚
2. USB中断初始化
void usbIntInit(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
/* 2 bit for pre-emption priority, 2 bits for subpriority */
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
/* Enable the USB interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
/* Enable the USB Wake-up interrupt */
NVIC_InitStructure.NVIC_IRQChannel = USBWakeUp_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}
实际USB有3个中断,分别为USB_HP_CAN1_TX_IRQn(USB高优先级中断)、USB_LP_CAN1_RX0_IRQn(USB低优先级中断)和USBWakeUp_IRQn(USB唤醒中断)。
USB_HP_CAN1_TX_IRQn仅由USB同步(Isochronous)模式传输或双缓冲块(Bulk)传输模式下的正确传输事件产生,大部分的例子没有用到,先不考虑使用。
3. 设置USB频率
/* Select USBCLK source */
RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);
/* Enable the USB clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);
4. 调用USB库的API函数USB_Init()
此时编译会有错误提示,undefined reference to `Device_Property'和undefined reference to `User_Standard_Requests'
Device_Property是一个结构,参考例程Custom_HID中建立一个空的结构。
DEVICE_PROP Device_Property =
{
usbClassInit,
usbClassReset,
usbClassStatusIn,
usbClassStatusOut,
usbClassDataSetup,
usbClassNoDataSetup,
usbClassGetInterfaceSetting,
usbClassGetDeviceDescriptor,
usbClassGetConfigDescriptor,
usbClassGetStringDescriptor,
0,
0x40 /*MAX PACKET SIZE*/
};
所有处理的函数都是空的,例如
void usbClassInit(void)
{
}
同样对User_Standard_Requests
USER_STANDARD_REQUESTS User_Standard_Requests =
{
usbClassGetConfiguration,
usbClassSetConfiguration,
usbClassGetInterface,
usbClassSetInterface,
usbClassGetStatus,
usbClassClearFeature,
usbClassSetEndPointFeature,
usbClassSetDeviceFeature,
usbClassSetDeviceAddress
};
编译通过。
5. 在USB库的API函数USB_Init()中可以看到会调用Device_Property的usbClassInit。
参考例程JoyStickMouse中Joystick_init,看起来应该都是一样的处理,
void Joystick_init(void)
{
/* Update the serial number string descriptor with the data from the unique ID*/
Get_SerialNum();
pInformation->Current_Configuration = 0;
/* Connect the device */
PowerOn();
/* Perform basic device initialization operations */
USB_SIL_Init();
bDeviceState = UNCONNECTED;
}
第一步是根据MCU的96位ID生成唯一的Serial Number,然后PowerOn,PowerOn里面会控制USB_EN脚,USB_SIL_Init是初始化端点(EndPoint)的读写。
1. PowerOn是USB IP的上电复位过程。
RESULT PowerOn(void)
{
uint16_t wRegVal;
/*** cable plugged-in ? ***/
USB_Cable_Config(ENABLE);
/*** CNTR_PWDN = 0 ***/
wRegVal = CNTR_FRES;
_SetCNTR(wRegVal);
/* The following sequence is recommended:
1- FRES = 0
2- Wait until RESET flag = 1 (polling)
3- clear ISTR register */
/*** CNTR_FRES = 0 ***/
wInterrupt_Mask = 0;
_SetCNTR(wInterrupt_Mask);
/* Wait until RESET flag = 1 (polling) */
while((_GetISTR()&ISTR_RESET) == 1);
/*** Clear pending interrupts ***/
SetISTR(0);
/*** Set interrupt mask ***/
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
_SetCNTR(wInterrupt_Mask);
return USB_SUCCESS;
}
USB_CNTR是USB控制寄存器(),USB_ISTR是USB中断状态寄存器。
a) PDWN = 0, 退出断电模式;FRES = 1, 强制复位
wRegVal = CNTR_FRES;
_SetCNTR(wRegVal);
wInterrupt_Mask = 0;
_SetCNTR(wInterrupt_Mask);
b) 等待复位结束
while((_GetISTR()&ISTR_RESET) == 1);
c) 清除USB中断
SetISTR(0);
d) 设置USB中断使能,CNTR_WKUPM(唤醒请求)/ CNTR_SUSPM(挂起模块请求)/ CNTR_RESETM(复位中断)
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;
_SetCNTR(wInterrupt_Mask);
2. USB_SIL_Init是初始化USB IP和端点0
uint32_t USB_SIL_Init(void)
{
/* USB interrupts initialization */
/* clear pending interrupts */
_SetISTR(0);
wInterrupt_Mask = IMR_MSK;
/* set interrupts mask */
_SetCNTR(wInterrupt_Mask);
return 0;
}
a) 清除所有中断
_SetISTR(0);
b)设置中断源
wInterrupt_Mask = IMR_MSK;
_SetCNTR(wInterrupt_Mask);
#define IMR_MSK (CNTR_CTRM | CNTR_WKUPM | CNTR_SUSPM | CNTR_ERRM | CNTR_SOFM \
| CNTR_ESOFM | CNTR_RESETM )
设置到这里USB的中断处理函数USB_LP_CAN1_RX0_IRQn已经可以进了。
基于STM32F103的USB学习笔记4 - 初始化相关推荐
- 基于STM32F103的USB学习笔记27 - CustomHID
基于JoyStickMouse例程修改即可. 1. 调整描述符 设备描述符可以不用改. 配置描述符长度改为41,主要是增加一个端点. #define USB_CONFIG_DESC_LEN ...
- 基于STM32F103的USB学习笔记35 - Mass Storage之SCSI命令
参考文档:UFI Command Specification.SCSI Reference Guide CBW包中CB部分(0FH-1EH)的第一个字节是操作码,对于Mass Storage来说,使用 ...
- 基于STM32F103的USB学习笔记38 - Mass Storage之SPI Flash做U盘
1. 将整个Flash作为U盘的空间 Flash大小为4MB,SPI NorFlash的Sector大小为4KB,所以MSC_MEMORY_BLOCK_SIZE设置为4096.. 3个函数的实现如下, ...
- USB学习笔记(4)STM32关于USB库的解读
USB学习笔记(4)STM32关于USB库的解读 为了方便在STM32上实现USB功能,本文对USB库的文件进行解读. USB-FS_Device peripheral interface(外围接口) ...
- USB学习笔记(2)USB协议
USB学习笔记(2)USB协议 本文对前面提到的USB枚举过程中的标准请求以及各种描述符做出大致解释,方便后面的实操. 1. USB标准请求 USB协议定义了一个8字节的标准设备请求,主要用在设备的枚 ...
- 【毕业设计之python系列】基于Flask的在线学习笔记的设计与实现
基于Flask的在线学习笔记的设计与实现 摘要 在线学习笔记系统是一种为学生和教师提供在线学习和教学的平台.本文基于Flask框架,设计并实现了一个在线学习笔记系统.该系统支持用户注册.登录.创建课程 ...
- 统计学习导论 - 基于R的应用 学习笔记1
统计学习导论 - 基于R的应用 学习笔记 Chapter 1 导论 统计学习是什么: 关于估计ƒ的一系列方法 Y=f(x)+ξ f:X 提供给 Y 的系统信息,是 x 的函数 ξ:随机误差项:均值为0 ...
- USB学习笔记(3)HID应用分析
USB学习笔记(3)HID应用分析 本文根据前面对USB系统的了解,和USB协议的学习,列出鼠标,键盘,多媒体控制器,自定义HID设备等HID设备的各种描述符. 前景提要:每个设备有且仅有一个设备描述 ...
- 计算机基础与程序设计(基于C语言)学习笔记
计算机基础与程序设计(基于C语言)学习笔记 前言 这是一个学习笔记 课程导入 在线学习工具:https://c.runoob.com/compile/11 为什么要学习程序设计 (1)存储程序和程序控 ...
最新文章
- FMDatabase常见的几个操作
- 关于Spring的69个面试问答——终极列表
- Java abstract 关键字
- 自定义ProgressBar
- MATLAB可视化实战系列(四十)-基于MATLAB 自带手写数字集的CNN(LeNet5)手写数字识别-图像处理(附源代码)
- cadence 常见pcb电阻_经验分享|高频PCB设计中出现的干扰分析及对策
- 算法与数据结构(python):递归
- html+id选择器如何使用方法,id选择器_HTML+CSS前端基础知识教程_腾讯视频
- Fork_Join - Java多线程编程
- 【Nutch2.2.1基础教程之2.1】集成Nutch/Hbase/Solr构建搜索引擎之一:安装及运行【单机环境】
- 普通html和vue单选框的样式,vue2实现自定义样式radio单选框
- python回车键绑定按钮_python tkinter 绑定回车键
- 信数金服:决策模型的迭代
- 【OpenCV】OpenCV实战从入门到精通之 -- 离散傅里叶变换相关函数详解
- 安卓 dump 工具 影响_工具如何影响文化?
- STM32 编码器的CUBEMX的使用
- qgc地面站如何导入离线地图_如何下载百度地图离线包并导入OruxMaps
- ora 01033 linux,ORA-01033: ORACLE initialization or shutdown in progres
- ZigBee模块无线传输星形拓扑组网结构简介
- DNF检测原理分析篇