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

流水灯(标准库函数)

[复制链接]
STMCU小助手 发布时间:2022-11-28 14:41
知识点
GPIO 寄存器
  1. typedef struct
  2. {
  3.   __IO uint32_t CRL;
  4.   __IO uint32_t CRH;
  5.   __IO uint32_t IDR;
  6.   __IO uint32_t ODR;
  7.   __IO uint32_t BSRR;
  8.   __IO uint32_t BRR;
  9.   __IO uint32_t LCKR;
  10. } GPIO_TypeDef;
  11. typedef struct
  12. {
  13. vu32 EVCR;
  14. vu32 MAPR;
  15. vu32 EXTICR[4];
  16. } AFIO_TypeDef;
复制代码

640 (13).png
基地址
  1. #define PERIPH_BASE ((u32)0x40000000)
  2. #define APB1PERIPH_BASE PERIPH_BASE
  3. #define APB2PERIPH_BASE (PERIPH_BASE + 0x10000)
  4. #define AHBPERIPH_BASE (PERIPH_BASE + 0x20000)

  5. #define AFIO_BASE (APB2PERIPH_BASE + 0x0000)
  6. #define GPIOA_BASE (APB2PERIPH_BASE + 0x0800)
  7. #define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00)
  8. #define GPIOC_BASE (APB2PERIPH_BASE + 0x1000)
  9. #define GPIOD_BASE (APB2PERIPH_BASE + 0x1400)
  10. #define GPIOE_BASE (APB2PERIPH_BASE + 0x1800)
复制代码

