STM32使用库函数-配置GPIO口

 

目录

 

 

STM32简介

GPIO口的说明

GPIO库函数的使用

 再介绍一下外部中断和定时器中断的配置流程


 

STM32简介

 

STM32ST公司基于ARM Cortex-M内核开发的32位微控制器

STM32常应用在嵌入式领域,如智能车、无人机、机器人、无线通信、物联网、工业控制、娱乐电子产品等

STM32功能强大、性能优异、片上资源丰富、功耗低,是一款经典的嵌入式微控制器

 

ARM既指ARM公司,也指ARM处理器内核

ARM公司是全球领先的半导体知识产权(IP)提供商,全世界超过95%的智能手机和平板电脑都采用ARM架构

ARM公司设计ARM内核,半导体厂商完善内核周边电路并生产芯片

 

 可以看出芯片上的外设非常多,那怎么使用这些外设就成了头疼的问题,所以ST公司就提供了丰富的库函数,接下来简单说一下如何使用从零使用这些库函数

GPIO口的说明

GPIOGeneral Purpose Input Output)通用输入输出口

可配置为8种输入输出模式

引脚电平:0V~3.3V,部分引脚可容忍5V

输出模式下可控制端口输出高低电平,用以驱动LED、控制蜂鸣器、模拟通信协议输出时序等

输入模式下可读取端口的高低电平或电压,用于读取按键输入、外接模块电平信号输入、ADC电压采集、模拟通信协议接收数据等

 

 可以看到使用GPIO口首先要开启APB2外设时钟 ,再配置GPIO口使用一长串看不懂 ,不要急,一步一步考来

GPIO库函数的使用

当我们按照网上的教程创建了一个工程文件却有

 

1.首先要打开外设的是时钟

RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //打开外设时钟

 

这里打开的就是GPIOB口的外设时钟 

这行代码就是从找到的

 可以打开stm32fl10x_rcc.h中划到最终下面

void RCC_APB2PeriphResetCmd(uint32_t RCC_APB2Periph, FunctionalState NewState);

 然后快速找到需要的函数即可右键跳转到函数的定义查看他 参数是什么

 知道参数和用法之后就可以开启GPIOB的外设时钟了

第一个参数就是选择要使用的外设

第二个参数就是选择使能

接下来就是初始化GPIOB的某个引脚口,这里选择的是PB5这个引脚

    //创建结构体变量
	GPIO_InitTypeDef GPIO_InitStructure;
	//设置为推挽输出模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	//选择由于要使用 PB5引脚口,所以配置Pin5作为输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
	//选择 输出速度为50MHZ
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	//最后将参数填进去初始化
	GPIO_Init(GPIOB, &GPIO_InitStructure);	

打开atm32f10x.gpio.h找我们需要的函数

 需要的是

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

来初始化GPIO口,接下来跳转定义查看参数如何使用

 英文翻译之后得知

第一个参数是要初始化的GPIOX口

第二个参数是一个结构体变量 用于设置工作模式,引脚口和输出速度

在得知之后便可以配置引脚口了

void LED_Init(void)
{
	//打开外设时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	//创建结构体变量
	GPIO_InitTypeDef GPIO_InitStructure;
	//设置为推挽输出模式
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	//选择由于要使用 PB5引脚口,所以配置Pin5作为输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 ;
	//选择 输出速度为50MHZ
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	//最后将参数填进去初始化
	GPIO_Init(GPIOB, &GPIO_InitStructure);	
}

 配置完成后就 可以使用PB5这个引脚口了

可以使用官方提供的函数来拉低拉高引脚的高低电平,当然官方还提高拱了很多类似的函数不一一介绍

void LED1_ON(void)
{
	GPIO_ResetBits(GPIOB, GPIO_Pin_5);// 拉低引脚输出电平
}

void LED1_OFF(void)
{
	GPIO_SetBits(GPIOB, GPIO_Pin_5);  //拉高引脚输出电平
}

到这里就基本配置完毕了

在介绍一下GPIO口的工作模式

 再介绍一下外部中断和定时器中断的配置流程

