STM32精英版(正点原子STM32F103ZET6开发板)学习篇2——GPIO

前提

芯片引脚数量

  STM32F103ZET6为:144脚芯片。一共有7组IO口(GPIOA~GPIOG),每组IO口有16个IO(PA0 ~ PA16),共计16*7=112个IO.
在这里插入图片描述
   STM32的大部分引脚除了当GPIO使用外,还有一些特殊功能
   1、端口复用功能:所谓复用,就是一些端口不仅仅可以做为通用IO口,还可以复用为一些外设引脚,比如PA9,PA10可以复用为STM32的串口1引脚。
   作用:最大限度的利用端口资源。
在这里插入图片描述
   2、端口重映射功能:就是可以把某些功能引脚映射到其他引脚。 比如串口1默认引脚是PA9,PA10可以通过配置重映射映射到PB6,PB7
  作用:方便布线
在这里插入图片描述
   3、所有IO口都可以作为中断输入

GPIO工作方式(8种)

  4种输入模式:

     输入浮空:GPIO_Mode_IN_FLOATING
     输入上拉:GPIO_Mode_IPU
     输入下拉:GPIO_Mode_IPD
     模拟输入:GPIO_Mode_AIN

  4种输出模式:

     开漏输出:GPIO_Mode_Out_OD
(开漏,就等于输出口接了个NPN三极管,并且只接了e,b. c极 是开路的,你可以接一个电阻到3.3V,也可以接一个电阻到5V,这样,在输出1的时候,就可以是5V电压,也可以是3.3V电压了.但是不接电阻上拉的时候,这个输出高就不能实现了. )
(只可以输出强低电平,高电平得靠外部电阻拉高。输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内)

     开漏复用功能:GPIO_Mode_AF_OD
     推挽式输出:GPIO_Mode_Out_PP
