位带简介

image.png
位操作就是可以单独的对一个比特位读和写, 51 单片机中通过关键字 sbit 来实现位定义, STM32 没有这样的关键字,而是通过访问位带别名区来实现。

在 STM32 中,有两个地方实现了位带,一个是 SRAM 区的最低 1MB 空间,令一个是外设区最低 1MB 空间。这两个 1MB 的空间除了可以像正常的 RAM 一样操作外,他们还有自己的位带别名区,位带别名区把这 1MB 的空间的每一个位膨胀成一个 32 位的字,当访问位带别名区的这些字时,就可以达到访问位带区某个比特位的目的
image.png

位带地址转换

位带区的一个位,对应位带别名区的四个字节。一个字节对应一个地址。
image.png
8表示一个地址对应一个字节,一个字节有8个位,4表示1位对应4个别名区的字节(地址)
image.png
image.png

使用位带方式访问寄存器

main.c

  1. #include "stm32f10x.h"
  2. #include "bsp_led.h"
  3. #include "bsp_key.h"
  4. #define GPIOB_ODR_Addr (GPIOB_BASE+ 0x0C)
  5. #define PBout(n) *(unsigned int*)((GPIOB_ODR_Addr & 0xF0000000)+0x02000000+((GPIOB_ODR_Addr & 0x00FFFFF)<<5)+(n<<2))
  6. #define GPIOA_IDR_Addr (GPIOA_BASE+ 0x08)
  7. #define PAin(n) *(unsigned int*)((GPIOA_IDR_Addr & 0xF0000000)+0x02000000+((GPIOA_IDR_Addr & 0x00FFFFF)<<5)+(n<<2))
  8. #define GPIOC_IDR_Addr (GPIOC_BASE+ 0x08)
  9. #define PCin(n) *(unsigned int*)((GPIOC_IDR_Addr & 0xF0000000)+0x02000000+((GPIOC_IDR_Addr & 0x00FFFFF)<<5)+(n<<2))
  10. void Delay( uint32_t count)
  11. {
  12. for(;count != 0;count--);
  13. }
  14. //void GreenLed(uint32_t t)
  15. //{
  16. // LED_G(ON);
  17. // LED_B(OFF);
  18. // LED_R(OFF);
  19. // Delay(t);
  20. //}
  21. //void BlueLed(uint32_t t)
  22. //{
  23. // LED_G(OFF);
  24. // LED_B(ON);
  25. // LED_R(OFF);
  26. // Delay(t);
  27. //}
  28. //void RedLed(uint32_t t)
  29. //{
  30. // LED_G(OFF);
  31. // LED_B(OFF);
  32. // LED_R(ON);
  33. // Delay(t);
  34. //}
  35. int main(void)
  36. {
  37. LED_G_GPIO_Config();
  38. LED_B_GPIO_Config();
  39. KEY1_GPIO_Config();
  40. KEY2_GPIO_Config();
  41. #if 0
  42. while(1)
  43. {
  44. PBout(0) = 1;
  45. PBout(1) = 1;
  46. Delay(0xFFFFF);
  47. PBout(0) = 0;
  48. Delay(0xFFFFF);
  49. PBout(0) = 1;
  50. Delay(0xFFFFF);
  51. PBout(1) = 0;
  52. Delay(0xFFFFF);
  53. PBout(1) = 1;
  54. Delay(0xFFFFF);
  55. PBout(0) = 0;
  56. PBout(1) = 0;
  57. Delay(0xFFFFF);
  58. }
  59. #else
  60. while(1)
  61. {
  62. // if(Key_Scan(KEY1_GPIO_PORT,KEY1_GPIO_Pin) == KEY_ON)
  63. // {
  64. // LED_G_TOGGLE;
  65. //
  66. // }
  67. //
  68. // if(Key_Scan(KEY2_GPIO_PORT,KEY2_GPIO_Pin) == KEY_ON)
  69. // {
  70. // LED_B_TOGGLE;
  71. //
  72. // }
  73. if(PAin(0) == KEY_ON)
  74. {
  75. while(PAin(0) == KEY_ON);
  76. LED_G_TOGGLE;
  77. }
  78. if(PCin(13) == KEY_ON)
  79. {
  80. while(PCin(13) == KEY_ON);
  81. LED_B_TOGGLE;
  82. }
  83. }
  84. #endif
  85. }