STM32 -- 笔记一 -- CLK、GPIO、PWM

本文详细介绍了STM32微控制器的基础知识,包括时钟源、系统时钟分频原理及GPIO配置等内容。针对不同应用场景,提供了GPIO模式选择指导,并解释了PWM的工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

特别说明一下:像是STM32,在进行实际操作时很多情况都是读写寄存器,根据不同的情况对寄存器进行操作,并且,STM32的寄存器数量比较多,带着那些外设,所以我在记录这份笔记时,尽量简略关于寄存器的操作流程,把一些功能的函数实现,要注意的细节等进行笔记记录。

时钟

时钟源:HSI、HSE、LSI、LSE、PLL
时钟频率都不一样。

为什么要多个时钟源?
A:STM32拥有者丰富的外设,这些外设需要的时钟频率不一定都要有系统时钟那么高,像是看门狗,只需要几十k的时钟频率即可。并且,同一个电路,时钟越快功耗越大,同时,抗电磁干扰能力也会越弱。

系统时钟SYSCLK的分频:

  • 通过AHB分频器分频以后送给各模块使用
  • 模块包括总线,内核,内存,DMA等
  • 送给APB1分频器。APB1分频器输出一路供APB1外设使用(PCLK1,最大频率36Hz),另一路送给定时器2/3/4倍频器使用
  • 送给APB2分频器。APB2分频器输出一路供APB2外设使用(PCLK2,最大频率72Hz),另一路送给定时器1倍频器使用

这里要注意APB1余APB2的区别:
APB1连接的是低速外设,包括:电源接口、备份接口、CAN、USB、I2C1、I2C2、UART2、UART3等
APB2连接的是高速外设,包括:UART1、SPI1、Timer1、ADC1、ADC2、所有普通的IO口(PA~PE)、第二功能IO口等

GPIO

函数设置的GPIO_InitTypeDef 结构体内部的变量

  • GPIO_Pin;GPIO对应的引脚
    • GPIO_Pin_5,GPIO_Pin_6,GPIO_Pin_7
  • GPIO_Speed;输出的频率
    • GPIO_Speed_10MHz 最高输出速率10MHz
    • GPIO_Speed_2MHz 最高输出速率2MHz
    • GPIO_Speed_50MHz 最高输出速率50MHz
  • GPIO_Mode;输入输出的模式
    • GPIO_Mode_AIN 模拟输入
    • GPIO_Mode_IN_FLOATING 浮空输入
    • GPIO_Mode_IPD 下拉输入
    • GPIO_Mode_IPU 上拉输入
    • GPIO_Mode_Out_OD 开漏输出
    • GPIO_Mode_Out_PP 推挽输出
    • GPIO_Mode_AF_OD 复用开漏输出
    • GPIO_Mode_AF_PP 复用推挽输出

在STM32中选用IO模式
(1) 浮空输入_IN_FLOATING ——浮空输入,可以做KEY识别,RX1
(2)带上拉输入_IPU——IO内部上拉电阻输入
(3)带下拉输入_IPD—— IO内部下拉电阻输入
(4) 模拟输入_AIN ——应用ADC模拟输入,或者低功耗下省电
(5)开漏输出_OUT_OD ——IO输出0接GND,IO输出1,悬空,需要外接上拉电阻,才能实现输出高电平。当输出为1时,IO口的状态由上拉电阻拉高电平,但由于是开漏输出模式,这样IO口也就可以由外部电路改变为低电平或不变 。可以读IO输入电平变化,实现C51的IO双向功能
(6)推挽输出_OUT_PP ——IO输出0-接GND, IO输出1 -接VCC,读输入值是未知的
(7)复用功能的推挽输出_AF_PP ——片内外设功能(I2C的SCL,SDA)
(8)复用功能的开漏输出_AF_OD——片内外设功能(TX1,MOSI,MISO.SCK.SS)

