您的位置 首页 资料

STM32–USB具体使用说明

说明:使用的是STM32F103ZET6硬件原理图在开始枚举设备的一些初始化voidbsp_USBInit(void){GPIO_InitTypeDefGPIO_InitS

阐明:运用的是STM32F103ZET6

硬件原理图

在开端枚举设备的一些初始化

void bsp_USBInit(void)
{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_USB_PULL_UP, ENABLE);

USB_CABLE_DISABLE();

GPIO_InitStructure.GPIO_Pin = PIN_USB_PULL_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOB, &GPIO_InitStructure);

{
NVIC_InitTypeDef NVIC_InitStructure;

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
NVIC_InitStructure.NVIC_IRQChannel = USB_LP_CAN1_RX0_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
}

RCC_USBCLKConfig(RCC_USBCLKSource_PLLCLK_1Div5);

RCC_APB1PeriphClockCmd(RCC_APB1Periph_USB, ENABLE);

USB_Init();

}

现在开端剖析真实的初始化

第一步:初始化,总线复位及向默许地址 0发送 GET_DESCRIPTOR 指令包,恳求设备描绘

1)Index[4 – 5]:表明 USB刺进总线复位;

2)Index[7 – 8]:表明主机向默许地址发送GET_DESCRIPTOR指令包,详细信
息也抓出来了,如(图二)所示

3)Index[15 – 17]:表明设备向主机发送设备描绘数据 Index[16]
4)Index[18 – 19]:表明主机完结 GET_DESCRIPTOR指令后,给设备发送一个
空应对

现在详细的剖析103的usb的履行进程 按次序向下履行

***************(1)**************

DEVICE_INFO *pInformation;

DEVICE_PROP *pProperty;

DEVICE_PROP Device_Property =
{
Joystick_init,
Joystick_Reset,
Joystick_Status_In,
Joystick_Status_Out,
Joystick_Data_Setup,
Joystick_NoData_Setup,
Joystick_Get_Interface_Setting,
Joystick_GetDeviceDescriptor,
Joystick_GetConfigDescriptor,
Joystick_GetStringDescriptor,
0,
0x40
};

USER_STANDARD_REQUESTS User_Standard_Requests =
{
Joystick_GetConfiguration,
Joystick_SetConfiguration,
Joystick_GetInterface,
Joystick_SetInterface,
Joystick_GetStatus,
Joystick_ClearFeature,
Joystick_SetEndPointFeature,
Joystick_SetDeviceFeature,
Joystick_SetDeviceAddress
};

//USB内核将主机发送过来的用于完成USB设备的设置包保存在设备信息结构表中
typedef struct _DEVICE_INFO
{
uint8_t USBbmRequestType;
uint8_t USBbRequest;
uint16_t_uint8_t USBwValues;
uint16_t_uint8_t USBwIndexs;
uint16_t_uint8_t USBwLengths;

uint8_t ControlState;
uint8_t Current_Feature;
uint8_t Current_Configuration;
uint8_t Current_Interface;
uint8_t Current_AlternateSetting;

ENDPOINT_INFO Ctrl_Info;
}DEV%&&&&&%E_INFO;

usb_init.c文件里边的

void USB_Init(void)
{
pInformation = &Device_Info;
pInformation->ControlState = 2;
pProperty = &Device_Property;
pUser_Standard_Requests = &User_Standard_Requests;

pProperty->Init();
}

***************(2)**************经过函数指针指向这个初始化函数pProperty 在usb_prop.c文件里边

void Joystick_init(void)
{

Get_SerialNum();//得到串行号

pInformation->Current_Configuration = 0;//

PowerOn();//将USB上电 衔接设备

USB_SIL_Init();//主要是CNTR寄存器的初始化
bDeviceState = UNCONNECTED;//设备状况标志 当时状况未衔接
}

hw_config.c文件里边 这个和规范的不一样有改动,获取设备版本号,将其存入到版本号字符串。

void Get_SerialNum(void) //得到串行号
{
uint32_t Device_Serial0, Device_Serial1, Device_Serial2;
Device_Serial0 = *(__IO uint32_t*)(0x1FFFF7E8);
Device_Serial1 = *(__IO uint32_t*)(0x1FFFF7EC);
Device_Serial2 = *(__IO uint32_t*)(0x1FFFF7F0);
Device_Serial0 += Device_Serial2;
if (Device_Serial0 != 0)
{
IntToUnicode (Device_Serial0, &Joystick_StringSerial[2] , 8);
IntToUnicode (Device_Serial1, &Joystick_StringSerial[18], 4);
}
}

usb_pwr.c文件里边 在这个文件里边仅仅使能了复位,挂起,唤醒中止,在PowerOn函数使能了复位中止今后,将进入到USB的复位中止里边去。