(推挽,就是有推有拉,任何时候IO口的电平都是确定的,不需要外接上拉或者下拉电阻. )
(推挽电路是两个参数相同的三极管或MOSFET,以推挽方式存在于电路中,各负责正负半周的波形放大任务,电路工作时,两只对称的功率开关管每次只有一个导通,所以导通损耗小、效率高。输出既可以向负载灌电流,也可以从负载抽取电流。推拉式输出级既提高电路的负载能力,又提高开关速度。 )
(可以输出强高低电平,连接数字器件

     推挽式复用功能:GPIO_Mode_AF_PP

  3种最大翻转速度:

     -2MHZ
     -10MHz
     -50MHz
参考网址:http://www.openedv.com/posts/list/21980.htm(有空在回来看)

GPIO基本结构

在这里插入图片描述

GPIO的输入工作模式1—输入浮空模式

在这里插入图片描述

GPIO的输入工作模式2—输入上拉模式

在这里插入图片描述

GPIO的输入工作模式3—输入下拉模式

在这里插入图片描述

GPIO的输入工作模式4—模拟模式

在这里插入图片描述

GPIO的输出工作模式1—开漏输出模式

在这里插入图片描述

GPIO的输出工作模式2—开漏复用输出模式

在这里插入图片描述

GPIO的输出工作模式3—推挽输出模式

在这里插入图片描述

GPIO的输出工作模式4—推挽复用输出模式

在这里插入图片描述
上电复位后,GPIO默认为浮空状态,部分特殊功能引脚为特定状态。
在这里插入图片描述

GPIO相关配置寄存器

  是每组IO口含下面7个寄存器。也就是7个寄存器,一共可以控制一组GPIO的16个IO口。

  每组GPIO端口的寄存器包括:
    两个32位配置寄存器(GPIOx_CRL ,GPIOx_CRH) ,
    两个32位数据寄存器 (GPIOx_IDR和GPIOx_ODR),
    一个32位置位/ 复位寄存器(GPIOx_BSRR),
    一个16位复位寄存器(GPIOx_BRR),
    一个32位锁定寄存器(GPIOx_LCKR)。
每个I/O端口位可以自由编程,然而I/O端口寄存器必须按32位字被访问(不允许半字或字节访问)
两个32位配置寄存器,每个IO口只需要4位,64/4=16个IO。

    - GPIOx_CRL :端口配置低寄存器
    - GPIOx_CRH:端口配置高寄存器
    - GPIOx_IDR:端口输入寄存器
    - GPIOx_ODR:端口输出寄存器
    - GPIOx_BSRR:端口位设置/清除寄存器
     - GPIOx_BRR :端口位清除寄存器
    - GPIOx_LCKR:端口配置锁存寄存器

端口配置低寄存器(GPIOx_CRL)

在这里插入图片描述
  已知配置寄存器为32位,两位为一个空格。可分为上图的16个空格,每两个空格(4位)设置IO口,寄存器CRL可控制0~7的口,下面寄存器CRH可控制8 ~15的口。
  具体的位根据不同的数值可设置为不同的模式,根据上下图可知。
  根据图可知,上下拉电阻是根据寄存器ODR进行设置的。
在这里插入图片描述

端口配置高寄存器(GPIOx_CRH)

在这里插入图片描述
在这里插入图片描述

端口输入数据寄存器(GPIOx_IDR)

在这里插入图片描述
  每一组IO都有这样的一个寄存器(一组16个IO口),输入数据寄存器IDR(控制IO口输入)是32位,低16位的每位都是代表的对应组的IO口,输入为0则对应IO口输入为低电平,输入为1则对应IO口输入为高电平。

端口输出数据寄存器(GPIOx_ODR)

在这里插入图片描述
在这里插入图片描述
  当为输出模式时,每一组IO都有这样的一个寄存器(一组16个IO口),输出数据寄存器ODR(控制IO口输出)是32位,低16位的每位都是代表的对应组的IO口,输出为0则对应IO口输出为低电平,输出为1则对应IO口输出为高电平。
  当为输入模式时,用寄存器ODR进行设置上拉电阻还是下拉电阻。

端口位设置/清除寄存器(GPIOx_BSRR)

在这里插入图片描述
  该寄存器也是用来设置IO口的高低电平。
  BSRR寄存器低16位,对应位设置为1,那么IO扣输出为高电平,对应位设置为0,对应IO口不产生任何影响。
  高16位作用相反。
  可查看开漏输出模式的原理图,通过寄存器BSRR来间接设置寄存器ODR
可知道我们只需要设置为0则不产生任何影响的作用就是可以帮助我们简单的单独对应引脚的高低电平且不对其他引脚有影响

端口位清除寄存器(GPIOx_BRR)

在这里插入图片描述
  寄存器BRR低16位的作用与寄存器BSRR高16位的作用是一样的,所以一般我们都是用寄存器BRR和寄存器BSRR两个的低16位进行设置。

### 使用STM32F103ZET6开发板正点原子)控制DS3115舵机 #### 一、硬件准备 要使用STM32F103ZET6开发板来控制DS3115舵机,需准备好以下材料: - STM32F103ZET6开发板正点原子) - DS3115舵机 - 杜邦线若干 - 连接电源适配器或电池盒提供稳定供电给舵机 确保所有组件都已正确连接。通常情况下,舵机会有三条线:红色为电源正极(VCC),棕色为接地(GND),橙色为PWM信号线(PWM)[^3]。 #### 二、软件设置 对于STM32CubeMX初始化配置: 1. 打开STM32CubeMX并创建新工程; 2. 配置时钟源及时钟频率; 3. 设置TIMx定时器用于生成PWM波形,其中x取决于具体使用的引脚对应的定时器通道; 4. 将GPIO端口配置成复用推挽输出模式以便发送PWM脉冲宽度调制信号给舵机; 编译环境推荐使用Keil MDK或其他兼容IDE进行编程工作。 #### 三、编写程序逻辑 下面给出一段简单的C语言代码片段展示如何通过调整占空比改变舵机角度位置: ```c #include "stm32f1xx_hal.h" // 定义PWM参数 #define PWM_FREQUENCY_HZ (50U) /* 脉宽调制频率 */ #define MIN_DUTY_CYCLE (5U * 100 / 20) /* 最小占空比对应的角度范围起点(约等于0度) */ #define MAX_DUTY_CYCLE (7.5U * 100 / 20) /* 中间位置 */ #define MAX_ANGLE (180U) void Servo_Init(TIM_HandleTypeDef* htim, uint32_t channel); float Map(float value, float fromLow, float fromHigh, float toLow, float toHigh); int main(void){ HAL_Init(); // 初始化系统时钟 __HAL_RCC_TIM1_CLK_ENABLE(); // 启用定时器外设时钟 TIM_HandleTypeDef TimHandle; TimHandle.Instance = TIM1; // 设定实例化对象关联的定时器编号 TimHandle.Init.Prescaler = 72 - 1; // APB1分频系数设定预分频值使得计数周期大约为1us TimHandle.Init.CounterMode = TIM_COUNTERMODE_UP; TimHandle.Init.Period = ((SystemCoreClock / 72) / PWM_FREQUENCY_HZ)-1 ;// 计算自动重装载寄存器ARR数值使溢出时间间隔约为20ms TimHandle.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; TimHandle.Init.RepetitionCounter = 0; if(HAL_TIM_PWM_Init(&TimHandle)!= HAL_OK){while(1);} Servo_Init(&TimHandle,TIM_CHANNEL_1); while (1){ static int angle=0; angle++; if(angle>MAX_ANGLE)angle=0; uint32_t duty_cycle=(uint32_t)(Map((float)angle,(float)0,(float)MAX_ANGLE, (float)MIN_DUTY_CYCLE,(float)MAX_DUTY_CYCLE)*htim->Instance->ARR/100); __HAL_TIM_SET_COMPARE(htim,channel,duty_cycle); HAL_Delay(20); } } /** * @brief 初始化指定定时器通道为PWM模式. * @param htim: 指向定时器句柄结构体指针. * @param Channel: 定时器通道号. * @retval None */ static void Servo_Init(TIM_HandleTypeDef* htim,uint32_t Channel){ TIM_OC_InitTypeDef sConfigOC; sConfigOC.OCMode = TIM_OCMODE_PWM1; sConfigOC.Pulse = 0; sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH; sConfigOC.OCFastMode = TIM_OCFAST_DISABLE; HAL_TIM_PWM_ConfigChannel(htim,&sConfigOC,Channel); } ``` 此段代码实现了从0°到180°连续旋转的功能,并且每经过20毫秒增加一度角直到回到起始状态循环往复[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值