按键控制LED&光敏传感器控制蜂鸣器

按键控制LED&光敏传感器控制蜂鸣器

按键控制LED

  • 1接线图如图:
    在这里插入图片描述
  • 2程序编写:与以往程序编写不同,现在编写程序要新建两个文件,一个.c文件,一个.h文件,分别命名为LED.c和LED.h文件;LED.c中存放LED的初始化函数和一系列控制LED开关的函数,将其建在新建文件夹Hardware下;LED.C代码如下:
#include "stm32f10x.h"                  // Device header
#include <string.h>
#include <stdio.h>

//初始化LED函数
void LED_Init(void){
	//配置时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
	//初始化相应端口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	//设置默认电平为高电平,LED灯初始化是灭的
	GPIO_SetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);
}

//点亮A1口的LED
void LED1_ON(void){
	GPIO_ResetBits(GPIOA,GPIO_Pin_1);
}

//点亮A2口的LED
void LED2_ON(void){
	GPIO_ResetBits(GPIOA,GPIO_Pin_2);
}

//当A1口的电平为低电平,将A1口电平变为高电平;当A1口的电平为高电平,将A1口电平变为低电平
void LED1_Turn(void)
	{
		if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_1) == 0)
		{
		GPIO_SetBits(GPIOA,GPIO_Pin_1);
		}
		else
		{
		GPIO_ResetBits(GPIOA,GPIO_Pin_1);
		}
}

//当A2口的电平为低电平,将A2口电平变为高电平;当A2口的电平为高电平,将A2口电平变为低电平
void LED2_Turn(void)
{
	if(GPIO_ReadOutputDataBit(GPIOA,GPIO_Pin_2) ==0)
	{
		GPIO_SetBits(GPIOA,GPIO_Pin_2);
	}
	else
	{
		GPIO_ResetBits(GPIOA,GPIO_Pin_2);
	}
}

//熄灭A1口的LED
void LED1_OFF(void){
	GPIO_SetBits(GPIOA,GPIO_Pin_1);
}

//熄灭A2口的LED
void LED2_OFF(void){
	GPIO_SetBits(GPIOA,GPIO_Pin_2);
}

//用户传入LED灯所在的端口和mode(on 或者 off)即可实现特定的LED灯的开关
void LED_ON_OFF(uint16_t GPIO_Pin_X,char* mode){
	if(strcmp(mode,"on")==0){
		GPIO_ResetBits(GPIOA,GPIO_Pin_X);
	}else if(strcmp(mode,"off")==0){
		GPIO_SetBits(GPIOA,GPIO_Pin_X);
	}else{
		//printf("error of input!!!\n");
	}
	
}

void LED1_Turn(void);和void LED2_OFF(void);使用GPIO_ReadOutputDataBit();来检测相应LED端口的输出电平(0表示低电平,灯亮;1表示高电平,灯灭),若检测LED灯处于低电平,则亮灯GPIO_ResetBits(GPIOA,GPIO_Pin_1);
反之,熄灯GPIO_SetBits(GPIOA,GPIO_Pin_1);.

编写好的.c文件的函数需要在相应的.h文件(LED.h)中作函数声明,以便外部可以调用LED.c中的函数,.h文件的固定格式如下:

#ifndef __名称_H
#define __名称_H
	...
#endif

LED.h函数如下:

#ifndef __LED_H
#define __LED_H

void LED_Init(void);
void LED1_ON(void);
void LED1_OFF(void);
void LED2_ON(void);
void LED2_OFF(void);
void LED_ON_OFF(uint16_t GPIO_Pin_X,char* mode);
void LED1_Turn(void);
void LED2_Turn(void);

#endif

在main.c下编写函数如下:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

int main(void)
{
	LED_Init();
	
	while(1)
	{
		LED1_ON();
		Delay_ms(500);
		LED1_OFF();
		Delay_ms(500);
		}
}

  • 3仿照LED的文件格式作出Key按键开关的文件:
    Key.c代码:
#include "stm32f10x.h"                  // Device header
#include "Delay.h"
//初始化Key函数
void Key_Init(void)
{
	//配置时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	//初始化相应端口
	GPIO_InitTypeDef GPIO_InitStruct;
	//GPIO_Mode_IPU上拉输入,按下低电平,松开高电平
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);
}

uint8_t Key_GetNum(void)
{
	uint8_t KeyNum = 0;
	//读取输入寄存器某一位的值,0代表低电平,1代表高电平,0表示按键按下去,LED灯是低电平点亮的
	//按键1(GPIO_Pin_1)
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_1) == 0);
		Delay_ms(20);
		KeyNum = 1;
	}
	//按键2(GPIO_Pin_11)
	if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0)
	{
		Delay_ms(20);
		while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_11) == 0);
		Delay_ms(20);
		KeyNum = 2;
	}
	return KeyNum;
}

