AHB1ENR|= 1<<5;//使能RCC的AHB1时钟 //PF9 的GPIO配置 //将(1 1)左移..._gpioe->odr&=~(1<<13)">
当前位置:   article > 正文

4.3、使用寄存器版本点亮LED灯(内附代码)_gpioe->odr&=~(1<<13)

gpioe->odr&=~(1<<13)

第一种:指针形式

  1. led.c文件:
  2. #include "led.h"
  3. #include "stm32f4xx.h"
  4. void LED_Init(void)
  5. {
  6. //1左移五位既是将第五位置为1,查寄存器可知1是使能0失能
  7.     RCC->AHB1ENR|= 1<<5;//使能RCC的AHB1时钟
  8. //PF9 的GPIO配置
  9. //将(1 1)左移18位再取反清零:2代表两位控制一IO,因为IO是F9,所以最后是~(3<<2*9),达到清零效果
  10. GPIOF->MODER &= ~(3<<2*9);//配置为0用&,配置为1用 | 
  11.   GPIOF->MODER |= 1<<(2*9);//1既是0 1,代表输出模式(查寄存器)
  12.   GPIOF->OSPEEDR &= ~(3<<2*9);//同理,清零
  13.   GPIOF->OSPEEDR |= 2<<(2*9);//2是1 0,将F9设置为50MHZ的速度
  14.   GPIOF->PUPDR &= ~(3<<2*9);//清零
  15.   GPIOF->PUPDR |=1<<(2*9);//上拉
  16. GPIOF->OTYPER &= ~(1<<9);//清零,该寄存器是低16位有效,1位控制1个IO
  17. GPIOF->OTYPER |=0<<9;//置0,既是输出推挽(复位)
  18. GPIOF->ODR|= 1<<9;//1 控制高低电平
  19. //GPIOF->ODR&=~(1<<9);//
  20. //PF10         同理配置PF10
  21. GPIOF->MODER &= ~(3<<2*10);
  22. GPIOF->MODER |= 1<<(2*10);
  23.   GPIOF->OSPEEDR &= ~(3<<2*10);
  24.   GPIOF->OSPEEDR |= 2<<(2*10);
  25.   GPIOF->PUPDR &= ~(3<<2*10);
  26.   GPIOF->PUPDR |=1<<(2*10);
  27. GPIOF->OTYPER &= ~(1<<10);
  28. GPIOF->OTYPER |=0<<10;
  29. GPIOF->ODR|= 1<<10;
  30. }
  31. ///
  32. led.h文件:
  33. #ifndef __LED_H
  34. #define __LED_H
  35. void LED_Init(void);
  36. #endif
  37. ///
  38. main.c文件:
  39. #include "stm32f4xx.h"
  40. #include "led.h"
  41. #include "delay.h"
  42. int main(void)
  43. {
  44. delay_init(168);
  45. LED_Init();
  46. while(1)
  47. {
  48. GPIOF->ODR&=~(1<<9);
  49. GPIOF->ODR&=~(1<<10);
  50. delay_ms(500);
  51. GPIOF->ODR |= 1<<9;
  52. GPIOF->ODR |=1<<10;
  53. delay_ms(500);
  54. }
  55. }

------------------------------------------------------------------------------------------------------------------