关于GPIO的上拉与下拉:
设置GPIO引脚为上拉模式时默认为高电平,设置GPIO引脚为下拉模式时默认为低电平。
控制对应的引脚如果高有效那么我们就下拉,如果低有效那么就上拉
上拉电阻有时是用来解决总线驱动能力不足时提供电流的,一般说法是拉电流;下拉电阻是用来吸收电流的,也就是灌电流。比如有I2C总线使用会上拉一个10k的电阻。
关于GPIO的上拉与下拉的设置我们可以看一个实例:按键所在的GPIO引脚,设置GPIO为输入功能,低电平有效,那么我们可以将其设置为上拉功能,这样我们在使用GPIO_INIT函数对引脚进行初始化后,引脚默认的电平值即为高电平,待发生按键事件时,引脚电压为低电平。

注意,在进行GPIO引脚的电压读取时,有的时候会要求读取输出电平值或者输入电平值,分别对应函数为:

GPIO_ReadOutputDataBit(GPIOC, GPIO_Pin_3)//读取输出电平值
GPIO_ReadInputDataBit(GPIOC, GPIO_Pin_2)//读取输入电平值

如果程序在关于调用读取输出或者输入电平值时写错,那么很可能读取到的电平值是一个不变的电平值,不会随着引脚的输出输入电平值改变。

GPIO引脚:
设为输入功能时,可以设置为浮动输入或者上拉输入两种方式。浮动输入是 GPIO 的管脚的电平状态是不确定的,容易受到外部电平的干扰;上拉输入时,管脚的电平则只有高电平或低电平两种确定的状态。一般I/O 做外部中断输入时要设置为上拉输入,做 A/D 转换时要设置为浮动输入。

设为输出功能时,可以设置为推挽输出或者开漏输出两种方式。推挽输出方式能够独立的输出高电平和低电平,适合驱动数字器件;开漏输出可以稳定的输出低电平,能承受大的灌电流,但是开漏输出无法输出高电平,需要外接上拉电阻才可以输出高电平,输出的高电平则有外接的上拉电平决定,这种输出方式适合做电流型驱动。

PWM

简介

利用数字输出来对模拟电路进行控制,简单说就是对脉冲宽度的控制。

这个简介比较难懂,简单说就是在对应的引脚产生类似于方波似的波形,可以通过设置相应的参数直接来控制波形的周期,以及高电平在整个波形中所占的比例。

STM32的定时器可以用来产生PWM输出,除了TIM6余TIM7以外。并且定时器可以产生好几路的PWM输出。

GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable , ENABLE);

注意,这个语句可以使原有的下载用的引脚失能。将其下载功能的引脚变更为普通的GPIO引脚。

PPS:关于屏蔽了STM32下载引脚的解决方案
只是禁止了JTAG下载,没有禁止SWD,将工具(JLINK或STLINK)设置为SWD方式即可下载仿真了。
另一个方法:将BOOT0脚和BOOT1脚接3.3V,断电再重新上电,就能使用仿真了,JTAG方式和SWD方式都可以用,这是因为这种方法是由RAM启动,所以之前你烧进去的程序是不会运行的,也就不存在JTAG被禁止。
boot0拉高,直接下载就可以了。这里看了一下电路,BOOT1连接的是3.3V,只需要将BOOT0的引脚进行拉高,这种与第二种方案一样。

