stm32基础

本文详细介绍STM32F4平台的GPIO接口操作,如点灯实验,通过GPIO控制LED;讲解外部中断实验,包括按键中断的配置和处理;并深入探讨通用定时器的定时器中断,实现定时任务。涉及的库函数、步骤和代码实例丰富实用。
摘要由CSDN通过智能技术生成

目录

 一.IO口输出实验--点灯

GPIO常用库函数

 点灯步骤及代码

二.外部中断实验--按键中断

外部中断常用库函数

外部中断步骤及代码  

三.通用定时器--定时器中断

通用定时器概述

 定时器配置中断的步骤及代码

 一.IO口输出实验--点灯

GPIO常用库函数

  • 1个初始化函数

        void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

  • 2个读取输入电平函数

        uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
        uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

  • 2个读取输出电平函数

        uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
        uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

  • 4个设置输出电平函数

        void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
        void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
        void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
        void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);

 点灯步骤及代码

     1.使能io口时钟,调用函数

        void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);

     2.初始化io口模式,调用函数

        void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);

     3.操作io口,输出高低电平

        void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
        void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

 led.c

void Led_Init(void)
{
	//库函数初始化步骤1:定义一个xxx_InitTypeDef类型的初始化结构体
	GPIO_InitTypeDef  GPIO_InitStruct;//可goto到该结构体查看成员
	
	//使能GPIO F组时钟,
	//RCC_AHB1ENR |= (0x01<<5);
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
	
	//库函数初始化步骤2:根据使用要求,向这些初始化结构体的成员写入特定的控制参数
	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_9;		//引脚9
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_OUT;	//输出模式
	GPIO_InitStruct.GPIO_OType	= GPIO_OType_PP;	//推挽
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz; //快速
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;     //上拉
	GPIO_Init(GPIOF, &GPIO_InitStruct);

}

main.c

//延时函数
void  delay(int n)
{
	int i, j;
	
	for(i=0; i<n; i++)
		for(j=0; j<40000; j++);

}


int main(void)
{
	//LED灯初始化
	Led_Init();
	
	while(1)
	{
		GPIO_SetBits(GPIOF,GPIO_Pin_9); //PF9置1 灯灭
		delay(1000);
		GPIO_ResetBits(GPIOF,GPIO_Pin_9);//PF9置0 灯亮
		delay(1000);
	}
	return 0;
}

二.外部中断实验--按键中断

外部中断常用库函数

void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex);
//设置IO口与中断线的映射关系
example: SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOE, EXTI_PinSource2);

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct);
//初始化中断线:触发方式等

ITStatus EXTI_GetITStatus(uint32_t EXTI_Line);
//判断中断线中断状态,是否发生

void EXTI_ClearITPendingBit(uint32_t EXTI_Line);
//清除中断线上的中断标志位

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);//使能SYSCFG时钟
//这个函数非常重要,在使用外部中断的时候一定要先使能SYSCFG时钟

外部中断步骤及代码  

  • 使能SYSCFG时钟:

        RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

  • 初始化IO口为输入。

        GPIO_Init();

  • 设置IO口与中断线的映射关系。

        void SYSCFG_EXTILineConfig();

  • 初始化线上中断,设置触发条件等。

        EXTI_Init();

  • 配置中断分组(NVIC),并使能中断。

        NVIC_Init();

  • 编写中断服务函数。

        EXTIx_IRQHandler();

  • 清除中断标志位

        EXTI_ClearITPendingBit();

 exit.c

//按键1中断配置
void Exti_PA0_Init(void)
{
	//库函数初始化步骤1:定义一个xxx_InitTypeDef类型的初始化结构体
	GPIO_InitTypeDef  GPIO_InitStruct;
	EXTI_InitTypeDef  EXTI_InitStruct;
	NVIC_InitTypeDef  NVIC_InitStruct;
	
	
	//☆☆☆使能GPIO A组时钟:
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	//☆☆☆使能SYSCFG时钟: 
	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	
	//库函数初始化步骤2:根据使用要求,向这些初始化结构体的成员写入特定的控制参数
	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_0;		//引脚0
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_IN;		//输入模式
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;     //上拉
	GPIO_Init(GPIOA, &GPIO_InitStruct);	
	
	//设置IO口与中断线的映射关系。PA0对应中断线0,详细看上图
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA,EXTI_PinSource0);
	
	EXTI_InitStruct.EXTI_Line	= EXTI_Line0; 			//中断线0 (可变)
	EXTI_InitStruct.EXTI_Mode	= EXTI_Mode_Interrupt;	//中断模式
	//可选为产生中断(EXTI_Mode_Interrupt)或者产生事件(EXTI_Mode_Event)
	
	EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling; //下降沿触发
	EXTI_InitStruct.EXTI_LineCmd= ENABLE;               //中断线使能
	//初始化线上中断,设置触发条件等。
    EXTI_Init(&EXTI_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel						= EXTI0_IRQn;  	//NVIC通道,在stm32f4xx.h可查看通道 (可变)
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority	= 0x01;			//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority			= 0x01;			//响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd					= ENABLE;		//使能
	//配置中断分组(NVIC),并使能中断。
    NVIC_Init(&NVIC_InitStruct);	
	
}

