STM32入门:GPIO推挽输出-LED闪烁+蜂鸣器响;

本文详细介绍了STM32单片机与51单片机在io口操作上的区别,包括STM32的时钟管理、io口的分类与模式、初始化固定思路,以及如何通过代码模块化实现LED和蜂鸣器控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

文章创作目的是梳理STM32的学习过程。本文旨在用最言简意骇的方式,主张用到哪里的代码就讲到哪里知识点。


一.STM32与51单片机——io口的区别;

STM32:需要进行io口初始化
因为stm32芯片拥有独特的时钟节能系统,如果要使用外设,必须先打开时钟,了解时钟如何打开与io口如何初始化成了第一课

五一单片机:直接对io口进行输出高低电平的操作

二.STM32芯片硬件基本知识:

1,io口介绍

STM32F103VET6的单片机,io端口数量非常多所以按组分类,每组含有16个引脚。有GPIOA,GPIOB,GPIOC,GPIOD,GPIOE,GPIOF,GPIOG,每组端口下有分有GPIO_Pin0到GPIO_Pin15一共16个引脚,所以总共有7*16=112个io口;

2,io口输出模式(led和蜂鸣器只用到推挽输出1种故不全提)

推挽输出:可以输出高电平和低电平

开漏输出:只能驱动输出低电平或浮动输出,高电平需要靠外部电阻拉高

3,时钟总线

STM32有APB1和APB2两种时钟线,具体哪组口使用哪个总线,看下图绿框部分,GPIOA-GPIOG都是APB2的时钟线

三.io口初始化固定思路

1.开启端口时钟。
2.设置引脚
3.引脚初始化

LED引脚连接如图 

                                                              蜂鸣器引脚连接如图

 

 四.代码思路:

1.创建对应文件,目的是实现代码模块化;

为两个外设,分别创建对应的.C与.H文件,在.C文件中初始化端口,.H文件作用与五一相同

2.在.C文件中,创建一个使用时钟使能函数:RCC_APB2PeriphClockCmd,使能(打开)时钟;
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE)

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能函数

其中     APB2   可以替换为   APB1

            GPIOB  可以替换为  GPIOA-GPIOG

            ENABLE(使能)  可以替换为  DISABLE  (失能)

参数(RCC_APB2Periph_GPIOB 还可以写成

(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE )//可以同时使能多组io口,一直添加"或"即可。
 3.配置引脚+模式+速率函数

引脚配置

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //LED0-->PB.5 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.5

补充:可以试着双击代码右键选择GO To.....,可以跳转到到参数所在位置。

 

  GPIO_Mode_Out_OD   //开漏输出
  GPIO_Mode_Out_PP  //推挽输出

补充:若是更改为其他端口的初始化时,更改下面几个初始化函数的标红的参数即可。

 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);     //使能PB,PE端口时钟
    
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;                 // 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;         //IO口速度为
 GPIO_Init(GPIOB, &GPIO_InitStructure);                     //根据设定参数初始化GPIO口

4.使用输出高低电平的函数

该函数可以直接控制端口高低电平,但还有另外一种可以输出高低电平的方式

 GPIO_SetBits(GPIOB,GPIO_Pin_5);						 //PB.5 输出高
 GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出高 

 GPIO_ResetBits(GPIOE,GPIO_Pin_5);                       //PE.5 输出低
 GPIO_ResetBits(GPIOB,GPIO_Pin_5);                       //PB.5 输出低
      
4.1另一种输出高低电平的方式
1.在硬件的.h与main所在文件中引用      #include "sys.h"
2.在硬件.h中宏定义                               #define BEEP PBout(8)
#ifndef __BEEP_H
#define __BEEP_H	 
#include "sys.h"       //在相应外设的.h文件中引用该函数库,
                       可以实现使用0或者1控制端口输出高低电平

//蜂鸣器端口定义
#define BEEP PBout(8)	// BEEP,蜂鸣器接口	#define 名字 P(组)out(端口号)	   
                        //               如 #define led PEout(5)     
void BEEP_Init(void);	//初始化
		 				    
#endif

