你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F446 USB D+和D- speed设置多少合适?

[复制链接]
miraclexue 提问时间:2018-8-3 17:40 /
如题  STM32F446 例程中将USB 的 D+  D-的speed设置成100Mhz,在这里请问:
一、如果配置成USB全速设备,那么将USB 的 D+  D-的speed设置成:
1、2Mhz
2、25Mhz
3、50Mhz
4、100Mhz
以上速度都可以吗,还是部分可以?貌似STM32F1设置成50Mhz就可以了。
二、USB48Mhz的频率,对 D+  D-的速度要求是多少?怎么计算?不同系列芯片和系统主频有没有关系?


收藏 评论4 发布时间:2018-8-3 17:40

举报

4个回答
miraclexue 回答时间:2018-8-3 22:43:09
大神来回答
feixiang20 回答时间:2018-8-3 23:44:30
本帖最后由 feixiang20 于 2018-8-3 23:46 编辑

是不是这样:GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
我看的资料是如下资料,你可以参考下

stm32F4系列库函数版本各模块配置过程
GPIO配置步骤:
  GPIO_InitTypeDef  GPIO_InitStructure;
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);//使能GPIOF时钟
  //GPIOF9,F10初始化设置
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10;//LED0和LED1对应IO口
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//普通输出模式
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHz
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;//上拉
  GPIO_Init(GPIOF, &GPIO_InitStructure);//初始化GPIOF9,F10
可以一次初始化一个IO组下的多个IO,前提是这些IO口的配置方式一样。

按键配置:
使能按键对应IO口时钟。调用函数:
     RCC_AHB1PeriphClockCmd ();//参照GPIO配置过程
初始化IO模式:上拉/下拉输入。调用函数:
     GPIO_Init();//和GPIO配置过程一样
扫描IO口电平(库函数/寄存器/位操作)。
u8 KEY_Scan(u8 mode)
    {
     static u8 key_up=1;
     if(mode==1) key_up=1;//支持连续按
      if(key_up &&  KEY按下)
      {
        delay_ms(10);//延时,防抖
        key_up=0;//标记这次key已经按下
        if(KEY确实按下)
          {
           return KEY_VALUE;
          }
        }else if(KEY没有按下)  key_up=1;
       return 没有按下
    }

端口复用配置过程:
①GPIO端口时钟使能。
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
②复用外设时钟使能。
     比如你要将端口PA9,PA10复用为串口,所以要使能串口时钟。
   RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);
③端口模式配置为复用功能。 GPIO_Init()函数。
   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
④配置GPIOx_AFRL或者GPIOx_AFRH寄存器,将IO连接
    到所需的AFx。

     /*PA9连接AF7,复用为USART1_TX */
    GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1);
    /* PA10连接AF7,复用为USART1_RX*/
   GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1);

例子:

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能GPIOA时钟 ①
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能USART1时钟 ②

//USART1端口配置③
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9与GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA9,PA10
//串口1对应引脚复用映射 ④
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //GPIOA9复用为USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //GPIOA10复用为USART1

中断优先级配置过程:
系统运行后先设置中断优先级分组。调用函数:
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);
整个系统执行过程中,只设置一次中断分组。
针对每个中断,设置对应的抢占优先级和响应优先级:
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct);
如果需要挂起/解挂,查看中断当前激活状态,分别调用相关函数即可。

例子:
typedef struct
{
  uint8_t NVIC_IRQChannel; //设置中断通道
  uint8_t NVIC_IRQChannelPreemptionPriority;//设置响应优先级
  uint8_t NVIC_IRQChannelSubPriority; //设置抢占优先级
  FunctionalState NVIC_IRQChannelCmd; //使能/使能
} NVIC_InitTypeDef;

NVIC_InitTypeDef   NVIC_InitStructure;
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;//串口1中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;// 抢占优先级为1
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;// 子优先级位2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;//IRQ通道使能
NVIC_Init(&NVIC_InitStructure);   //根据上面指定的参数初始化NVIC寄存器

串口配置:
①    串口时钟使能:RCC_APBxPeriphClockCmd();
     GPIO时钟使能:RCC_AHB1PeriphClockCmd();
② 引脚复用映射:
     GPIO_PinAFConfig();
③GPIO端口模式设置:GPIO_Init(); 模式设置为GPIO_Mode_AF
④串口参数初始化:USART_Init();
⑤开启中断并且初始化NVIC(如果需要开启中断才需要这个步骤)
      NVIC_Init();
      USART_ITConfig();
⑥使能串口:USART_Cmd();
⑦编写中断处理函数:USARTx_IRQHandler();
⑧串口数据收发:
void USART_SendData();//发送数据到串口,DR
uint16_t USART_ReceiveData();//接受数据,从DR读取接受到的数据
⑨串口传输状态获取:
FlagStatus USART_GetFlagStatus();
void USART_ClearITPendingBit();

