stm32库函数开发led等

  • 库函数与寄存器开发区别

1.1 寄存器

寄存器开发优点

直接操作寄存器,运行效率高。

寄存器开发缺点

  1. 开发难度大,开发周期长
  2. 代码可阅读性差,可移植差
  3. 后期维护难度高

1.2库函数

库函数开优点

  1. 开发难度较小,开发周期短
  2. 代码可阅读性强,可移植高
  3. 后期维护难度低

库函数开缺点

相对于寄存器开发,运行效率略低

注意:库函数其实是ST公司对寄存器的进一步封装。

  • 库函数开发LED

库函数开发LED要添加的库函数文件:stm32f4xx_gpio.c

 

 

  1. 理解led灯原理图

LED0连接在PF9

PF9输出低电平(0),灯亮;PF9输出高电平(0),灯灭;

 

 

  1. 打开GPIOF组时钟

在STM32芯片中,所有的外设时钟是不打开,为了降低功耗

//打开GPIOF组时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);

  1. 设置PF9灯为输出模式  输出推挽 上拉 速度(50MHZ)

GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; //引脚

GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT; //输出模式

GPIO_InitStruct.GPIO_OType = GPIO_OType_PP; //输出推挽

GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; //速度50MHZ

GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP; //上拉

GPIO_Init(GPIOF, &GPIO_InitStruct);

4、通过下面控制LED灯亮与灭

GPIO_SetBits()   引脚置1

GPIO_ResetBits() 引脚置0

官方参考案例

路径:D:\GZFX2103\STM32\STM32上课资料\STM32F4xx固件库\stm32f4_dsp_stdperiph_lib\STM32F4xx_DSP_StdPeriph_Lib_V1.4.0\stm32f4xx_dsp_stdperiph_lib_um.chm

 

  • 按键库函数开发

库函数开发按键要添加的库函数文件:stm32f4xx_gpio.c

1、理解按键控制原理

KEY0连接在PA0

按键未按下,PA0为高电平

按键 按下,PA0为低电平

 

  1. 打开GPIOA组时钟

//打开GPIOA组时钟

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);

  1. 设置引脚为输入,上拉。

GPIO_InitTypeDef  GPIO_InitStruct;

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);

4、通过下面函数获取引脚电平

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

  • 中断

中断概念

中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行(面试题)。

 

STM32外部中断需要注重知识点EXTI与NVIC,STM32所有引脚均可以做为外部中断。

4.1、外部中断/事件控制器 (EXTI)

EXTI 控制器的主要特性如下:
每个中断/事件线上都具有独立的触发和屏蔽
每个中断线都具有专用的状态位
支持多达 23 个软件事件/中断请求
检测脉冲宽度低于 APB2 时钟宽度的外部信号。有关此参数的详细信息,请参见
STM32F4xx 数据手册的电气特性部分。

引脚中断线

 

上升沿:数字电路中,数字电平从低电平(数字“0”)变为高电平(数字“1”)的那一瞬间(时刻)叫作上升沿。

下降沿:数字电路中,数字电平从高电平(数字“1”)变为低电平(数字“0”)的那一瞬间叫作下降沿。

 

4.2 NVIC

嵌套向量中断控制器 (NVIC)

NVIC 特性
嵌套向量中断控制器 NVIC 包含以下特性:
STM32F405xx/07xx STM32F415xx/17xx 具有 82 个可屏蔽中断通道, STM32F42xxx
STM32F43xxx 具有多达 86 个可屏蔽中断通道(不包括 Cortex™-M4F 16 根中
断线)
16 个可编程优先级(使用了 4 位中断优先级)
低延迟异常和中断处理
电源管理控制
系统控制寄存器的实现
嵌套向量中断控制器 (NVIC) 和处理器内核接口紧密配合,可以实现低延迟的中断处理和晚
到中断的高效处理。

NVIC优先级分为抢占优先级与响应优先级。

数字越小,优先级别越高

优先级分组

 

抢占优先级 & 响应优先级区别:  抢占优先级 > 响应优先级

高优先级的抢占优先级是可以打断正在进行的低抢占优先级中断的。

抢占优先级相同的中断,高响应优先级不可以打断低响应优先级的中断。

抢占优先级相同的中断,当两个中断同时发生的情况下,哪个响应优先级高,哪个先执行。

如果两个中断的抢占优先级和响应优先级都是一样的话,则看哪个中断先发生就先执行;

例:

假定设置中断优先级组为2,然后设置中断3(RTC中断)的抢占优先级为2,响应优先级为1。  中断6(外部中断0)的抢占优先级为3,响应优先级为0。中断7(外部中断1)的抢占优先级为2,响应优先级为0。

                                 

中断7>中断3>中断6。

4.3外部中断配置流程

外部中断配置流程要添加的库函数:stm32f4xx_exti.c和stm32f4xx_syscfg.c

 

参考库函数案例

 

 

  1. 理解按键原理

