请选择 进入手机版 | 继续访问电脑版

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

【经验分享】单片机快速将库函数版代码移植为寄存器代码方法

[复制链接]
STMCU小助手 发布时间:2022-3-18 21:54
 现在单片机开发越来越多用的是库函数版本的,寄存器版本使用越来越少了。但是在有些项目中使用库函数会导致程序运行速度比较慢,没有直接操作寄存器运行起来速度快。所以在对时间要求比较严格的项目中,还是需要使用寄存器来开发。如果不能够找到寄存器相关示例代码的时候,开发起来还是比较困难的。今天就来总结一个快速将库函数移植为寄存器的方法,这个方式为通用方法,在任何单片机上都可以使用。- r! t  D6 }$ f: o, n: L
7 S% D5 I! K) t* w" D8 @7 z- _
  现在就用一个STM8单片机库函数的工程来举例。
' Y0 \; q" Y  l$ X* y7 k1 W! P7 V6 h  p: {! Z! t) G
A6DVSS0B931J246$N%P[JN5.png 9 w/ P1 T) Y+ E4 B/ |

, n4 \) }: O/ {- v  ]4 C* p  这个代码的主要功能就是使用定时器1的捕获功能来计算输入波形的频率。对于定时器的初始化使用的都是库函数,现在要将定时器初始化部分的库函数修改为寄存器。) i4 c( Q" t' D" R
9 L$ k, @5 T- d+ C8 [' \$ z
  首先单步调试,进入初始化函数中。9 J+ \3 T) [, G+ N  x3 e2 M
(V$[ZK3]{X%RL8[84@$[0D1.png $ @2 I2 f  Y( {9 X9 D
) H8 c" |' _) g- N1 x! Q& Y# k
  单步进步到这个函数内部。5 B& H0 o- d3 Z# I
. ?# v4 K* I$ `1 q9 T- a& E- ]' b
C04B_Y2`FC[51JO[I{BQ}~L.png
2 d9 w4 ^6 W8 K: q- r+ {7 f; Z2 n: F! I1 R1 N) O
  可以看到在这个函数中初始化了6个寄存器,将这6个寄存器分别添加到观察窗口中。' q, x' {: O8 C" P

6 Z! j  L8 G8 h+ g& C9 ^ J(2JL$E9S~FY{17FV`6)RVV.png
1 G( v3 T2 Q* E% j# P9 d0 j
" h/ p5 _+ s* d  在代码中是通过指针的方式去操作寄存器的,所以在将寄存器添加到观察窗口时要注意名字格式,需要将 TIM1->ARRH 修改为 TIM1_ARRH 格式。添加寄存器的时候,可以直接在观察窗口表达式的位置处单击鼠标,直接将寄存器的名字输入进去。
+ o, D9 j  Z2 |1 n9 m- H7 }9 e: U. l5 y6 p4 e$ Y. h
C(M$JL6P$E5HQ`{KI}1)9.png & @- p8 J, Q6 L+ h

; P7 w6 M3 G6 r1 i5 p: N  然后将寄存器值显示的方式修改为 16进制显示。在观察窗口中寄存器上单击鼠标右键,选择16进制显示。
8 l9 ~5 _* G$ c9 h& k- S  ^$ ?. o) _+ H/ b$ S; w
%RM@J4}@1TZK~2$V0(E9EKX.png * x/ x: Z1 p$ D9 F9 {6 n; x
+ M- N* v, d" B, b' @3 Q2 C) p8 F* q
  按照同样的方法将其他寄存器全部添加进去。) K; `! B- T' B4 L, N

  M# B! C4 C( n/ P, k K}FS8B(}$]IJ2NK(OU9C.png
  R) A7 k; o7 s, U. C. d5 r3 c( h5 r+ H( Z* `
  此时寄存器的值都为默认值,然后单步执行程序。观察寄存器值的变化。
/ z5 o0 M& w" q5 g/ y; v: y* w2 P9 R" ~
JZFKH02QN3Z%Z[WH@J)V8L8.png ' p, @# v! s4 Q& ?

0 Q4 l3 g8 y/ d# ?/ \  当前函数执行完成之后,所有的寄存器值就是库函数设置之后的值。将这些寄存器的值记录下来。8 T# F9 @+ G5 F8 |
" r- \! _$ H( E* L
Q[[P)E)VAY~7IN6}{7@L9DM.png ' _& I+ t9 w. \" E, \5 V$ q6 D

# o9 ]2 v4 v. s& d6 d* v  h  相当于TIM1_TimeBaseInit()函数设置的就是这几个寄存器,然后设置后的寄存器值就是变量观察窗口中的值。按照同样的方法,依次单步调试,记录下所有初始化寄存器的值。
0 q. A" T  i2 e* v9 h; B  u
9 f! |: E0 w, f0 H- |2 I/ K J0%`FM4A~JFG%2MMU{XI2`Q.png
% c& N6 y& M& f& K! K: B5 b4 I8 q7 ?" g  f$ o: p! m
  当初始化代码中的寄存器值全部记录完成之后,这时候就可以用寄存器直接替换库函数了。
  x  S/ {4 O, l# p. W3 O+ Q  K3 S& m$ j0 R
6WKJM4{LAFA6BH@ANA}~2WQ.png
2 j* k" @$ ?/ G0 j7 l  c" b) q
" N1 B; a# F1 O  替换完成后运行程序,观察程序运行结果是否争正确。通过观察串口输出的结果证明程序执行是正确的。
, ]+ G5 F* j, V0 s% U/ y/ C# M2 J+ T0 M2 L
T4`)S2}}54UGU0R1)LE2K6W.png " Q7 e7 C2 V7 T4 T8 P  [
) i0 B8 L) X: q
  这样通过单步调试的方法,直接观察寄存器的值,就能快速的搞清楚库函数代码到底是设置了哪些寄存器,设置后的值是多少。当设置的寄存器值知道之后,然后通过查阅单片机资料,对比寄存器中的各个位的含义,就明白了使用哪些功能要设置哪些寄存器对应的哪些位。
2 A8 m! A* B0 K$ G2 w0 w1 R, ]
: N/ v+ W8 {/ x( L- l* Y XL)1JR0DGT5IUL80(B8KDKC.png + o+ z9 {8 W  p. O, \* G8 y) i

- c8 a. M/ K2 G  当看完寄存器资料后,明白了每个寄存器的作用,这时候就可以将寄存器的初始化优化一下,让代码看起来更清晰明了。" x8 B. u! n% D4 L9 }7 T

; u" T3 H/ c$ g/ `4 K0 w M067{F3F~8L8CI8X24JAL[F.png 4 X( M0 r. z( ^' T2 Q8 o1 i

5 i6 A/ W9 S# m5 ?  将寄存器的设置修改为位操作模式,这样直接通过代码就可以很方法的看出来操作的是哪个寄存器的哪些位。 修改完成后重新编译下载,验证一下修改之后的代码功能是否正常。" I( _3 s) M, n/ s& H& b+ H$ [2 S
* V4 j/ m: Q0 p" V, r7 m
  通过这种方法就能快速的了解到寄存器的使用,否则只是看单片机寄存器的相关手册的话,没有重点,而且有些手册非常大,看了后面忘了前面,效率非常低。同时在看的过程中也搞不清楚,有些寄存器到底要在哪个功能中去设置。而通过单步调试的方法,直接观察库函数中设置的寄存器,就能快速的了解寄存器的作用,可以做到用什么功能时再去看对应寄存器的资料,避免了单纯看资料浪费时间过程,还提高了学习效率。
' p7 u! ?* U2 Q, O5 M  b. [2 {1 T0 Z1 @* F* s  N! {4 I
# [1 t# H% G" r4 S8 q. A/ m% x- b6 D. c
- m  Q- w% y8 N( G( U9 o' ^6 ^7 [
收藏 评论0 发布时间:2022-3-18 21:54

举报

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