外设
  1. #define TIM2                ((TIM_TypeDef *) TIM2_BASE)
  2. #define TIM3                ((TIM_TypeDef *) TIM3_BASE)
  3. #define TIM4                ((TIM_TypeDef *) TIM4_BASE)
  4. #define TIM5                ((TIM_TypeDef *) TIM5_BASE)
  5. #define TIM6                ((TIM_TypeDef *) TIM6_BASE)
  6. #define TIM7                ((TIM_TypeDef *) TIM7_BASE)
  7. #define TIM12               ((TIM_TypeDef *) TIM12_BASE)
  8. #define TIM13               ((TIM_TypeDef *) TIM13_BASE)
  9. #define TIM14               ((TIM_TypeDef *) TIM14_BASE)
  10. #define RTC                 ((RTC_TypeDef *) RTC_BASE)
  11. #define WWDG                ((WWDG_TypeDef *) WWDG_BASE)
  12. #define IWDG                ((IWDG_TypeDef *) IWDG_BASE)
  13. #define SPI2                ((SPI_TypeDef *) SPI2_BASE)
  14. #define SPI3                ((SPI_TypeDef *) SPI3_BASE)
  15. #define USART2              ((USART_TypeDef *) USART2_BASE)
  16. #define USART3              ((USART_TypeDef *) USART3_BASE)
  17. #define UART4               ((USART_TypeDef *) UART4_BASE)
  18. #define UART5               ((USART_TypeDef *) UART5_BASE)
  19. #define I2C1                ((I2C_TypeDef *) I2C1_BASE)
  20. #define I2C2                ((I2C_TypeDef *) I2C2_BASE)
  21. #define CAN1                ((CAN_TypeDef *) CAN1_BASE)
  22. #define CAN2                ((CAN_TypeDef *) CAN2_BASE)
  23. #define BKP                 ((BKP_TypeDef *) BKP_BASE)
  24. #define PWR                 ((PWR_TypeDef *) PWR_BASE)
  25. #define DAC                 ((DAC_TypeDef *) DAC_BASE)
  26. #define CEC                 ((CEC_TypeDef *) CEC_BASE)
  27. #define AFIO                ((AFIO_TypeDef *) AFIO_BASE)
  28. #define EXTI                ((EXTI_TypeDef *) EXTI_BASE)
  29. #define GPIOA               ((GPIO_TypeDef *) GPIOA_BASE)
  30. #define GPIOB               ((GPIO_TypeDef *) GPIOB_BASE)
  31. #define GPIOC               ((GPIO_TypeDef *) GPIOC_BASE)
  32. #define GPIOD               ((GPIO_TypeDef *) GPIOD_BASE)
  33. #define GPIOE               ((GPIO_TypeDef *) GPIOE_BASE)
  34. #define GPIOF               ((GPIO_TypeDef *) GPIOF_BASE)
  35. #define GPIOG               ((GPIO_TypeDef *) GPIOG_BASE)
  36. #define ADC1                ((ADC_TypeDef *) ADC1_BASE)
  37. #define ADC2                ((ADC_TypeDef *) ADC2_BASE)
  38. #define TIM1                ((TIM_TypeDef *) TIM1_BASE)
  39. #define SPI1                ((SPI_TypeDef *) SPI1_BASE)
  40. #define TIM8                ((TIM_TypeDef *) TIM8_BASE)
  41. #define USART1              ((USART_TypeDef *) USART1_BASE)
  42. #define ADC3                ((ADC_TypeDef *) ADC3_BASE)
  43. #define TIM15               ((TIM_TypeDef *) TIM15_BASE)
  44. #define TIM16               ((TIM_TypeDef *) TIM16_BASE)
  45. #define TIM17               ((TIM_TypeDef *) TIM17_BASE)
  46. #define TIM9                ((TIM_TypeDef *) TIM9_BASE)
  47. #define TIM10               ((TIM_TypeDef *) TIM10_BASE)
  48. #define TIM11               ((TIM_TypeDef *) TIM11_BASE)
  49. #define SDIO                ((SDIO_TypeDef *) SDIO_BASE)
  50. #define DMA1                ((DMA_TypeDef *) DMA1_BASE)
  51. #define DMA2                ((DMA_TypeDef *) DMA2_BASE)
  52. #define DMA1_Channel1       ((DMA_Channel_TypeDef *) DMA1_Channel1_BASE)
  53. #define DMA1_Channel2       ((DMA_Channel_TypeDef *) DMA1_Channel2_BASE)
  54. #define DMA1_Channel3       ((DMA_Channel_TypeDef *) DMA1_Channel3_BASE)
  55. #define DMA1_Channel4       ((DMA_Channel_TypeDef *) DMA1_Channel4_BASE)
  56. #define DMA1_Channel5       ((DMA_Channel_TypeDef *) DMA1_Channel5_BASE)
  57. #define DMA1_Channel6       ((DMA_Channel_TypeDef *) DMA1_Channel6_BASE)
  58. #define DMA1_Channel7       ((DMA_Channel_TypeDef *) DMA1_Channel7_BASE)
  59. #define DMA2_Channel1       ((DMA_Channel_TypeDef *) DMA2_Channel1_BASE)
  60. #define DMA2_Channel2       ((DMA_Channel_TypeDef *) DMA2_Channel2_BASE)
  61. #define DMA2_Channel3       ((DMA_Channel_TypeDef *) DMA2_Channel3_BASE)
  62. #define DMA2_Channel4       ((DMA_Channel_TypeDef *) DMA2_Channel4_BASE)
  63. #define DMA2_Channel5       ((DMA_Channel_TypeDef *) DMA2_Channel5_BASE)
  64. #define RCC                 ((RCC_TypeDef *) RCC_BASE)
  65. #define CRC                 ((CRC_TypeDef *) CRC_BASE)
  66. #define FLASH               ((FLASH_TypeDef *) FLASH_R_BASE)
  67. #define OB                  ((OB_TypeDef *) OB_BASE)
  68. #define ETH                 ((ETH_TypeDef *) ETH_BASE)
  69. #define FSMC_Bank1          ((FSMC_Bank1_TypeDef *) FSMC_Bank1_R_BASE)
  70. #define FSMC_Bank1E         ((FSMC_Bank1E_TypeDef *) FSMC_Bank1E_R_BASE)
  71. #define FSMC_Bank2          ((FSMC_Bank2_TypeDef *) FSMC_Bank2_R_BASE)
  72. #define FSMC_Bank3          ((FSMC_Bank3_TypeDef *) FSMC_Bank3_R_BASE)
  73. #define FSMC_Bank4          ((FSMC_Bank4_TypeDef *) FSMC_Bank4_R_BASE)
  74. #define DBGMCU              ((DBGMCU_TypeDef *) DBGMCU_BASE)
复制代码

这里就已经把GPIOx的类型变为结构体GPIO_TypeDef,地址变为GPIOx_BASE;
比如使用时可以 用GPIOC->ODR这样。

输入模式(上拉、下拉、浮空、模拟)
在输入模式时,施密特触发器打开,输出被禁止,可通过输入数据寄存器 GPIOx_IDR读取 I/O 状态。其中输入模式,可设置为上拉、下拉、浮空和模拟输入四种。上拉和下拉输入很好理解,默认的电平由上拉或者下拉决定。浮空输入的电平是不确定的,完全由外部的输入决定,一般接按键的时候用的是这个模式。模拟输入则用于 ADC 采集。

