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

不用晶振,STM32内部HSI时钟的倍频使用

[复制链接]
STMCU小助手 发布时间:2023-1-6 16:25
最近用STM32F1系列单片机做一个触摸屏USB鼠标,考虑不用外部晶振而使用STM32内部8MHz HSI RC作为时钟源。由于USB协议规定了48MHz 的USB时钟,故必须对HIS作PLL倍频处理后得到PLLCLK作为STSCLK时钟。时钟关系见如下STM32F1时钟树:$ H$ i6 T9 v" {9 O- C% w
8 ?/ q2 N* g# Y, K
20170809203202707.png
+ z( H$ f( X9 N, p: ~  w2 ^9 q, D) i! G4 z2 h: n
类比正点原子STM32F1寄存器版本使用外部晶振的时钟初始化函数,改动得到使用HSI作为时钟源,SYSCLK为48MHz的初始化代码:
4 K) G' h1 W1 i# b
: h2 s- ~& s- @4 a3 _" m: \. z/ w  h
  1. void Stm32_Clock_Init(u8 PLL). y. m; S* _  [: n  Z8 F8 K
  2. {
    ' O3 \/ a: v9 _. }
  3.     unsigned char temp=0;4 D3 D) g! [% G) }2 t
  4.     MYRCC_DeInit();                  //复位并配置向量表
    - L4 A: m8 `5 H0 w: _( Q
  5.     RCC->CR|=0x00000001;  //内部高速时钟使能HSION5 J" o& |9 n( j4 Y/ B0 E
  6.     while(!(RCC->CR>>1));//等待内部时钟就绪
    $ q& P& m7 ]( r( W; K
  7.     RCC->CFGR=0X00000400; //APB1=DIV2;APB2=DIV1;AHB=DIV1;& s. U5 l/ Q, z& Y; n
  8.     PLL-=2;//抵消2个单位
    ) U+ U( f& P: m6 h" W6 T
  9.     RCC->CFGR|=PLL<<18;   //设置PLL值 2~16
    , b7 k. Z3 ^3 A2 `* }
  10.     RCC->CFGR|=0<<16;          //PLLSRC ON  HSI经2分频后作为PLL输入时钟2 l2 n2 g2 I: B& }
  11.     FLASH->ACR|=0x32;          //FLASH 2个延时周期
    - i- G' w/ D1 h6 K0 ?( [

  12. % D8 K, i# \, }% R! W
  13.     RCC->CR|=0x01000000;  //PLLON
    / a9 b& l; }3 r' T2 b5 U# `3 d: h
  14.     while(!(RCC->CR>>25));//等待PLL锁定9 e0 Y3 U, z  d8 X8 a
  15.     RCC->CFGR|=0x00000002;//PLL作为系统时钟% j) U; p( r- f) T: z
  16.     while(temp!=0x02)     //等待PLL作为系统时钟设置成功
    7 k0 Y- A7 h/ V6 m8 f, S% G: U
  17.     {
    5 u* `2 X" w( Q& m
  18.     temp=RCC->CFGR>>2;7 F7 S6 ^% c) O5 X7 b9 J
  19.     temp&=0x03;# @% S: `6 a. \9 f& _) `0 q) Y
  20.     }
    5 J% ?+ ^2 Z+ b) x  Z
  21. }
复制代码

/ E" i) Y) N% @* @8 n" [9 u其中MYRCC_DeInit()代码如下:( N% U$ D) G. G" m. k4 y0 t) N

7 L7 A# y9 `0 c9 G4 _
  1. void MYRCC_DeInit(void). n: G- h/ D# Q" b7 ^# R1 w
  2. {        % g- L$ j9 `7 |
  3.         RCC->APB1RSTR = 0x00000000;//复位结束                         
    - p5 b4 {) Z) F7 U
  4.         RCC->APB2RSTR = 0x00000000; ; S: T7 a3 n: k: I+ {
  5.           
    2 X2 f# W0 X3 C/ v( X9 r
  6.           RCC->AHBENR = 0x00000014;  //睡眠模式闪存和SRAM时钟使能.其他关闭.          
    7 y9 S8 g% f' f% g1 `' ]
  7.           RCC->APB2ENR = 0x00000000; //外设时钟关闭.                           0 c+ _( q& [# D  x0 \
  8.           RCC->APB1ENR = 0x00000000;   
    % g7 `( P) f' [4 V/ P: J3 A1 y" i
  9.         RCC->CR |= 0x00000001;     //使能内部高速时钟HSION                                                                                                                                  
    - [1 F" F/ v. X6 j+ t1 J; |" G
  10.         RCC->CFGR &= 0xF8FF0000;   //复位SW[1:0],HPRE[3:0],PPRE1[2:0],PPRE2[2:0],ADCPRE[1:0],MCO[2:0]                                         + {1 P! @1 f1 i
  11.         RCC->CR &= 0xFEF6FFFF;     //复位HSEON,CSSON,PLLON" }) N0 ?: P: z7 T" P
  12.         RCC->CR &= 0xFFFBFFFF;     //复位HSEBYP                     ! P! p) Y* ~1 e# j# ]
  13.         RCC->CFGR &= 0xFF80FFFF;   //复位PLLSRC, PLLXTPRE, PLLMUL[3:0] and USBPRE 9 i" G" G( ~6 G# e
  14.         RCC->CIR = 0x00000000;     //关闭所有中断                 6 |+ v# m. x8 T1 C9 w) {; U
  15.         //配置向量表                                  / ^9 ^2 `8 x/ Y% k. M5 Q0 [4 I
  16. #ifdef  VECT_TAB_RAM
    : n7 J% N, Z! k
  17.         MY_NVIC_SetVectorTable(0x20000000, 0x0);
    3 ]" s; e& W, I9 E+ w& J0 u2 s
  18. #else   . t* l# c; `% w5 y. r1 L6 s
  19.         MY_NVIC_SetVectorTable(0x08000000,0x0);
    + F" }, ?- Z* ?2 x1 e$ ]
  20. #endif1 |( \7 ^& R! V" y/ B* {
  21. }