大家看看就行,不一一介绍了

 

void Key_Init(void)
{
	//打开GPIO和AFIO的外设时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);
	
	//初始化GPIO_Pin_15口
	GPIO_InitTypeDef GPIO_InitStructure;//创立参数结构体
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; //选择工作模式
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15 ;   //选择GPIO引脚接口
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //选择输出速度
	GPIO_Init(GPIOB, &GPIO_InitStructure);		//初始化GPIO口
	
	//初始化EXTI
	GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource15);//用于配置EXIT外部中断/事件的GPIO中断源,传入的参数是GPIO和相应的IO口
	EXTI_InitTypeDef EXTI_InitStructure;	//创立参数结构体
	EXTI_InitStructure.EXTI_Line = EXTI_Line15; //将EXTI的第15个线路配置为中断模式
	EXTI_InitStructure.EXTI_LineCmd =ENABLE ;	//开启中断
	EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt ;// EXTI_Mode_Interrupt选择中断模式 EXTI_Mode_Event选择事件模式
	EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; //下降沿触发
	EXTI_Init(&EXTI_InitStructure);//初始化EXTI
	
	//初始化NVIC
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择优先级
	NVIC_InitTypeDef NVIC_InitStructure;	//创立参数结构体
	NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn;//选择通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		//选择指定通道使能(打开通道)
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =1 ;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;		//响应优先级
	NVIC_Init(&NVIC_InitStructure);
}

void EXTI15_10_IRQHandler(void)//中断程序
{
	if(EXTI_GetITStatus(EXTI_Line15) == SET)//由于中断源10到中断源15都能进入本中断函数,所以要判断是否是自己想要的中断源
	{
		
		EXTI_ClearITPendingBit(EXTI_Line15);//清楚标志位
	}
}

 

 

/****************************************************************************
* 名    称:void Timer2_Init(void)
* 功    能:初始化定时器2
* 入口参数:无
* 出口参数:无
* 说    明:将定时器2以每次300ms的时间触发中断程序
* 调用方法:无 
****************************************************************************/ 
void Timer2_Init(void)
{

	RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); //打开外设时钟
	
	TIM_InternalClockConfig(TIM2);//打开选择内部时钟作为输出源
	
	//初始化时基单元
	TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
	TIM_TimeBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1 ; //时钟分频模式(滤波),但是采用内部时钟采样型号稳定配不配这个没关系
	TIM_TimeBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up;//选择定时器计数模式,选择向上计数
	
	TIM_TimeBaseInitStructure.TIM_Period = 3000-1; //ARR自动重装其的值
	TIM_TimeBaseInitStructure.TIM_Prescaler = 7200-1;//PSC预分频器的值
	
	TIM_TimeBaseInitStructure.TIM_RepetitionCounter = 0; //重复计数器 当计时器溢出x次时才执行中断
	TIM_TimeBaseInit(TIM2,&TIM_TimeBaseInitStructure);
	
	TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE);//打开TIM2的更行中断
	
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //选择优先级
	NVIC_InitTypeDef NVIC_InitStructure;	//创立参数结构体
	NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;//选择通道
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;		//选择指定通道使能(打开通道)
	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority =2 ;//抢占优先级
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//响应优先级
	NVIC_Init(&NVIC_InitStructure);
}
void TIM2_IRQHandler(void)
{
	if(TIM_GetITStatus(TIM2,TIM_IT_Update)==SET)
	{
		TIM_ClearITPendingBit(TIM2,TIM_IT_Update);
	}
}

 

...全文
110 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,365

社区成员

发帖
与我相关
我的任务
社区描述
柳职院电子信息工程学院同学们的学习园地
社区管理员
  • c_university_1974
  • qq_39231145
  • zhuisir
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

各位加入社区的同学,请完善社区信息,把社区昵称改为【班级-姓名】,社区签名改为【班级-学号-姓名】的格式

如【社区昵称】20计应1班  张某某(班级用简称)

     【社区签名】2020级计算机应用技术1班 20201234567 张某某 (班级用全称)

试试用AI创作助手写篇文章吧