输出模式(推挽/开漏)
在输出模式中,推挽模式时双 MOS 管以轮流方式工作,输出数据寄存器 GPIOx_ODR可控制 I/O 输出高低电平。开漏模式时,只有 N-MOS 管工作,输出数据寄存器可控制 I/O输出高阻态或低电平。输出速度可配置,有2MHz\10MHz\50MHz的选项。此处的输出速度即 I/O 支持的高低电平状态最高切换频率,支持的频率越高,功耗越大,如果功耗要求不严格,把速度设置成最大即可。在输出模式时施密特触发器是打开的,即输入可用,通过输入数据寄存器 GPIOx_IDR可读取 I/O 的实际状态。

复用功能(推挽/开漏)
复用功能模式中,输出使能,输出速度可配置,可工作在开漏及推挽模式,但是输出信号源于其它外设,输出数据寄存器GPIOx_ODR 无效;输入可用,通过输入数据寄存器可获取 I/O 实际状态,但一般直接用外设的寄存器来获取该数据信号。
通过对 GPIO寄存器写入不同的参数,就可以改变 GPIO的工作模式,再强调一下,要了解具体寄存器时一定要查阅《STM32F10X-中文参考手册》中对应外设的寄存器说明。
在 GPIO外设中,控制端口高低控制寄存器 CRH和 CRL可以配置每个 GPIO 的工作模式和工作的速度,每 4个位控制一个 IO,CRH控制端口的高八位,CRL控制端口的低 8位,具体的看 CRH和 CRL的寄存器描述

640 (12).png

640 (11).png

  1. typedef enum
  2. {
  3. GPIO_Mode_AIN = 0x0, // 模拟输入
  4. GPIO_Mode_IN_FLOATING = 0x04, // 浮空输入
  5. GPIO_Mode_IPD = 0x28, // 下拉输入
  6. GPIO_Mode_IPU = 0x48, // 上拉输入
  7. GPIO_Mode_Out_OD = 0x14, // 开漏输出
  8. GPIO_Mode_Out_PP = 0x10, // 推挽输出
  9. GPIO_Mode_AF_OD = 0x1C, // 复用开漏输出
  10. GPIO_Mode_AF_PP = 0x18 // 复用推挽输出
  11. } GPIOMode_TypeDef;
复制代码
  1. typedef enum
  2. {
  3.   GPIO_Speed_10MHz = 1,
  4.   GPIO_Speed_2MHz,
  5.   GPIO_Speed_50MHz
  6. }GPIOSpeed_TypeDef;
复制代码


改变GPIO引脚状态

640 (10).png

1、高16位和低16位,只能以16位形式操作。
2、高16位用于置 0,低16位用于置 1。(高16位用于置0,低16位用于1置1,相应位设1才有效)
3、各个位对 0 操作是免疫的
比如控制PC13:
输出高电平 1<<13
输出低电平 1<<(13+16)


640 (9).png
640 (8).png

只有低16位有效,在相应位置写 1 时,可以输出一个低电平。


通过这两个寄存器,我们就可以控制一个GPIO引脚输出高低电平,最简单的可以使用BSRR输出高电平,用BRR输出低电平。

  1. GPIOC ->BSRR |=1<<13;
复制代码

用函数控制引脚输出高电平
640 (7).png
用函数控制输出低电平
640 (6).png

GPIO_Init()函数函数讲解
函数讲解

作用:根据 GPIO_InitStruct 中指定的参数初始化外设 GPIOx 寄存器。


640 (5).png

GPIO_Init()函数就是配置引脚的四个位,再将四个位写入到对应引脚的寄存器。

库函数中的此函数代码如下图。


640 (4).png

函数分析:

  • 确定currentmode 的值。
  • 判断输入还是输出,如果是输出,添加速度值。
  • 配置低八位。
  • 配置高八位。


函数使用例子

比如设定:PA2推挽输出,输出速度50NHz;
用库函数定义的代码和实际赋值如下图:


640 (3).png

0b:32位
640 (2).png

库函数理解
640 (1).png

库函数是控制寄存器操作的语句被封装成函数的函数集合,需要执行相应动作的时候只需要调用函数(并填入参数)即可。
实例操作
工 程在这里分为三个程序。main.c     ;LED.h  ;LED.c
思路:
一:打开引脚对应的时钟。
二:配置输出,确定输出模式
三:输出高电平或者低电平

