按键控制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).
366

被折叠的 条评论
为什么被折叠?