<think>我们正在处理个关于步进电机驱动的问题,用户需要A4988SETTR-T与STM32F030K6T6配合的示例代码和接线方式。首先,我们需要了解A4988SETTR-T是个步进电机驱动芯片,常用于驱动双极步进电机。STM32F030K6T6是款ARMCortex-M0微控制器。接线方式:A4988需要连接步进电机的两个线圈(每个线圈两根线,共四线)。同时,需要连接控制信号:步进脉冲(STEP)、方向(DIR)、使能(ENABLE)等。STM32F030K6T6的GPIO引脚可以输出这些控制信号。典型接线:步进电机:线圈A+->A4988的1A(或OUT1A)线圈A-->A4988的1B(或OUT1B)线圈B+->A4988的2A(或OUT2A)线圈B-->A4988的2B(或OUT2B)A4988的电源:VMOT:电机电源(根据电机电压,注意要加电容滤波)GND:电机电源地VDD:逻辑电源(3.3V或5V,由于STM32是3.3V,建议用3.3V)GND:逻辑地(与STM32共地)控制信号:STEP:连接到STM32GPIO(如PA0),每个脉冲上升沿使电机移动步。DIR:连接到STM32GPIO(如PA1),高电平或低电平控制方向。ENABLE:连接到STM32GPIO(如PA2),低电平使能驱动器(有些设计也可直接接地使直使能)。另外,A4988有微步控制引脚(MS1,MS2,MS3),用于设置微步细分。如果不使用微步,可将它们都接地(全步进)。如果使用微步,需要根据微步表连接(如1/2步、1/4步等)。示例代码:我们将使用STM32的HAL库来操作GPIO。假设:STEP引脚:PA0DIR引脚:PA1ENABLE引脚:PA2(低电平有效)基本操作:1.初始化GPIO(输出模式)2.设置方向(高或低)3.使能驱动器(拉低ENABLE)4.发送脉冲:拉高STEP,延时,拉低STEP,延时(延时时间决定转速)注意:为了精确控制步进电机的速度,我们可以使用延时函数(简单示例)或定时器(更精确)。下面是个简单的示例代码(使用HAL库,基于STM32CubeIDE):```#include"stm32f0xx_hal.h"//引脚定义#defineSTEP_PINGPIO_PIN_0#defineSTEP_PORTGPIOA#defineDIR_PINGPIO_PIN_1#defineDIR_PORTGPIOA#defineENABLE_PINGPIO_PIN_2#defineENABLE_PORTGPIOAvoiddelay_us(uint16_tus){//简单延时函数,实际应用中建议使用定时器uint32_tticks=us*(SystemCoreClock/1000000)/5;//粗略计算,需要根据实际时钟调整while(ticks--);}intmain(void){HAL_Init();SystemClock_Config();//初始化GPIOGPIO_InitTypeDefGPIO_InitStruct={0};__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin=STEP_PIN|DIR_PIN|ENABLE_PIN;GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull=GPIO_NOPULL;GPIO_InitStruct.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA,&GPIO_InitStruct);//设置方向(例如高电平为正方向)HAL_GPIO_WritePin(DIR_PORT,DIR_PIN,GPIO_PIN_SET);//使能驱动器HAL_GPIO_WritePin(ENABLE_PORT,ENABLE_PIN,GPIO_PIN_RESET);//低电平使能while(1){//产生个步进脉冲HAL_GPIO_WritePin(STEP_PORT,STEP_PIN,GPIO_PIN_SET);delay_us(10);//保持高电平至少1us(根据A4988要求)HAL_GPIO_WritePin(STEP_PORT,STEP_PIN,GPIO_PIN_RESET);//延时控制步进速度,例如延时1ms(1000步/秒)HAL_Delay(1);//这个延时决定了步进周期,注意:实际速度还要考虑微步设置}}```注意:-上述代码中的delay_us函数是简单实现,实际应用中为了精确延时,建议使用定时器。-步进电机的速度由脉冲间隔决定,这里每1ms步(即1kHz),如果使用全步进模式,电机每步1.8度,则转速为1.8*1000/60=30转/分钟。-如果要改变方向,在循环前或循环中改变DIR引脚的电平。-微步设置:如果需要微步,需要连接MS1,MS2,MS3到STM32GPIO,并在初始化时设置相应的电平。例如,1/4步进:MS1=高,MS2=高,MS3=低。安全注意事项:-A4988的VMOT电源需要根据电机电压选择,并确保散热良好(如果电流较大需要散热器)。-在电机电源和地之间加个大电容(如100uF)以吸收电压波动。-逻辑电源VDD可以使用3.3V(与STM32致),注意不要超过5.5V。参考资源:-A4988数据手册:详细说明了接线、电流调节、微步设置等。-STM32F030K6T6参考手册:GPIO操作和定时器配置。相关问题:1.如何调节A4988的输出电流?2.使用定时器生成步进脉冲的方法?3.如何实现步进电机的加减速控制?以上代码和接线仅供参考,具体实现需要根据硬件设计和电机参数调整。</think>### A4988SETTR-T与STM32F030K6T6步进电机驱动方案 #### 、接线方式(关键引脚连接) **1. 电源部分** - **电机电源**: - `A4988 VMOT` → 外接电源(8-35V,根据电机规格) - `A4988 GND` → 电源地 - *注意*:在VMOT和GND间并联100μF电容滤波[^1] - **逻辑电源**: - `A4988 VDD` → `STM32 3.3V`(不可超过5.5V) - `A4988 GND` → `STM32 GND`(共地) **2. 控制信号连接** | A4988引脚 | STM32F030K6T6引脚 | 功能说明 | |-----------|-------------------|-----------------| | `STEP` | `PA0` (或其他GPIO) | 脉冲输入(每个上升沿移动步) | | `DIR` | `PA1` | 方向控制(高/低电平) | | `ENABLE` | `PA2` | 使能端(低电平有效) | | `MS1/MS2/MS3` | 悬空或接地 | 微步控制(悬空=全步进)| **3. 电机连接** - **双极步进电机**: - 线圈A+ → `A4988 1A` - 线圈A- → `A4988 1B` - 线圈B+ → `A4988 2A` - 线圈B- → `A4988 2B` **4. 保护电路** - **电流调节**: - 通过A4988的`VREF`引脚调节电流(公式:$I_{max} = V_{REF} / (8 \times R_{sense})$,典型$R_{sense}=0.05\Omega$) - **散热**: - 必须安装散热片(尤其电流>1A时) #### 二、STM32示例代码(HAL库) ```c #include "stm32f0xx_hal.h" // 引脚定义 #define STEP_PIN GPIO_PIN_0 #define STEP_PORT GPIOA #define DIR_PIN GPIO_PIN_1 #define DIR_PORT GPIOA #define ENABLE_PIN GPIO_PIN_2 #define ENABLE_PORT GPIOA void delay_us(uint16_t us) { uint32_t ticks = us * (SystemCoreClock / 1000000) / 5; while(ticks--); } int main(void) { HAL_Init(); SystemClock_Config(); // GPIO初始化 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = STEP_PIN | DIR_PIN | ENABLE_PIN; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Pull = GPIO_NOPULL; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 使能驱动器(低电平有效) HAL_GPIO_WritePin(ENABLE_PORT, ENABLE_PIN, GPIO_PIN_RESET); // 设置方向(示例:正转) HAL_GPIO_WritePin(DIR_PORT, DIR_PIN, GPIO_PIN_SET); while (1) { // 生成个步进脉冲(最小脉宽1μs) HAL_GPIO_WritePin(STEP_PORT, STEP_PIN, GPIO_PIN_SET); delay_us(5); // 保持高电平 HAL_GPIO_WritePin(STEP_PORT, STEP_PIN, GPIO_PIN_RESET); // 控制转速(延时决定步频) HAL_Delay(2); // 2ms延时 → 500步/秒 } } ``` #### 三、关键注意事项 1. **电流校准**: - 通电前用万用表测量`VREF`电压,确保$I_{max}$不超过电机额定值 - 计算公式:$V_{REF} = I_{max} \times 8 \times 0.05$ *例*:1A电流需设$V_{REF} = 0.4V$ 2. **抗干扰措施**: - 逻辑信号线长度<20cm - 电机电源与逻辑电源分离 - 在A4988的VMOT引脚就近并联100μF电解电容 + 0.1μF陶瓷电容[^2] 3. **故障保护**: - 过热关断:当结温>165°C时自动禁用输出 - 欠压锁定:VMOT<8V时停止工作 #### 四、进阶优化建议 - **微步控制**:连接MS1/MS2/MS3到STM32,实现1/16微步(需修改代码输出细分时序) - **定时器驱动**:用TIM2产生PWM脉冲替代软件延时(精度更高) - **加减速算法**:实现S型曲线加速(避免失步) --- ### 相关问题 1. **如何调节A4988的输出电流保护电机?** 2. **使用定时器生成STEP脉冲与软件延时相比有何优势?** 3. **A4988驱动电机时出现抖动可能是什么原因?** 4. **如何实现STM32通过UART控制步进电机运动?** [^1]: A4988数据手册第9页:电源滤波电容推荐值 [^^2]: Pololu A4988应用笔记:降低电机噪声的设计实践
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值