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

【ST标准库RTC byte转BCD代码写法理解】

[复制链接]
andeyqi 发布时间:2018-8-31 09:45
本帖最后由 andeyqi 于 2018-8-31 11:16 编辑

查看STM32f4标准库RTC代码时(STM32F4xx_DSP_StdPeriph_Lib_V1.8.0),发现RTC_ByteToBcd2函数书写的不够简洁,代码片段如下。
  1. 02723 /**
  2. 02724   * @brief  Converts a 2 digit decimal to BCD format.
  3. 02725   * @param  Value: Byte to be converted.
  4. 02726   * @retval Converted byte
  5. 02727   */
  6. 02728 static uint8_t RTC_ByteToBcd2(uint8_t Value)
  7. 02729 {
  8. 02730   uint8_t bcdhigh = 0;
  9. 02731   
  10. 02732   while (Value >= 10)
  11. 02733   {
  12. 02734     bcdhigh++;
  13. 02735     Value -= 10;
  14. 02736   }
  15. 02737   
  16. 02738   return  ((uint8_t)(bcdhigh << 4) | Value);
  17. 02739 }
复制代码
代码很容易理解,第一反应感觉代码写的不够简洁。效果和如下的代码是相同的。
  1. static uint8_t RTC_ByteToBcd2(uint8_t Value)
  2. {
  3.    return  (((Value/10) << 4) + (Value %10));
  4. }
复制代码