KEY0 连接PA0,选择下降沿触发

 

 

  1. 设置NVIC分组

void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup);

3、使能SYSCFG及GPIOA时钟: 

       RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);

4、 初始化IO口为输入。

       GPIO_Init();

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

        void SYSCFG_EXTILineConfig();

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

       EXTI_Init();

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

       NVIC_Init();

8、 编写中断服务函数。

      EXTIx_IRQHandler();

9、清除中断标志位

      EXTI_ClearITPendingBit();

五、函数说明

void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState)

函数功能:使能AHB1外设时钟

返回值:无

uint32_t RCC_AHB1Periph:哪个外设

FunctionalState NewState:ENABLE or DISABLE

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

函数功能:GPIO初始化

返回值:无

GPIO_TypeDef* GPIOx:哪个GPIO组

GPIO_InitTypeDef* GPIO_InitStruct:GPIO结构

typedef struct

{

  uint32_t GPIO_Pin;              //哪个引脚

  GPIOMode_TypeDef GPIO_Mode;     //模式

  GPIOSpeed_TypeDef GPIO_Speed;   //速度

  GPIOOType_TypeDef GPIO_OType;   //输出类型

  GPIOPuPd_TypeDef GPIO_PuPd;     //上下拉

}GPIO_InitTypeDef;

void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

函数说明:引脚置位

函数返回值:无

GPIO_TypeDef* GPIOx:哪个组IO

uint16_t GPIO_Pin:哪个引脚

void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

函数说明:引脚复位

函数返回值:无

GPIO_TypeDef* GPIOx:哪个组IO

uint16_t GPIO_Pin:哪个引脚

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

函数说明:读某个引脚输入状态

函数返回值:

  Bit_RESET = 0 (低电平)

  Bit_SET   = 1 (高电平)

GPIO_TypeDef* GPIOx:哪个组IO

uint16_t GPIO_Pin:哪个引脚

void SYSCFG_EXTILineConfig(uint8_t EXTI_PortSourceGPIOx, uint8_t EXTI_PinSourcex)

函数说明:设置IO口与中断线的映射

函数返回值:无

uint8_t EXTI_PortSourceGPIOx:哪个组IO

uint8_t EXTI_PinSourcex:哪个引脚

void EXTI_Init(EXTI_InitTypeDef* EXTI_InitStruct)

函数说明:外部中断控制器初始化

返回值:无

typedef struct

{

  uint32_t EXTI_Line;                //中断线

   

  EXTIMode_TypeDef EXTI_Mode;       //模式

  EXTITrigger_TypeDef EXTI_Trigger; //触发条件

  FunctionalState EXTI_LineCmd;     //中断线命令

}EXTI_InitTypeDef;

void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)

函数说明:NVIC初始化

返回值:无

NVIC_InitTypeDef* NVIC_InitStruct:NVIC结构体

typedef struct

{

  uint8_t NVIC_IRQChannel;                    //中断通道,可在stm32f4xx.h文件当中查找

  uint8_t NVIC_IRQChannelPreemptionPriority;  //抢占优先级

  uint8_t NVIC_IRQChannelSubPriority;         //响应优先级

  FunctionalState NVIC_IRQChannelCmd;         //中断通道使能   

} NVIC_InitTypeDef;

六、应用产品

  1. LED

家用LED

 

指示灯

 

 

  1. 按键

汽车按键                               

 

   电梯按键

 led库函数开发

#include "led.h"


/****************************************************
LED0连接在PF9(属于GPIOF组)
PF9输出低电平(0),灯亮;PF9输出高电平(1),灯灭;

*****************************************************/
void Led_Init(void)
{
	
	GPIO_InitTypeDef  GPIO_InitStruct;

	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);	

	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_PuPd	= GPIO_PuPd_UP;		//上拉
	GPIO_InitStruct.GPIO_Speed	= GPIO_Speed_50MHz;	//50MHZ
	GPIO_Init(GPIOF,&GPIO_InitStruct);	
	
}
#ifndef __LED_H
#define __LED_H

#include "stm32f4xx.h"


void Led_Init(void);

#endif
#include "stm32f4xx.h"
#include "led.h"


void delay(int n)
{
	int i, j;

	for(i=0; i<n; i++)
		for(j=0; j<20000; j++);
}


int main(void)
{
	Led_Init();

	
	while(1)
	{
		//LED0亮
		GPIO_ResetBits(GPIOF, GPIO_Pin_9);
		delay(1000);
		
		//LED0灭
		GPIO_SetBits(GPIOF, GPIO_Pin_9);
		delay(1000);
	}
}

key库函数开发

#include "key.h"

/****************************************************
引脚说明
KEY0 -- PA0

按键未按下,PA0为高电平
按键按下,  PA0为低电平
*****************************************************/

void Key_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	//使能GPIOA 时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);	

	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_0;		//引脚9
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_IN;		//输入模式
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;		//上拉
	GPIO_Init(GPIOA,&GPIO_InitStruct);		

}
#ifndef __KEY_H
#define __KEY_H