外部中断配置:
使能SYSCFG时钟:
         RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
初始化IO口为输入。
       GPIO_Init();
设置IO口与中断线的映射关系。
        void SYSCFG_EXTILineConfig();
初始化线上中断,设置触发条件等。
       EXTI_Init();
配置中断分组(NVIC),并使能中断。
       NVIC_Init();
编写中断服务函数。
      EXTIx_IRQHandler();
清除中断标志位
      EXTI_ClearITPendingBit();

EXTI_InitStructure.EXTI_Line=EXTI_Line2;   
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;  
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);


独立看门狗配置过程:
1.取消寄存器写保护:
IWDG_WriteAccessCmd();
2.设置独立看门狗的预分频系数,确定时钟:
IWDG_SetPrescaler();
3.设置看门狗重装载值,确定溢出时间:
IWDG_SetReload();
4.使能看门狗
IWDG_Enable();
5.应用程序喂狗:
IWDG_ReloadCounter();
溢出时间计算:
Tout=((4×2^prer) ×rlr) /32 (M4) 注意单位统一
prep:预分频系数 rlr:重装载值
void IWDG_Init(u8 prer,u16 rlr)
{
IWDG_WriteAccessCmd(IWDG_WriteAccess_Enable);

IWDG_SetPrescaler(prer);
IWDG_SetReload(rlr);
IWDG_ReloadCounter();

IWDG_Enable();
}
主函数中设置中断优先级分组,初始化IO;调用IWDG_Init(4,500);  在while中进行喂狗。

窗口看门狗配置:
1.使能看门狗时钟:
RCC_APB1PeriphClockCmd();
2.设置分频系数:
WWDG_SetPrescaler();
3.设置上窗口值:
WWDG_SetWindowValue();
4.开启提前唤醒中断并分组(可选):
WWDG_EnableIT();
NVIC_Init();
5.使能看门狗:
WWDG_Enable();
6.喂狗:
WWDG_SetCounter();
7.编写中断服务函数
WWDG_IRQHandler();
void WWDG_Init(u8 tr,u8 wr,u32 fprer)
{

NVIC_InitTypeDef NVIC_InitStructure;


RCC_APB1PeriphClockCmd(RCC_APB1Periph_WWDG,ENABLE); //使能窗口看门狗时钟

WWDG_CNT=tr&WWDG_CNT; //初始化WWDG_CNT.
WWDG_SetPrescaler(fprer); //设置分频值
WWDG_SetWindowValue(wr); //设置窗口值
//        WWDG_SetCounter(WWDG_CNT);//设置计数值
WWDG_Enable(WWDG_CNT); //开启看门狗

NVIC_InitStructure.NVIC_IRQChannel=WWDG_IRQn; //窗口看门狗中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02; //抢占优先级为2
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03;        //子优先级为3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE; //使能窗口看门狗
NVIC_Init(&NVIC_InitStructure);

WWDG_ClearFlag();//清除提前唤醒中断标志位
WWDG_EnableIT();//开启提前唤醒中断
}

//窗口看门狗中断服务程序
void WWDG_IRQHandler(void)
{
WWDG_SetCounter(WWDG_CNT); //重设窗口看门狗值
WWDG_ClearFlag();//清除提前唤醒中断标志位
LED1=!LED1;
}

定时器中断配置:
1.能定时器时钟。
RCC_APB1PeriphClockCmd();
2.初始化定时器,配置ARR,PSC。
TIM_TimeBaseInit();
3.开启定时器中断,配置NVIC。
NVIC_Init();
4.使能定时器。
TIM_Cmd();
5.编写中断服务函数。
TIMx_IRQHandler();
void TIM3_Int_Init(u16 arr,u16 psc)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3时钟

TIM_TimeBaseInitStructure.TIM_Period = arr; //自动重装载值
TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3

TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允许定时器3更新中断
TIM_Cmd(TIM3,ENABLE); //使能定时器3

NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定时器3中断
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x01; //抢占优先级1
NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x03; //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
NVIC_Init(&NVIC_InitStructure);

}

