您的位置:

零死角玩转STM32

一、基础知识

1、STM32介绍

STM32是由ST公司推出的一款基于ARM Cortex-M内核的单片机,具有高性能、低功耗、高性价比等优点,被广泛应用于工控、汽车电子、医疗等领域。

2、GPIO

GPIO是通用输入输出控制器,是STM32最基本的外设之一,可以用来控制外围设备的状态,如LED灯、按键等。

3、中断

中断是一种处理器对外界事件的响应机制,STM32支持多种中断模式,应用广泛,如外部中断、定时器中断、DMA中断等。

二、环境搭建

1、开发环境准备

在进行STM32开发之前,需要搭建开发环境,包括安装Keil MDK和STM32CubeMX等工具。


#include "stm32f4xx.h"
int main(void)
{
  //代码内容
}

2、Keil项目配置

在Keil中配置项目,包括选择芯片型号、添加源文件等。


#include "stm32f4xx.h"
int main(void)
{
  //代码内容
}

3、STM32CubeMX使用

STM32CubeMX是一款用于配置和生成STM32代码的工具,可以快速生成基本代码框架,方便开发者快速上手。


#include "stm32f4xx.h"
int main(void)
{
  //代码内容
}

三、GPIO控制

1、STM32 GPIO简介

STM32的GPIO口分为多组,每组有多个引脚,每个引脚可以进行输入输出控制。

2、GPIO控制原理

通过设置GPIO配置寄存器的不同位可以控制GPIO的工作模式和输出状态,如下面的代码:


#include "stm32f4xx.h"
int main(void)
{
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);//使能GPIOA时钟
  
  GPIO_InitTypeDef GPIO_InitStructure;  
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0;//设置GPIOA0口  
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;//设置输出模式  
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;//推挽输出  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//设置输出速率  
  GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA0口
  
  while(1)
  {  
    GPIO_SetBits(GPIOA, GPIO_Pin_0);//GPIOA0置高  
    delay(500);  
    GPIO_ResetBits(GPIOA,GPIO_Pin_0);//GPIOA0置低  
    delay(500);  
  }  
}

四、外部中断

1、外部中断简介

STM32支持外部中断,可以通过配置某个引脚为中断输入模式来监听外部事件,如按键按下等。

2、外部中断实现

下面是一个通过配置GPIOA0为中断输入模式并实现按键转换的例子:


#include "stm32f4xx.h"  
GPIO_InitTypeDef GPIO_InitStructure;  
NVIC_InitTypeDef NVIC_InitStructure;  
EXTI_InitTypeDef EXTI_InitStructure;  
#define KEY1_GPIO_PORT    GPIOA  
#define KEY1_GPIO_CLK     RCC_AHB1Periph_GPIOA  
#define KEY1_GPIO_PIN     GPIO_Pin_0  
#define KEY1_EXTI_PORTSRC EXTI_PortSourceGPIOA  
#define KEY1_EXTI_PINSRC  EXTI_PinSource0  
#define KEY1_EXTI_LINE    EXTI_Line0  
#define KEY1_EXTI_IRQ     EXTI0_IRQn  
void KEY1_Init(void)  
{  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);  
    RCC_AHB1PeriphClockCmd(KEY1_GPIO_CLK, ENABLE);  
    GPIO_InitStructure.GPIO_Pin = KEY1_GPIO_PIN;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN ;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  
    GPIO_Init(KEY1_GPIO_PORT, &GPIO_InitStructure);  
    EXTI_InitStructure.EXTI_Line = KEY1_EXTI_LINE;  
    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt ;  
    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;   
    EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
    EXTI_Init(&EXTI_InitStructure);  
    NVIC_InitStructure.NVIC_IRQChannel = KEY1_EXTI_IRQ;  
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;  
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;  
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;  
    NVIC_Init(&NVIC_InitStructure);  
}  
void EXTI0_IRQHandler(void)  
{  
    if(EXTI_GetITStatus(KEY1_EXTI_LINE) != RESET)  
    {  
        //执行中断处理函数  
        EXTI_ClearITPendingBit(KEY1_EXTI_LINE);  
    }  
}  
int main(void)  
{  
    KEY1_Init();  
    while (1)  
    {  
        //其他代码  
    }  
}  

五、定时器

1、定时器介绍

定时器是STM32中比较常用的模块之一,可以用来产生各种时序信号,如PWM波、脉冲信号等。

2、定时器配置

下面是一个使用TIM3定时器产生PWM波的例子:


#include "stm32f4xx.h"  
TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;  
TIM_OCInitTypeDef TIM_OCInitStructure;  
GPIO_InitTypeDef GPIO_InitStructure;  
void TIM3_PWM_Init(u16 arr,u16 psc)  
{  
    uint16_t CCR1_Val = 32768;  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);  
    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);  
      
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7 ;  
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;  
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;  
    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;  
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;  
    GPIO_Init(GPIOC, &GPIO_InitStructure);  
      
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource6, GPIO_AF_TIM3);  
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource7, GPIO_AF_TIM3);  
      
    TIM_TimeBaseInitStructure.TIM_Period = arr;  
    TIM_TimeBaseInitStructure.TIM_Prescaler =psc;  
    TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;  
    TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;  
    TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStructure);  
      
    TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;  
    TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;  
    TIM_OCInitStructure.TIM_Pulse = CCR1_Val;  
    TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;  
      
    TIM_OC1Init(TIM3, &TIM_OCInitStructure);  
    TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Enable);  
      
    TIM_CtrlPWMOutputs(TIM3, ENABLE);  
    TIM_Cmd(TIM3, ENABLE);  
}  
int main(void)  
{  
    TIM3_PWM_Init(999,83);  
    while (1)  
    {  
        //其他代码  
    }  
}