3.便可以在main中使用:                               BEEP=0;   //BEEP 输出低电平
                                                                      BEEP=1;    //BEEP 输出高电平      

 int main(void)
 {
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	 	//初始化与LED连接的硬件接口
	BEEP_Init();         	//初始化蜂鸣器端口
	while(1)
	{
		LED0=0;
		BEEP=0;		  
		delay_ms(300);//延时300ms
		LED0=1;	  
		BEEP=1;  
		delay_ms(300);//延时300ms
	}
 }

 五.代码实现如下:

led闪烁+蜂鸣器响

led.c

#include "led.h"

 

//初始化PB5和PE5为输出口.并使能这两个口的时钟		    
//LED IO初始化
void LED_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;//GPIO_InitTypeDef是一个结构体类型,其功能是定义一个结构体,该结构体有三个成员分别是u16类型的GPIO_Pin、GPIOSpeed_TypeDef 类型的GPIO_Speed和GPIOMode_TypeDef 类型的GPIO_Mode
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);	 //使能PB,PE端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //LED0-->PB.5 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //常规下,IO口速度为50MHz,

 GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.5
 GPIO_SetBits(GPIOB,GPIO_Pin_5);						 //PB.5 输出高

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	    		 //LED1-->PE.5 端口配置, 推挽输出
 GPIO_Init(GPIOE, &GPIO_InitStructure);	  				
 GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出高 
}

led.h


#include "beep.h"
	   

//初始化PB8为输出口.并使能这个口的时钟		    
//蜂鸣器初始化
void BEEP_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);	 //使能GPIOB端口时钟
 
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;				 //BEEP-->PB.8 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;	 //速度为50MHz
 GPIO_Init(GPIOB, &GPIO_InitStructure);	 //根据参数初始化GPIOB.8
 
 GPIO_ResetBits(GPIOB,GPIO_Pin_8);//输出0,关闭蜂鸣器输出
	
}

 beep.c

#ifndef __LED_H
#define __LED_H	 
#include "sys.h"

#define LED0 PBout(5)// PB5
#define LED1 PEout(5)// PE5	//本次未用上,仅用于理解#define LED1 PEout(5)

void LED_Init(void);//初始化

		 				    
#endif

beep.h

#ifndef __BEEP_H
#define __BEEP_H	 
#include "sys.h"

//蜂鸣器端口定义
#define BEEP PBout(8)	// BEEP,蜂鸣器接口		   

void BEEP_Init(void);	//初始化
		 				    
#endif

 main.c

#include "sys.h"	
#include "delay.h"	
#include "led.h" 
#include "beep.h" 


 int main(void)
 {
	delay_init();	    	 //延时函数初始化	  
	LED_Init();		  	 	//初始化与LED连接的硬件接口
	BEEP_Init();         	//初始化蜂鸣器端口
	while(1)
	{
		LED0=0;
		BEEP=0;		  
		Delay_ms(300);//延时300ms
		LED0=1;	  
		BEEP=1;  
		Delay_ms(300);//延时300ms
	}
 }

delay.c (套用即可)

#include "stm32f10x.h"

/**
  * @brief  微秒级延时
  * @param  xus 延时时长,范围:0~233015
  * @retval 无
  */
void Delay_us(uint32_t xus)
{
	SysTick->LOAD = 72 * xus;				//设置定时器重装值
	SysTick->VAL = 0x00;					//清空当前计数值
	SysTick->CTRL = 0x00000005;				//设置时钟源为HCLK,启动定时器
	while(!(SysTick->CTRL & 0x00010000));	//等待计数到0
	SysTick->CTRL = 0x00000004;				//关闭定时器
}

/**
  * @brief  毫秒级延时
  * @param  xms 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_ms(uint32_t xms)
{
	while(xms--)
	{
		Delay_us(1000);
	}
}
 
/**
  * @brief  秒级延时
  * @param  xs 延时时长,范围:0~4294967295
  * @retval 无
  */
void Delay_s(uint32_t xs)
{
	while(xs--)
	{
		Delay_ms(1000);
	}
} 

delay.h

#ifndef __DELAY_H
#define __DELAY_H

void Delay_us(uint32_t us);
void Delay_ms(uint32_t ms);
void Delay_s(uint32_t s);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值