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

基于stm32f103内部存储和定时器的经验分享

[复制链接]
攻城狮Melo 发布时间:2023-3-26 19:16
从目前了解的看,STM32的操作其实就是对内部存储器的操作,寄存器是映射到存储器地址空间上的。
4 E2 ]/ e: _8 {1 q但这些存储器地址可不像普通内存空间一样可以按照自己的需要来操作,它需要遵循硬件特性,先操作哪个再操作哪个。
7 d' w2 Z6 p8 a4 |首先需要了解的是存储器地址映射。7 T) U3 P% @3 j" P. {9 Y9 z
STM32自然是32位机,存储器可寻址空间为4GB,即0x0000,0000~0xFFFF,FFFF。) j' |) E8 T* Q; d9 g" t8 B
这里有个通常所说的1024问题,其实这是为了在数字上好用16进制来表示才规定的,说是规定不如说是约定俗成。1k=1024,表示成16进制刚好是0x400,如果1k=1000表示成16进制就是0x3E8,那么2k=0x7D0就不如表示成1024时2k=0x800好表示:2k=2*0x400=0x800。看,刚好是400的2倍。2 _" `8 H6 b  }5 H
这些地址空间被粗略地分成了8个块,每块512MB,其中第0、1、2块最重要。
2 r; i  \0 v7 bblock0:是内部Flash,用于储存用户程序代码和其他必须的工厂代码。可是芯片并非全提供这么多的实体Flash给我们用,比如精英版的STM32F103ZET只有512kB可以用来编程就已经是大容量了。第0块大量的是预留空间,其实是为了将来芯片升级不用再重新设计才预留的,预留就是在该芯片上不提供的意思。
+ A6 h! z' x- [% |0 P! r: {! _block1:是内部SRAM,也就是我们说的内存,易失性。这512M也只有部分可用,精英版的STM32F103ZET是64kB。片上内存总是很贵的。
4 w, y, f, I- O% s4 Z3 A* }block2:是以后学习的重灾区了,片上外设映射到此。
% d7 j! ~. e& L. E$ o4 f$ n3 U: M片上外设分两种:低速和高速。低速外设用到APB1总线,或者说APB1就是低速外设,映射到存储器地址是:0x4000,000~0x4000,77FF.) d  k* S* J" [6 I' c8 |/ u
高速外设又分两种:APB2和AHB总线。APB2映射地址为:0x4001,000~0x4001,3FFF。AHB地址为:0学4002,000~0x5003,FFFF。看来是AHB总线的地址范围大。
! b# L) z4 t5 K$ C& ?block2的512MB也没有全部提供使用,使用到的空间也不是全都连续。功能不同的总线间有预留空间。
2 l2 j  S/ Y% u, g5 V* A------------------------
2 S+ C6 x2 W4 u/ o/ V" [( ^为什么是总线映射而不是直接寄存器映射呢?寄存器是设备的控制单元,而设备是挂载在总线上的,无论是外设还是核内设备都如此。总线天然地有地址,这对于有一点点51常识的我来说还是比较好理解的。
$ r6 o' ~5 [6 b  x; C/ r# H9 w
6 V; x0 H* M& _) L
可以这么理解:总线上的设备和存储器(Flash/SRAM)是统一编址的。
9 u. F  |) N- R; q
! w: ]4 |1 Z, O3 m0 Y. H$ c& d; |ysTick是内核定时器,有4个相关寄存器,LOAD和VAL是24位寄存器,一直认为STM32的寄存器都是32位的,这下毁三观了。) j, z& t  r: W: J
我在M3权威指南和中文参考里面都没有发现这四个寄存器中CTRL和CALIB的具体定义,只看到CTRL中16、2、1、0位的定义,其他位没有说明,怎么回事儿呀?8 X4 D9 Y# a+ O8 X, Z
再看misc.c中的SysTick定时器初始化函数SysTick_CLKSourceConfig(),传入的是宏常量,关于是配置外部HCLK的还是内部HCLK作为SysTick时钟源,宏定义是:- \! p0 o4 `' q( v1 d
[mw_shl_code=c,true]#define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
/ b+ R* x) U: ?8 j# _" J1 R9 N#define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)[/mw_shl_code]: S  i- G0 s1 t% }7 h
SysTick_CLKSourceConfig()里面直接用这个宏来赋值CTRL寄存器,其中如果是内部HCLK做源第2位为1,则使用“或”,这个好理解,就是把CTRL的第2位赋值为传入的参数。如果是外部HCLK则使用“与”:
  }4 T: J( [6 ?0 T$ ]
  1. [mw_shl_code=c,true]  if (SysTick_CLKSource == SysTick_CLKSource_HCLK)  {1 c& v& o$ x! i' V2 d3 A% q
  2.     SysTick->CTRL |= SysTick_CLKSource_HCLK;1 ~, ?7 V. l; K' R
  3.   }
    5 P0 T7 z0 }! S
  4.   else
    . G) t& @3 j7 ^+ D0 t- f- D
  5.   {. W6 I  C4 d0 r9 @
  6.     SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
    ( n! o# j  Q2 d8 P" j5 R/ q& n
  7.   }[/mw_shl_code]
复制代码

% O( f- f  P+ @$ [7 S5 {外部HCLK值做源为0xFFFFFFFB,低4位B是二进制1011,第2位是0,采用AHB的8分频。第2位&也容易理解。) O, ?! `) _3 m! w, P. A% O! @( D
第0位第1位是1,使能SysTick定时器和定时到产生中断。“与”1就是不用管,不产生影响了。
( A" Z& B% F4 ]( ~所以,如果以后要使某位置1则data中的某位为1其他位0,然后或。) r/ x5 ~% s( }: R8 o/ L
如果要使某位置0则data中某位为0其他位为1,然后与。
! l' L: Q4 a/ q, n————————————————
; S. r% t) B1 C) _/ ~+ @版权声明:被大佬糊弄的只会点灯的小菜鸡
: f9 [! L! W2 J# k如有侵权请联系删除
! ?2 E# L" m( b. f3 P+ g% ^
7 i+ M: j" @/ ^0 j' z1 J4 y' t! J6 Y9 j) K
收藏 评论0 发布时间:2023-3-26 19:16

举报

0个回答
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版