第二种方法:配置基地址开始

  1. // 设置寄存器宏定义
  2. //1、时钟线
  3. #define RCC_AHB1ENR *(volatile unsigned long *)(0x40023800 + 0x30)  // volatile 防止编译器优化 AHB1外设使能时钟线
  4. #define GPIOF_MODER *(volatile unsigned long *)(0x40021400 + 0x00)  // GPIOF的模式寄存器
  5. #define GPIOF_OTYPER *(volatile unsigned long *)(0x40021400 + 0x04)  // GPIOF的输出类型寄存器
  6. #define GPIOF_OSPEEDR *(volatile unsigned long *)(0x40021400 + 0x08)  // GPIOF的输出速度寄存器PUPDR
  7. #define GPIOF_PUPDR *(volatile unsigned long *)(0x40021400 + 0x0c)  // GPIOF的上下拉寄存器
  8. #define GPIOF_ODR *(volatile unsigned long *)(0x40021400 + 0x14)  // GPIOF的输出数据寄存器
  9. #define GPIOF_BSRR *(volatile unsigned long *)(0x40021400 + 0x18)  // GPIOF的复位/置位寄存器
  10. #define GPIOE_MODER *(volatile unsigned long *)(0x40021000 + 0x00)  // GPIOF的模式寄存器
  11. #define GPIOE_OTYPER *(volatile unsigned long *)(0x40021000 + 0x04)  // GPIOF的输出类型寄存器
  12. #define GPIOE_OSPEEDR *(volatile unsigned long *)(0x40021000 + 0x08)  // GPIOF的输出速度寄存器PUPDR
  13. #define GPIOE_PUPDR *(volatile unsigned long *)(0x40021000 + 0x0c)  // GPIOF的上下拉寄存器
  14. #define GPIOE_ODR *(volatile unsigned long *)(0x40021000 + 0x14)  // GPIOF的输出数据寄存器
  15. #define GPIOE_BSRR *(volatile unsigned long *)(0x40021000 + 0x18)  // GPIOF的复位/置位寄存器
  16. // 大概时间的延时函数
  17. void delay(int n)
  18. {
  19. while(n--)
  20. {
  21. int i = 1000;
  22. while(i--);
  23. }
  24. }
  25. // 初始化LED
  26. int init_led(void)
  27. {
  28. // 2、初始化时钟、寄存器  第5位置1就是使能
  29. RCC_AHB1ENR |= 1<<5
  30. //3、配置寄存器各种参数,LED只是输出,所以选择每个参数里面的输出模式
  31. // ①初始化GPIOF为输出模式
  32. //---------------模式--移动位数
  33. GPIOF_MODER &= ~(0x3<<18);   // 清空第18位和19位  11
  34. GPIOF_MODER |= 1<<18; // 配置PF9
  35. //GPIOF_MODER &= ~(0xF<<18);   // 清空第18位和19位、20位、21位  1111
  36. //GPIOF_MODER |= 0x5<<18; // 配置PF9、PF10
  37. GPIOF_MODER &= ~(0x3<<20); // 清空第20位、21位   11
  38. GPIOF_MODER |= 1<<20;//配置PF10
  39. // ②配置GPIOF的输出类型为推挽
  40. GPIOF_OTYPER &= ~(0x1<<9);  // 清空第9位
  41. GPIOF_OTYPER &= ~(0x1<<10);  // 清空第10位
  42. // ③配置GPIOF的输出速度
  43. GPIOF_OSPEEDR &= ~(0x3<<18);  // 清空第18位和19位  11
  44. GPIOF_OSPEEDR &= ~(0x3<<20);  // 清空第20 21  11
  45. GPIOF_OSPEEDR |= 0x2<<18; // 50M速度
  46. GPIOF_OSPEEDR |= 0x2<<20; // 50M速度
  47. // ④配置 GPIOF为上拉输出
  48. GPIOF_PUPDR &= ~(0x3<<18);  // 清空第18位和19位  11
  49. GPIOF_PUPDR |= 1<<18; // 配置PF9为上拉输出
  50. GPIOF_PUPDR &= ~(0x3<<20);  // 清空第20位和21位  11
  51. GPIOF_PUPDR |= 1<<20; // 配置PF10为上拉输出
  52. // ⑤输出数据:高电平 1 低电平 0
  53. GPIOF_ODR |= 1<<9; // PF的第9个引脚输出高电平
  54. GPIOF_ODR |= 1<<10; // PF的第10个引脚输出高电平
  55. /*********************************PE脚**************************************/
  56. // 初始化时钟 寄存器第4位置1就是使能
  57. RCC_AHB1ENR |= 1<<4; //PE脚
  58. // 初始化GPIOF为输出模式
  59. GPIOE_MODER &= ~(0x3<<26);   // 清空第26位和27\28\29位  11
  60. GPIOE_MODER |= 1<<26; // 配置PF9, 1010即是5,可同时配置
  61. GPIOE_MODER &= ~(0x3<<28); // 清空第20位、21位   11
  62. GPIOE_MODER |= 1<<28;//配置PF10
  63. // 配置GPIOF的输出类型为推挽
  64. GPIOE_OTYPER &= ~(0x1<<13);  // 清空第9位
  65. GPIOE_OTYPER &= ~(0x1<<14);  // 清空第10位
  66. // 配置GPIOF的输出速度
  67. GPIOE_OSPEEDR &= ~(0x3<<26);  // 清空第18位和19位  11
  68. GPIOE_OSPEEDR &= ~(0x3<<28);  // 清空第20 21  11
  69. GPIOE_OSPEEDR |= 0x2<<26; // 50M速度
  70. GPIOE_OSPEEDR |= 0x2<<28; // 50M速度
  71. // 配置 GPIOF为上拉输出
  72. GPIOE_PUPDR &= ~(0x3<<26);  // 清空第18位和19位  11
  73. GPIOE_PUPDR |= 1<<26; // 配置PF9为上拉输出
  74. GPIOE_PUPDR &= ~(0x3<<28);  // 清空第20位和21位  11
  75. GPIOE_PUPDR |= 1<<28 ;// 配置PF10为上拉输出
  76. // 输出数据:高电平 1 低电平 0
  77. GPIOE_ODR |= 1<<13; // PF的第9个引脚输出高电平
  78. GPIOE_ODR |= 1<<14; // PF的第10个引脚输出高电平
  79. return 0;
  80. }
  81. int main(void)
  82. {
  83. // 初始化LED
  84. init_led();
  85.   while (1)
  86.   {
  87. // 点亮LED0
  88. GPIOF_ODR &= ~(1<<9); // PF的第9个引脚输出低电平
  89. delay(2000);
  90. GPIOF_ODR |= 1<<9;
  91. delay(2000);
  92.  
  93. // 输出数据:高电平 1 低电平 0
  94. GPIOF_ODR &= ~(1<<10);
  95. delay(2000);
  96. GPIOF_ODR |= 1<<10; // PF的第9个引脚输出高电平
  97. delay(2000);
  98.  
  99. GPIOE_ODR &= ~(1<<13);
  100. delay(2000);
  101. GPIOE_ODR |= 1<<13; // PE的第13、14个引脚输出高电平
  102. delay(2000);
  103.  
  104. GPIOE_ODR &= ~(1<<14);
  105. delay(2000);
  106. GPIOE_ODR |= 1<<14;
  107. delay(2000); 
  108.   }
  109. }

两者的区别在于一个需要配置基地址,一个直接用指针对寄存器进行操作,那怎样配置基地址,下面解释一下:

    1、根据STM32F4xx中文参考手册的2.3节存储器的映射找到对应总线、外设的边界基地址,我这里只截了部分图,仅供参考

  2、找到对应寄存器的偏移地址,在STM32F4xx中文参考手册7.4节

配置后如下所示:

  2、最后对应寄存器进行对其位移操作即可(寄存器映射),可参考上面的代码


总结:这里以一个简单的LED闪烁来了解对寄存器进行具体的操作,使自己能够用寄存器来进行项目的开发,其他的外设配置是一样的原理。

 

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/309557
推荐阅读
相关标签
  

闽ICP备14008679号