#include "stm32f4xx.h"


void Key_Init(void);

#endif
#include "stm32f4xx.h"
#include "led.h"
#include "key.h"

void delay(int n)
{
	int i, j;

	for(i=0; i<n; i++)
		for(j=0; j<20000; j++);
}


int main(void)
{
	int key_count = 0;
	
	Led_Init();
	Key_Init();
	
	//查询判断按键状态
	while(1)
	{
		/*
		//应用场景1 根据按键的时长,相应的动作
		//判断按键是否按下
		if(GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0) == Bit_RESET)
		{
			//延时消抖 20ms
			delay(20); 
			//判断按键是否按下
			if(GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0) == Bit_RESET)
			{
				key_count++;
				//按键已经按下,处理相关事件
				//变更引脚状态
				GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
			}

		}
		
		if(key_count == 100)//2S
		{
			key_count = 0;
			//LED3 亮
			GPIO_ResetBits(GPIOE, GPIO_Pin_14);
		}
		*/
		
		//应用场景2 根据按键按下松开一次表示一个动作,比如ATM按键
		//判断按键是否按下
		if(GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0) == Bit_RESET)
		{
			//延时消抖 20ms
			delay(25); 
			//判断按键是否按下
			if(GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0) == Bit_RESET)
			{
				//等待按键松开
				while(GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0) == Bit_RESET);
				//变更引脚状态
				GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
			}

		}
		
	
		
	}
}

key中断

#include "exti.h"

/**************************************
引脚说明
PA0 -- EXTI0
PA0选择下降沿触发
**************************************/
void Exti_PA0_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStruct;
	EXTI_InitTypeDef  EXTI_InitStruct;
	NVIC_InitTypeDef  NVIC_InitStruct;
	//使能SYSCFG 时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
	//使能GPIOA 时钟
	RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE);
	
	GPIO_InitStruct.GPIO_Pin	= GPIO_Pin_0;		//引脚9
	GPIO_InitStruct.GPIO_Mode	= GPIO_Mode_IN;		//输入模式
	GPIO_InitStruct.GPIO_PuPd	= GPIO_PuPd_UP;		//上拉
	GPIO_Init(GPIOA,&GPIO_InitStruct);		
	
	//设置IO口与中断线的映射关系。PA0 -- EXTI0
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
	
	EXTI_InitStruct.EXTI_Line	= EXTI_Line0;			//中断线0
	EXTI_InitStruct.EXTI_Mode	= EXTI_Mode_Interrupt; 	//中断模式
	EXTI_InitStruct.EXTI_Trigger= EXTI_Trigger_Falling;	//下降沿触发
	EXTI_InitStruct.EXTI_LineCmd= ENABLE;				//中断线使能
	//初始化线上中断,设置触发条件等。 
    EXTI_Init(&EXTI_InitStruct);
	
	NVIC_InitStruct.NVIC_IRQChannel						= EXTI0_IRQn;//中断通道,中断通道在stm32f4xx.h文件当中查找
	NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority	= 2;		 //抢占优先级			
	NVIC_InitStruct.NVIC_IRQChannelSubPriority			= 2;		 //响应优先级
	NVIC_InitStruct.NVIC_IRQChannelCmd					= ENABLE;	 //使能通道
	//配置中断分组(NVIC),并使能中断。
    NVIC_Init(&NVIC_InitStruct);	
	
}

extern void delay(int n);

/**************************************
中断服务函数
1 中断函数名字在startup_stm32f40_41xxx.s查找,且中断服务函数格式是固定:void 中断服务函数名(void)
2 中断服务函数是EXTI控制检测到下降沿并通知CPU主动去执行的函数,不需要在程序当中进行调用
***************************************/
void EXTI0_IRQHandler(void)
{
	//判断标志位是否置1
	if(EXTI_GetITStatus(EXTI_Line0) == SET)
	{
		//延时消抖 20ms
			delay(25); 
		if(GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0) == Bit_RESET)
		{
				//变更引脚状态
			GPIO_ToggleBits(GPIOF, GPIO_Pin_9);
			//等待按键松开
				while(GPIO_ReadInputDataBit(GPIOA,  GPIO_Pin_0) == Bit_RESET);

		}
	}
	//清空标志位
	EXTI_ClearITPendingBit(EXTI_Line0);
}




#ifndef __EXTI_H
#define __EXTI_H

#include "stm32f4xx.h"


void Exti_PA0_Init(void);

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

void delay(int n)
{
	int i, j;

	for(i=0; i<n; i++)
		for(j=0; j<20000; j++);
}


int main(void)
{
	int key_count = 0;
	//设置NVIC分组(一个工程只能设置一个分组) 
	//第二分组;抢占优先组取值范围:0~3 响应先组取值范围:0~3
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
	Led_Init();
	Exti_PA0_Init();
	
	
	
	while(1)
	{

		
	
		
	}
}

 

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hqb_newfarmer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值