然后再履行函数USB_SIL_Init 将一切的USB中止都翻开。在D+被接通上拉今后,设备就能被主机检测到。

RESULT PowerOn(void)
{
#ifndef STM32F10X_CL
uint16_t wRegVal;

USB_Cable_Config(ENABLE);//将USB上电衔接

//对USB模块强制复位,类似于USB总线上的复位信号。USB模块将一向坚持在复位状况下
//直到软件铲除此位。假如USB复位中止被使能,将发生一个复位中止。
wRegVal = CNTR_FRES;//强制复位
_SetCNTR(wRegVal);

wInterrupt_Mask = 0;
_SetCNTR(wInterrupt_Mask);//铲除复位信号

_SetISTR(0);

//复位中止屏蔽位 挂起中止屏蔽位 唤醒中止屏蔽位使能
wInterrupt_Mask = CNTR_RESETM | CNTR_SUSPM | CNTR_WKUPM;

_SetCNTR(wInterrupt_Mask);
#endif

return USB_SUCCESS;
}

usb_istr.c文件里边,下面只写了进入到复位中止函数,进入到USB衔接状况

void USB_Istr(void)

{

wIstr = _GetISTR();

#if (IMR_MSK & ISTR_RESET)//USB复位恳求中止
if (wIstr & ISTR_RESET & wInterrupt_Mask)
{
_SetISTR((uint16_t)CLR_RESET);//清楚复位中止标志
Device_Property.Reset();//进入到复位中止
#ifdef RESET_CALLBACK
RESET_Callback();
#endif
}
#end

}

usb_prop.c文件里边,完成对端点的设置。

void Joystick_Reset(void)
{

pInformation->Current_Configuration = 0;
pInformation->Current_Interface = 0;

pInformation->Current_Feature = Joystick_ConfigDescriptor[7];//供电形式挑选

#ifdef STM32F10X_CL

OTG_DEV_EP_Init(EP1_IN, OTG_DEV_EP_TYPE_INT, 4);
#else

SetBTABLE(BTABLE_ADDRESS);//分组缓冲区描绘表地址设置

SetEPType(ENDP0, EP_CONTROL);//初始化为操控端点类型
SetEPTxStatus(ENDP0, EP_TX_STALL); //端点以STALL分组呼应一切的发送恳求。

//也便是端点状况设置成发送无效,也便是主机的IN令牌包来的时分,回送一个STALL。
SetEPRxAddr(ENDP0, ENDP0_RXADDR);//设置端点0描绘符的承受地址,

SetEPTxAddr(ENDP0, ENDP0_TXADDR);//设置端点0描绘符的发送地址

Clear_Status_Out(ENDP0);

//仅用于操控端点 假如STATUS_OUT位被铲除,OUT分组能够包括恣意长度的数据
SetEPRxCount(ENDP0, Device_Property.MaxPacketSize);

//设置端点0的承受字节寄存器的最大值是64
SetEPRxValid(ENDP0);//设置承受端点有用

SetEPType(ENDP1, EP_INTERRUPT);//初始化为中止端点类型
SetEPTxAddr(ENDP1, ENDP1_TXADDR);//设置发送数据的地址
SetEPTxCount(ENDP1, 4);//设置发送的长度
SetEPRxStatus(ENDP1, EP_RX_DIS);//设置承受端点封闭
SetEPTxStatus(ENDP1, EP_TX_NAK);//设置发送端点端点非应对

SetDeviceAddress(0);//设置设备用缺省地址相应
#endif

bDeviceState = ATTACHED;//当时状况衔接
}

usb_sil.c的文件里边,主要是使能了如下这些中止

CNTR_CTRM 正确传输(CTR)中止使能 CNTR_WKUPM 唤醒中止使能
CNTR_SUSPM 挂起(SUSP)中止使能 CNTR_ERRM 出错中止使能
CNTR_SOFM 帧首中止使能 CNTR_ESOFM 希望帧首中止使能CNTR_RESETM 设置此位将向PC主机发送唤醒恳求。依据USB协议,假如此位在1ms到15ms内坚持有用,主机将对USB模块实施唤醒操作。

uint32_t USB_SIL_Init(void)
{
#ifndef STM32F10X_CL

_SetISTR(0);//铲除中止标志
wInterrupt_Mask = IMR_MSK;

//这组寄存器用于界说USB模块的作业形式,中止的处理,设备的地址和读取当时帧的编号
_SetCNTR(wInterrupt_Mask);//设置相应的操控寄存器
#else

OTG_DEV_Init();
#endif

return 0;
}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/ziliao/256777.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部