后来就在想,为什么库函代码写的如此不够简洁,一定有自身的道理,仔细比较了上下两个函数的区别发现库函数规避了除法的使用,记得之前看过的编码规范上有要求能用移位操作来实现的运算就不要使用除法来实现,提高代码的运行效率,下面反汇编如上两个函数用来验证上述的想法。

  1. static uint8_t RTC_ByteToBcd2(uint8_t Value)
  2. {
  3. 8000108:        b580              push        {r7, lr}
  4. 800010a:        b084              sub        sp, #16
  5. 800010c:        af00              add        r7, sp, #0
  6. 800010e:        0002              movs        r2, r0
  7. 8000110:        1dfb              adds        r3, r7, #7
  8. 8000112:        701a              strb        r2, [r3, #0]
  9.    uint8_t bcdhigh = 0;
  10. 8000114:        230f              movs        r3, #15
  11. 8000116:        18fb              adds        r3, r7, r3
  12. 8000118:        2200              movs        r2, #0
  13. 800011a:        701a              strb        r2, [r3, #0]

  14.   while (Value >= 10)
  15. 800011c:        e00b              b.n        8000136 <RTC_ByteToBcd2_1+0x2e>
  16.   {
  17.      bcdhigh++;
  18. 800011e:        230f              movs        r3, #15
  19. 8000120:        18fb              adds        r3, r7, r3
  20. 8000122:        781a              ldrb        r2, [r3, #0]
  21. 8000124:        230f              movs        r3, #15
  22. 8000126:        18fb              adds        r3, r7, r3
  23. 8000128:        3201              adds        r2, #1
  24. 800012a:        701a              strb        r2, [r3, #0]
  25.      Value -= 10;
  26. 800012c:        1dfb              adds        r3, r7, #7
  27. 800012e:        1dfa              adds        r2, r7, #7
  28. 8000130:        7812              ldrb        r2, [r2, #0]
  29. 8000132:        3a0a              subs        r2, #10
  30. 8000134:        701a              strb        r2, [r3, #0]
  31.   while (Value >= 10)
  32. 8000136:        1dfb              adds        r3, r7, #7
  33. 8000138:        781b              ldrb        r3, [r3, #0]
  34. 800013a:        2b09              cmp        r3, #9
  35. 800013c:        d8ef              bhi.n        800011e <RTC_ByteToBcd2_1+0x16>
  36.   }

  37.    return  ((uint8_t)(bcdhigh << 4) | Value);
  38. 800013e:        230f              movs        r3, #15
  39. 8000140:        18fb              adds        r3, r7, r3
  40. 8000142:        781b              ldrb        r3, [r3, #0]
  41. 8000144:        011b              lsls        r3, r3, #4
  42. 8000146:        b2da              uxtb        r2, r3
  43. 8000148:        1dfb              adds        r3, r7, #7
  44. 800014a:        781b              ldrb        r3, [r3, #0]
  45. 800014c:        4313              orrs        r3, r2
  46. 800014e:        b2db              uxtb        r3, r3
  47. }
  48. 8000150:        0018              movs        r0, r3
  49. 8000152:        46bd              mov        sp, r7
  50. 8000154:        b004              add        sp, #16
  51. 8000156:        bd80              pop        {r7, pc}
复制代码

  1. static uint8_t RTC_ByteToBcd2_2(uint8_t Value)
  2. {
  3. 8000158:        b580              push        {r7, lr}
  4. 800015a:        b082              sub        sp, #8
  5. 800015c:        af00              add        r7, sp, #0
  6. 800015e:        0002              movs        r2, r0
  7. 8000160:        1dfb              adds        r3, r7, #7
  8. 8000162:        701a              strb        r2, [r3, #0]
  9.    return  ((Value/10) << 4 | (Value & 0X0F));
  10. 8000164:        1dfb              adds        r3, r7, #7
  11. 8000166:        781b              ldrb        r3, [r3, #0]
  12. 8000168:        210a              movs        r1, #10
  13. 800016a:        0018              movs        r0, r3
  14. 800016c:        f000 f89a         bl        80002a4 <__udivsi3>
  15. 8000170:        0003              movs        r3, r0
  16. 8000172:        b2db              uxtb        r3, r3
  17. 8000174:        011b              lsls        r3, r3, #4
  18. 8000176:        b25a              sxtb        r2, r3
  19. 8000178:        1dfb              adds        r3, r7, #7
  20. 800017a:        781b              ldrb        r3, [r3, #0]
  21. 800017c:        b25b              sxtb        r3, r3
  22. 800017e:        210f              movs        r1, #15
  23. 8000180:        400b              ands        r3, r1
  24. 8000182:        b25b              sxtb        r3, r3
  25. 8000184:        4313              orrs        r3, r2
  26. 8000186:        b25b              sxtb        r3, r3
  27. 8000188:        b2db              uxtb        r3, r3
  28. }
  29. 800018a:        0018              movs        r0, r3
  30. 800018c:        46bd              mov        sp, r7
  31. 800018e:        b002              add        sp, #8
  32. 8000190:        bd80              pop        {r7, pc}
复制代码


咋一看,好像方法2的代码量是要少于库函数的里的实现的,但发现方法2有如下代码
bl        80002a4 <__udivsi3>
该函数是除法实现的相关代码,实现如下
  1. 080002a4 <__udivsi3>:
  2. 80002a4:        2200              movs        r2, #0
  3. 80002a6:        0843              lsrs        r3, r0, #1
  4. 80002a8:        428b              cmp        r3, r1
  5. 80002aa:        d374              bcc.n        8000396 <__udivsi3+0xf2>
  6. 80002ac:        0903              lsrs        r3, r0, #4
  7. 80002ae:        428b              cmp        r3, r1
  8. 80002b0:        d35f              bcc.n        8000372 <__udivsi3+0xce>
  9. 80002b2:        0a03              lsrs        r3, r0, #8
  10. 80002b4:        428b              cmp        r3, r1
  11. 80002b6:        d344              bcc.n        8000342 <__udivsi3+0x9e>
  12. 80002b8:        0b03              lsrs        r3, r0, #12
  13. 80002ba:        428b              cmp        r3, r1
  14. 80002bc:        d328              bcc.n        8000310 <__udivsi3+0x6c>
  15. 80002be:        0c03              lsrs        r3, r0, #16
  16. 80002c0:        428b              cmp        r3, r1
  17. 80002c2:        d30d              bcc.n        80002e0 <__udivsi3+0x3c>
  18. 80002c4:        22ff              movs        r2, #255        ; 0xff
  19. 80002c6:        0209              lsls        r1, r1, #8
  20. 80002c8:        ba12              rev        r2, r2
  21. 80002ca:        0c03              lsrs        r3, r0, #16
  22. 80002cc:        428b              cmp        r3, r1
  23. 80002ce:        d302              bcc.n        80002d6 <__udivsi3+0x32>
  24. 80002d0:        1212              asrs        r2, r2, #8
  25. 80002d2:        0209              lsls        r1, r1, #8
  26. 80002d4:        d065              beq.n        80003a2 <__udivsi3+0xfe>
  27. 80002d6:        0b03              lsrs        r3, r0, #12
  28. 80002d8:        428b              cmp        r3, r1
  29. 80002da:        d319              bcc.n        8000310 <__udivsi3+0x6c>
  30. 80002dc:        e000              b.n        80002e0 <__udivsi3+0x3c>
  31. 80002de:        0a09              lsrs        r1, r1, #8
  32. 80002e0:        0bc3              lsrs        r3, r0, #15
  33. 80002e2:        428b              cmp        r3, r1
  34. 80002e4:        d301              bcc.n        80002ea <__udivsi3+0x46>
  35. 80002e6:        03cb              lsls        r3, r1, #15
  36. 80002e8:        1ac0              subs        r0, r0, r3
  37. 80002ea:        4152              adcs        r2, r2
  38. 80002ec:        0b83              lsrs        r3, r0, #14
  39. 80002ee:        428b              cmp        r3, r1
  40. 80002f0:        d301              bcc.n        80002f6 <__udivsi3+0x52>
  41. 80002f2:        038b              lsls        r3, r1, #14
  42. 80002f4:        1ac0              subs        r0, r0, r3
  43. 80002f6:        4152              adcs        r2, r2
  44. 80002f8:        0b43              lsrs        r3, r0, #13
  45. 80002fa:        428b              cmp        r3, r1
  46. 80002fc:        d301              bcc.n        8000302 <__udivsi3+0x5e>
  47. 80002fe:        034b              lsls        r3, r1, #13
  48. 8000300:        1ac0              subs        r0, r0, r3
  49. 8000302:        4152              adcs        r2, r2
  50. 8000304:        0b03              lsrs        r3, r0, #12
  51. 8000306:        428b              cmp        r3, r1
  52. 8000308:        d301              bcc.n        800030e <__udivsi3+0x6a>
  53. 800030a:        030b              lsls        r3, r1, #12
  54. 800030c:        1ac0              subs        r0, r0, r3
  55. 800030e:        4152              adcs        r2, r2
  56. 8000310:        0ac3              lsrs        r3, r0, #11
  57. 8000312:        428b              cmp        r3, r1
  58. 8000314:        d301              bcc.n        800031a <__udivsi3+0x76>
  59. 8000316:        02cb              lsls        r3, r1, #11
  60. 8000318:        1ac0              subs        r0, r0, r3
  61. 800031a:        4152              adcs        r2, r2
  62. 800031c:        0a83              lsrs        r3, r0, #10
  63. 800031e:        428b              cmp        r3, r1
  64. 8000320:        d301              bcc.n        8000326 <__udivsi3+0x82>
  65. 8000322:        028b              lsls        r3, r1, #10
  66. 8000324:        1ac0              subs        r0, r0, r3
  67. 8000326:        4152              adcs        r2, r2
  68. 8000328:        0a43              lsrs        r3, r0, #9
  69. 800032a:        428b              cmp        r3, r1
  70. 800032c:        d301              bcc.n        8000332 <__udivsi3+0x8e>
  71. 800032e:        024b              lsls        r3, r1, #9
  72. 8000330:        1ac0              subs        r0, r0, r3
  73. 8000332:        4152              adcs        r2, r2
  74. 8000334:        0a03              lsrs        r3, r0, #8
  75. 8000336:        428b              cmp        r3, r1
  76. 8000338:        d301              bcc.n        800033e <__udivsi3+0x9a>
  77. 800033a:        020b              lsls        r3, r1, #8
  78. 800033c:        1ac0              subs        r0, r0, r3
  79. 800033e:        4152              adcs        r2, r2
  80. 8000340:        d2cd              bcs.n        80002de <__udivsi3+0x3a>
  81. 8000342:        09c3              lsrs        r3, r0, #7
  82. 8000344:        428b              cmp        r3, r1
  83. 8000346:        d301              bcc.n        800034c <__udivsi3+0xa8>
  84. 8000348:        01cb              lsls        r3, r1, #7
  85. 800034a:        1ac0              subs        r0, r0, r3
  86. 800034c:        4152              adcs        r2, r2
  87. 800034e:        0983              lsrs        r3, r0, #6
  88. 8000350:        428b              cmp        r3, r1
  89. 8000352:        d301              bcc.n        8000358 <__udivsi3+0xb4>
  90. 8000354:        018b              lsls        r3, r1, #6
  91. 8000356:        1ac0              subs        r0, r0, r3
  92. 8000358:        4152              adcs        r2, r2
  93. 800035a:        0943              lsrs        r3, r0, #5
  94. 800035c:        428b              cmp        r3, r1
  95. 800035e:        d301              bcc.n        8000364 <__udivsi3+0xc0>
  96. 8000360:        014b              lsls        r3, r1, #5
  97. 8000362:        1ac0              subs        r0, r0, r3
  98. 8000364:        4152              adcs        r2, r2
  99. 8000366:        0903              lsrs        r3, r0, #4
  100. 8000368:        428b              cmp        r3, r1
  101. 800036a:        d301              bcc.n        8000370 <__udivsi3+0xcc>
  102. 800036c:        010b              lsls        r3, r1, #4
  103. 800036e:        1ac0              subs        r0, r0, r3
  104. 8000370:        4152              adcs        r2, r2
  105. 8000372:        08c3              lsrs        r3, r0, #3
  106. 8000374:        428b              cmp        r3, r1
  107. 8000376:        d301              bcc.n        800037c <__udivsi3+0xd8>
  108. 8000378:        00cb              lsls        r3, r1, #3
  109. 800037a:        1ac0              subs        r0, r0, r3
  110. 800037c:        4152              adcs        r2, r2
  111. 800037e:        0883              lsrs        r3, r0, #2
  112. 8000380:        428b              cmp        r3, r1
  113. 8000382:        d301              bcc.n        8000388 <__udivsi3+0xe4>
  114. 8000384:        008b              lsls        r3, r1, #2
  115. 8000386:        1ac0              subs        r0, r0, r3
  116. 8000388:        4152              adcs        r2, r2
  117. 800038a:        0843              lsrs        r3, r0, #1
  118. 800038c:        428b              cmp        r3, r1
  119. 800038e:        d301              bcc.n        8000394 <__udivsi3+0xf0>
  120. 8000390:        004b              lsls        r3, r1, #1
  121. 8000392:        1ac0              subs        r0, r0, r3
  122. 8000394:        4152              adcs        r2, r2
  123. 8000396:        1a41              subs        r1, r0, r1
  124. 8000398:        d200              bcs.n        800039c <__udivsi3+0xf8>
  125. 800039a:        4601              mov        r1, r0
  126. 800039c:        4152              adcs        r2, r2
  127. 800039e:        4610              mov        r0, r2
  128. 80003a0:        4770              bx        lr
  129. 80003a2:        e7ff              b.n        80003a4 <__udivsi3+0x100>
  130. 80003a4:        b501              push        {r0, lr}
  131. 80003a6:        2000              movs        r0, #0
  132. 80003a8:        f000 f806         bl        80003b8 <__aeabi_idiv0>
  133. 80003ac:        bd02              pop        {r1, pc}
  134. 80003ae:        46c0              nop                        ; (mov r8, r8)
复制代码
这么一比较的话库函数的代码效率要明显,比自己实现的简洁的代码效率要高。

总结:
库函数的代码实现虽然不够简洁,但代码的实现充分考虑了代码运行的效率性。


评分

参与人数 1 ST金币 +6 收起 理由
MrJiu + 6 赞一个!

查看全部评分

收藏 评论6 发布时间:2018-8-31 09:45

举报

6个回答
MrJiu 回答时间:2018-8-31 10:05:04
这个分析的这么具体,顶!!!
andeyqi 回答时间:2018-8-31 10:10:54
MrJiu 发表于 2018-8-31 10:05
这个分析的这么具体,顶!!!

感谢 打赏支持
左岸右岸 回答时间:2018-8-31 10:57:38
这种探究的精神,点个赞
zero99 回答时间:2018-8-31 13:19:39
学习了
toofree 回答时间:2018-8-31 13:38:57
支持楼主,
的确,有好的硬件,还得有高效的程序。
所谓DSP库,就是把代码优化到效率最高。
如果不用库,自己胡写的话,就算是TI的DSP处理器的高性能都没得发挥。
andeyqi 回答时间:2018-8-31 17:19:40
toofree 发表于 2018-8-31 13:38
支持楼主,
的确,有好的硬件,还得有高效的程序。
所谓DSP库,就是把代码优化到效率最高。

大佬说的很有道理。

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

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