//编写中断服务函数。这个函数不需要程序员在主函数调用,满足条件CPU自行调用的函数
void EXTI0_IRQHandler(void)
{
	//判断中断标志是否为1		☆☆☆消抖
	if(EXTI_GetITStatus(EXTI_Line0)) //判断是EXTI0中断线进来的。一般用于防止例如EXTI5-9共用一个服务函数的情况
	{
		delay_ms(15);
		if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == Bit_RESET)
		{
			if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0) == 0)
			{
				//变更灯状态
				GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
			}
			
			// 清除中断标志位
			EXTI_ClearITPendingBit(EXTI_Line0); 
		}
		
	}

}

main.c

#include "stm32f4xx.h"
#include "led.h"
#include "key.h"
#include "exti.h"
#include "delay.h"

int main(void)
{
	
	//NVIC分组(一个工程当中只能配置一次分组)抢占优先级2位,值范围:0~3;响应优先级2位,值范围:0~3;
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	//LED灯初始化
	Led_Init();
	Exti_PA0_Init();
	
	while(1)
	{
		//delayms(15); 
	}
	return 0;
}




三.通用定时器--定时器中断

通用定时器概述

        STM32F4 的定时器有14个,其中TIM2-TIM5,TIM9~TIM14属于通用定时器,TIM1 和TIM8 则属于高级控制定时器,TIM6和TIM7是基本定时器。  

      

 定时器配置中断的步骤及代码

  • 使能定时器时钟。

        RCC_APB1PeriphClockCmd();

  • 初始化定时器,配置ARR,PSC。

        TIM_TimeBaseInit();

  • 启定时器中断,配置NVIC。

        NVIC_Init();

  • 设置 TIM3_DIER 允许更新中断。

        TIM_ITConfig();

  • 使能定时器。

        TIM_Cmd();

  • 编写中断服务函数。

        TIMx_IRQHandler();

以TIM3为例,延时1秒点亮led灯

tim.c

#include "tim.h"

/*
定时器说明:
TIM3 -- APB1
定时器TIM3:84MHZ
16位定时器:值范围:0~65535

*/

void Tim3_Init(void)
{
	TIM_TimeBaseInitTypeDef  TIM_TimeBaseInitStruct;
	NVIC_InitTypeDef  NVIC_InitStruct;

	//1、使能定时器时钟。
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);
    
	 //8400分频 84000 000/8400 = 10000HZ  1S数10000个数
	TIM_TimeBaseInitStruct.TIM_Prescaler    = 8400-1;   
	TIM_TimeBaseInitStruct.TIM_Period		= 10000-1;  //计10000个数 在10000HZ下,用时1s
	TIM_TimeBaseInitStruct.TIM_CounterMode  = TIM_CounterMode_Up; //向上计数
	TIM_TimeBaseInitStruct.TIM_ClockDivision= TIM_CKD_DIV1; //分频因子
	//2、初始化定时器,配置ARR,PSC。
	TIM_TimeBaseInit(TIM3, &TIM_TimeBaseInitStruct);	
	
	//NVIC通道,在stm32f4xx.h可查看通道 (可变)
	NVIC_InitStruct.NVIC_IRQChannel						= TIM3_IRQn;  
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority	= 0x01;			//抢占优先级
	NVIC_InitStruct.NVIC_IRQChannelSubPriority			= 0x01;			//响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd					= ENABLE;		//使能
    //3、启定时器中断,配置NVIC。
	NVIC_Init(&NVIC_InitStruct);		
	
	//4、设置 TIM3_DIER  允许更新中断
	TIM_ITConfig(TIM3, TIM_IT_Update, ENABLE);
	
	//5、使能定时器。
	TIM_Cmd(TIM3, ENABLE);
}

//编写中断服务函数。这个函数不需要程序员在主函数调用,满足条件CPU自行调用的函数
void TIM3_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断
	{
		/*处理的程序段*/
		
	}
	TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中断标志位
}



原文链接:https://blog.csdn.net/wprpr/article/details/108046684

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值