复制代码
2 W, Y4 a2 g( v0 R7 u, ~
MY_NVIC_SetVectorTable()代码如下:
0 K; }6 r! G* F3 k& |% P
# T9 J; ~% i% q  L1 E& V! R* a# T
  1. void MY_NVIC_SetVectorTable(u32 NVIC_VectTab, u32 Offset)         % z, v- o( Y9 G* K  Y6 z
  2. {                     
    & F' D, [5 k1 y# k( [9 c$ j# n, r
  3.         SCB->VTOR = NVIC_VectTab|(Offset & (u32)0x1FFFFF80);//设置NVIC的向量表偏移寄存器
    . m, l! C6 v3 G# U
  4.         //用于标识向量表是在CODE区还是在RAM区
    6 v; W4 E4 j  k* L# d
  5. }
复制代码

% T# c. v2 t: t8 J/ H' ?(1)使用时在main()函数中应写成:Stm32_Clock_Init(12),即8/2*12=48MHz.1 Z2 {( l. B- o9 d8 J  ]$ g

9 \9 ]' N5 _# O2 ^; A(2)为使delay_ms()等函数时钟准确,应在system_stm32f10x.c中将. W. J0 g4 d& g' k& K. g, D

$ |( v: \- k% \2 m$ W" N(3)#define SYSCLK_FREQ_48MHz  48000000解除屏蔽
# @* B* w8 I/ D- {1 B
( H9 t7 N7 E/ o3 z! O4 X9 ?(4)同时要注意在USB时钟初始化函数中不再对PLL时钟分频。即时钟配置寄存器(RCC_CFGR)第22位应设置为13 ^: ^8 S. v+ {- j- H' g  \
3 H8 B9 j8 k7 s* H" H
(5)最后,内部时钟要想正确使用,需要在启动.s文件中屏蔽sysinit4 U- n, O" i8 s6 a9 J
————————————————
8 A+ g# T! Z, G& t2 t1 O版权声明:qhw52794 F' q) X3 I* t) h

  F+ V$ t* D" A: x8 D6 }4 @
赞 收藏 评论0 发布时间:2023-1-6 16:25

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版