Key.h代码:

#ifndef __Key_H
#define __Key_H
	void Key_Init(void);
	uint8_t Key_GetNum(void);
#endif

按键控制LED的main.c文件代码:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"

uint8_t KeyNum;

int main(void)
{
		
	LED_Init();
	Key_Init();
	
	while(1)
	{
		KeyNum = Key_GetNum();
		if(KeyNum == 1)
		{
		LED1_Turn();
		}
		
		if(KeyNum == 2)
		{
		LED2_Turn();
		}
	}
}

代码原理:
①程序通过GPIO_ReadInputBit();函数来读取B1和B11口的电平状态,当没按开关时,电平处于高电位,为什么会处于高电位呢?因为在初始化Key函数时将其输入模式编写为上拉输入,即GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;这串代码.
②两个函数为什么能结合在一起?
答:关键就在main.c的逻辑中,声明的KeyNum变量会循环(while(1)循环)读取按键开关的状态,若电平发生变化,则KeyNum接收到值(1或2),则控制灯打开或关闭.
③为什么同一个开关按一次小灯开启,再按一次小灯关闭呢?
答:关键在于LED1_Turn();和LED2_Turn();中,再次函数中,若检测到小灯是开的就将小灯关闭,检测到小灯是关的,就将小灯打开.加入LED1初试是关闭的,当按一次按键开关1(B1口的按键开关),KeyNum就会得到值1,在循环里就会执行第一个if语句,进入LED1_Turn();函数,将小灯打开,之后进行下一次循环,再次按动按键开关1,KeyNum又会的得到值1,再次进入第一个if,执行LED1_Turn();将小灯关闭.由此实现按键开关和小灯的联动.

光敏传感器控制蜂鸣器

  • 1接线图如图:
    在这里插入图片描述
  • 2该项目代码与按键控制LED项目代码逻辑结构类似,不再赘述,代码如下:
    Buzzer.c:
#include "stm32f10x.h"                  // Device header

//初始化Buzzer函数
void Buzzer_Init(void){
	//配置时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	//初始化相应端口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB,&GPIO_InitStruct);

}

//点亮B12口的蜂鸣器
void Buzzer_ON(void){
	GPIO_ResetBits(GPIOB,GPIO_Pin_12);
}

//熄灭B12口的蜂鸣器
void Buzzer_OFF(void){
	GPIO_SetBits(GPIOB,GPIO_Pin_12);
}

//检测B12(接入蜂鸣器的那个口)的信号变化
void Buzzer_Turn(void)
	{
		if(GPIO_ReadOutputDataBit(GPIOB,GPIO_Pin_12) == 0)
		{
		GPIO_SetBits(GPIOB,GPIO_Pin_12);
		}
		else
		{
		GPIO_ResetBits(GPIOB,GPIO_Pin_12);
		}
}

Buzzer.h:

#ifndef __BUZZER_H
#define __BUZZER_H
//初始化Buzzer函数
void Buzzer_Init(void);

//点亮B12口的蜂鸣器
void Buzzer_ON(void);

//熄灭B12口的蜂鸣器
void Buzzer_OFF(void);

//检测B12(接入蜂鸣器的那个口)的信号变化
void Buzzer_Turn(void);


#endif

LightSensor.c:

#include "stm32f10x.h"                  // Device header

//初始化光敏传感器函数
void LigntSensor_Init(void)
{
	//配置时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	//初始化相应端口
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
}


//读取光敏传感器的值
uint8_t LightSensor_Get(void)
{
return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_13);

}

LightSensor.h:

#ifndef __LIGHT_SENSOR_H
#define __LIGHT_SENSOR_H

//初始化光敏传感器函数
void LigntSensor_Init(void);


//读取光敏传感器接入口的值
uint8_t LightSensor_Get(void);

#endif

main.c文件:

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "Buzzer.h"
#include "LightSensor.h"

int main(void)
{
	Buzzer_Init();
	LigntSensor_Init();
		
	while(1)
	{
		if(LightSensor_Get() == 1)
		{
			Buzzer_OFF();
		}
		else
		{
			Buzzer_ON();	
		}

	}
}


值得注意的是:
①main.c与按键控制LED的项目的main.c的逻辑基本一样,但是蜂鸣器的一个函数做了相应的改变,即函数uint8_t LightSensor_Get(void);会返回一个值,这个值要在循环内也只能在循环内使用,达到循环检测光敏电阻器的电位变化,0表示无光,1表示检测到光.
②光敏电阻器在接电源时不要正负极接反,否则会烧坏它(我就烧坏了一个o(╥﹏╥)o).

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

必胜的思想钢印

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

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

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

打赏作者

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

抵扣说明:

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

余额充值