一、基础知识
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)
{
//其他代码
}
}