stm32f103c8t6学习1 控制IO口的输出(点灯)

在stm32系列单片机中,如果我们想要控制一个IO口输出或者输入,我们都需要对这个IO口进行配置,根据我们需要的功能,将其配置成适合的输出方式或者输入方式。

所以当我们想要控制IO的输出时我们先要确定stm32的输出方式:

1.推挽输出

内部结构

stm32f103c8t6学习1 控制IO口的输出(点灯)_第1张图片

根据数模电的知识我们可以了解到,Vout具有输出高低电平的能力。

当上面的PMOS管导通,下面的NMOS管截止的时候,Vout输出高电平;

当上面的PMOS管截止,下面的NMOS管导通的时候,Vout输出低电平;

优缺点

优点:输出电压基本与电源电压没有压差;

           IO口驱动能力强,输出电流最大可达20mA

           电平变化快

缺点:

         不支持线与(线与指的就是两个IO口连接在一起,输出电平是这两个IO口相与的结果,当这两个IO口都是推挽输出的时候,线与容易烧坏芯片

2.开漏输出

内部结构

stm32f103c8t6学习1 控制IO口的输出(点灯)_第2张图片

 根据数模电的知识我们知道,Vout具有输出低电平的能力

当NMOS管导通的时候,Vout输出低电平;

当NMOS管关断的时候,Vout为高阻态;

所以我们知道开漏输出本身不具有输出高电平的功能,我们需要外部连接一个上拉电阻,这样其才有输出高电平的能力。

3.复用推挽输出

 与普通推挽输出口一样,不过这时IO口不在是简单的输出高低电平那么简单,而是可以将其复用成输出PWM等功能。

4.复用开漏输出

与普通开漏输出口一样,不过这时IO口不在是简单的输出高低电平那么简单,而是可以将其复用成输出PWM等功能。

根据上面的解释,我们可以根据我们的实际情况选择合适的输出方式,一般IO口都没有上拉电阻,IO口也不需要线与,所以我们一般选择推挽输出。

确定了IO口的输出方式,我们就可以开始写代码了

首先确定我们的IO口,一般是查看原理图

stm32f103c8t6学习1 控制IO口的输出(点灯)_第3张图片

这里我们知道我们需要控制PB5和PE5两个IO口的输出来控制LED。所以我们需要对PB5和PE5两个IO口进行程序配置。代码如下 

这里的文件是led.c

void LED_Init(void)
{
 GPIO_InitTypeDef  GPIO_InitStructure;  //IO口配置结构体
 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);	  				 //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出高 
}

重点语句程序解释:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);     //使能PB,PE端口时钟 

在APB2总线上开启PB,PE端口时钟,只有开启才会工作!!!

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;

需要配置的具体引脚,如果是PBx,这里就是GPIO_Pin_x。

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   设置为推挽输出

配置好IO口后,我们需要在main函数中进行调用

这里的文件是main.c

#include "delay.h"
#include "sys.h"
#include "led.h"
#include "lcd_init.h"
#include "lcd.h"
#include "pic.h"
#include "pwm.h"
#include "key.h"

int main(void)
{
	delay_init();
	LED_Init();
	//KEY_Init();
	//TIM3_PWM_Init(59999,23);//设置频率为50Hz,公式为:溢出时间Tout(单位秒)=(arr+1)(psc+1)/Tclk	 20MS = (59999+1)*(23+1)/72000000
                          //Tclk为通用定时器的时钟,如果APB1没有分频,则就为系统时钟,72MHZ
                          //PWM时钟频率=72000000/(59999+1)*(23+1) = 50HZ (20ms),设置自动装载值60000,预分频系数24
	while(1)
	{
//		if(GPIO_ReadInputDataBit(KEYPORT,KEY1)==0)
//		{
//			delay_ms(20);//20ms消除抖动	
//			if(GPIO_ReadInputDataBit(KEYPORT,KEY1)==0)
//			{
//				LED0=!LED0;
//			}
//			while(GPIO_ReadInputDataBit(KEYPORT,KEY1)==0); //等待按键松开 
//		}
        LED1=0;
		delay_ms(500);
		LED0=!LED0;
		delay_ms(500);
	}
}

LED0与LED1在led.h中配置

#ifndef __LED_H
#define __LED_H

#include "sys.h"

#define LED0 PBout(5)// PB5
#define LED1 PEout(5)// PE5	

void LED_Init(void);


#endif

这里我们的期望是LED1一直亮,LED0闪烁

效果如下

stm32f103c8t6学习1 控制IO口的输出(点灯)_第4张图片

 视频地址

VID20220921171305_哔哩哔哩_bilibili

你可能感兴趣的:(stm32,单片机,学习)