LED.h
  1. #ifndef __LED_H//此处是表示当我们没有定义LED这个名字时,一下这个程序才被使用
  2. #define __LED_H
  3. #include "stm32f10x.h"//头文件
  4. #define LED_G_GPIO_PIN          GPIO_Pin_0//定义LED灯G的管脚
  5. #define LED_B_GPIO_PIN          GPIO_Pin_1//定义LED灯B的管脚
  6. #define LED_R_GPIO_PIN          GPIO_Pin_5//定义LED灯R的管脚
  7. #define LED_GPIO_PORT           GPIOB
  8. #define LED_GPIO_CLK            RCC_APB2Periph_GPIOB
  9. #define    ON        1
  10. #define    OFF       0
  11. //    \表示换行符
  12. //ResetBits可用于输出低电平
  13. //SetBits  可用于输出高电平
  14. #define   LED_G(a)   if(a) \
  15.                         GPIO_ResetBits(LED_GPIO_PORT, LED_G_GPIO_PIN); \
  16.                      else  GPIO_SetBits(LED_GPIO_PORT, LED_G_GPIO_PIN);
  17. #define   LED_B(a)   if(a) \
  18.                         GPIO_ResetBits(LED_GPIO_PORT, LED_B_GPIO_PIN); \
  19.                      else  GPIO_SetBits(LED_GPIO_PORT, LED_B_GPIO_PIN);
  20. #define   LED_R(a)   if(a)\
  21.                        GPIO_ResetBits(LED_GPIO_PORT, LED_R_GPIO_PIN); \
  22.                      else  GPIO_SetBits(LED_GPIO_PORT, LED_R_GPIO_PIN);
  23. void LED_GPIO_Config(void);
  24. #endif /* __LED_H */
复制代码

LED.c
  1. #include "LED.h"
  2. void LED_GPIO_Config(void)
  3. {
  4. /*定义3个GPIO_InitTypeDef 类型的结构体*/
  5. GPIO_InitTypeDef  GPIO_InitStruct1;
  6. GPIO_InitTypeDef  GPIO_InitStruct2;
  7. GPIO_InitTypeDef  GPIO_InitStruct3;
  8. /*开启 LED 相关的 GPIO 外设时钟*/
  9. RCC_APB2PeriphClockCmd(LED_GPIO_CLK, ENABLE);
  10. GPIO_InitStruct1.GPIO_Pin = LED_G_GPIO_PIN;//赋值为相应管脚的地址
  11. GPIO_InitStruct2.GPIO_Pin = LED_B_GPIO_PIN;
  12. GPIO_InitStruct3.GPIO_Pin = LED_R_GPIO_PIN;
  13. GPIO_InitStruct1.GPIO_Mode = GPIO_Mode_Out_PP;//其实就是赋值为0x10;
  14. GPIO_InitStruct1.GPIO_Speed = GPIO_Speed_50MHz;//赋值为3
  15. GPIO_InitStruct2.GPIO_Mode = GPIO_Mode_Out_PP;
  16. GPIO_InitStruct2.GPIO_Speed = GPIO_Speed_50MHz;
  17. GPIO_InitStruct3.GPIO_Mode = GPIO_Mode_Out_PP;
  18. GPIO_InitStruct3.GPIO_Speed = GPIO_Speed_50MHz;
  19. GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct1);
  20. GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct2);
  21. GPIO_Init(LED_GPIO_PORT, &GPIO_InitStruct3);
  22. }
复制代码

main.c
  1. #include "stm32f10x.h"   // 相当于51单片机中的  #include <reg51.h>
  2. #include "LED.h"
  3. void Delay( uint32_t count )
  4. {
  5. for(; count!=0; count--);
  6. }
  7. int main(void)
  8. {
  9.   LED_GPIO_Config();
  10. while(1)
  11. {
  12.   LED_G(OFF);
  13.   LED_B(OFF);
  14.   LED_R(OFF);
  15.   Delay(0xFFFFF);
  16.   LED_G(ON);
  17.   Delay(0xFFFFF);
  18.   LED_G(OFF);
  19.   Delay(0xFFFFF);
  20.   LED_B(ON);
  21.   Delay(0xFFFFF);
  22.   LED_B(OFF);
  23.   Delay(0xFFFFF);
  24.   LED_R(ON);
  25.   Delay(0xFFFFF);
  26.   LED_R(OFF);  
  27. }
  28. }
复制代码

仿真图
640.png

转载自: 跋扈洋


收藏 评论0 发布时间:2022-11-28 14:41

举报

0个回答

所属标签

相似分享

官网相关资源

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