pwm输出配置:
1.使能定时器14和相关IO口时钟。
使能定时器14时钟:RCC_APB1PeriphClockCmd();
使能GPIOF时钟:RCC_AHB1PeriphClockCmd ();
2.初始化IO口为复用功能输出。函数:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
3.GPIOF9复用映射到定时器14
GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14);
4.初始化定时器:ARR,PSC等:TIM_TimeBaseInit();
5.初始化输出比较参数:TIM_OC1Init();
6.使能预装载寄存器: TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable);
7.使能自动重装载的预装载寄存器允许位TIM_ARRPreloadConfig(TIM14,ENABLE);
8.使能定时器。
9.不断改变比较值CCRx,达到不同的占空比效果:TIM_SetCompare1();
void TIM14_PWM_Init(u32 arr,u32 psc)
{       
//此部分需手动修改IO口设置

GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM14,ENABLE); //TIM14时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE); //使能PORTF时钟       

GPIO_PinAFConfig(GPIOF,GPIO_PinSource9,GPIO_AF_TIM14); //GPIOF9复用为定时器14

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //GPIOF9
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; //复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure); //初始化PF9

TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM14,&TIM_TimeBaseStructure);//初始化定时器14

//初始化TIM14 Channel1 PWM模式         
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //选择定时器模式:TIM脉冲宽度调制模式2
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //比较输出使能
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_Low; //输出极性:TIM输出比较极性低
TIM_OC1Init(TIM14, &TIM_OCInitStructure); //根据T指定的参数初始化外设TIM1 4OC1
TIM_OC1PreloadConfig(TIM14, TIM_OCPreload_Enable); //使能TIM14在CCR1上的预装载寄存器

TIM_ARRPreloadConfig(TIM14,ENABLE);//ARPE使能

TIM_Cmd(TIM14, ENABLE); //使能TIM14


}

输入捕获配置:
① 初始化定时器和通道对应IO的时钟。
② 初始化IO口,模式为复用:GPIO_Init();
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
③设置引脚复用映射:
GPIO_PinAFConfig();
④初始化定时器ARR,PSC
TIM_TimeBaseInit();
⑤初始化输入捕获通道
TIM_ICInit();
⑥如果要开启捕获中断,
TIM_ITConfig();
NVIC_Init();
⑦使能定时器:TIM_Cmd();
⑧编写中断服务函数:TIMx_IRQHandler();
void TIM5_CH1_Cap_Init(u32 arr,u16 psc)
{
GPIO_InitTypeDef GPIO_InitStructure;
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
NVIC_InitTypeDef NVIC_InitStructure;

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //TIM5时钟使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); //使能PORTA时钟       

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0; //GPIOA0
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;        //速度100MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN; //下拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化PA0
GPIO_PinAFConfig(GPIOA,GPIO_PinSource0,GPIO_AF_TIM5); //PA0复用位定时器5


TIM_TimeBaseStructure.TIM_Prescaler=psc; //定时器分频
TIM_TimeBaseStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上计数模式
TIM_TimeBaseStructure.TIM_Period=arr; //自动重装载值
TIM_TimeBaseStructure.TIM_ClockDivision=TIM_CKD_DIV1;

TIM_TimeBaseInit(TIM5,&TIM_TimeBaseStructure);
//初始化TIM5输入捕获参数
TIM5_ICInitStructure.TIM_Channel = TIM_Channel_1; //CC1S=01 选择输入端 IC1映射到TI1上
TIM5_ICInitStructure.TIM_ICPolarity = TIM_ICPolarity_Rising;        //上升沿捕获
TIM5_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI; //映射到TI1上
TIM5_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;        //配置输入分频,不分频
TIM5_ICInitStructure.TIM_ICFilter = 0x00;//IC1F=0000 配置输入滤波器 不滤波
TIM_ICInit(TIM5, &TIM5_ICInitStructure);

TIM_ITConfig(TIM5,TIM_IT_Update|TIM_IT_CC1,ENABLE);//允许更新中断 ,允许CC1IE捕获中断       

TIM_Cmd(TIM5,ENABLE ); //使能定时器5

NVIC_InitStructure.NVIC_IRQChannel = TIM5_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级3
NVIC_InitStructure.NVIC_IRQChannelSubPriority =0;        //子优先级3
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;        //IRQ通道使能
NVIC_Init(&NVIC_InitStructure);        //根据指定的参数初始化VIC寄存器、


}



评分

参与人数 1蝴蝶豆 +2 收起 理由
zero99 + 2 内容太多了吧,看不过来

查看全部评分

lxq66620120 回答时间:2018-8-4 09:33:41
回答的很详细,学习了!
tanic 回答时间:2018-8-4 13:28:54
那个配置是设置引脚物理特性用的,和引脚内部连接到USB还是其他外设无关,如USB这种高速总线,设置为最高就行了,像点灯这种设置为最低即可。如果要输出高频率方波,而设置的引脚速度不够,方波会失真,
至于为何有这么多选择,估计是频率高功耗高些,还有没有其他原因不清楚

评分

参与人数 1蝴蝶豆 +3 收起 理由
zero99 + 3

查看全部评分

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版