STM32学习笔记【江科协】【3-4】按键控制LED&光敏传感器控制蜂鸣器

接线图,按键是上节第一种点亮方式和LED是低电平点亮的方式

 我们需要完成LED和按键的驱动代码,但把两个混在主函数里,就会太乱,也不好移植,所以选择将驱动代码封装起来,单独放在.c和.h文件里,这就是模块化编程的方式


准备工作

新建一个文件夹

新建一个组也叫Hardware
魔术棒选项,再在在这里加上Hardware

选择添加.c和.h文件

取名字,注意路径

 


添加必要代码 

#ifndef __LED_H
#define __LED_H


#endif

一定要在最后留空格


按键控制LED主体代码

不显示代码提示的话,可以按下Ctrl+Alt+空格

LED代码部分

void LED_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);//开启时钟
	//下面配置端口模式
	GPIO_InitTypeDef GPIO_InitStructure;//定义一个结构体变量
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);
    //初始化
	GPIO_ResetBits(GPIOA, GPIO_Pin_1 | GPIO_Pin_2);//GPIO配置好后默认是低电平
}//这个函数是用来初始化LED的

只需调用LED_Init();两个LED的两个GPIO口就初始化完成了

复制到.h文件里

 

回到main.c,加上头文件

void LED1_ON(void)
{
	 GPIO_ResetBits(GPIOA, GPIO_Pin_1);
}

void LED1_OFF(void)
{
	 GPIO_SetBits(GPIOA, GPIO_Pin_1);
}

LED的定亮和熄灭的代码,记得去.h文件里面声明

void LED1_ON(void);

void LED1_OFF(void);

按键代码部分

准备工作同上,只是名字为Key

同样写个Key初始化的函数

void KEY_Init(void)
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//需要读取按键,所以选择上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_11;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //这里是输出速度,在输入模式下其实没有用
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

再写一段读取按键值的函数

uint8_t KEY_GETNUM(void)  //uint8_t相当于unsinged char
{
	   uint8_t KEY_NUM = 0 ;  //如果按键没有按下,默认给0
       if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0 ){
	   Delay_ms(20);  //需要用到delay函数,头文件还需加上#include "Delay.h"
	   while (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_1) == 0 );//按键一般是松手才有动作,所以加上判断
	   Delay_ms(20); //同样是消抖
	   KEY_NUM = 1;
	   }
       if(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0 ){
	   Delay_ms(20);
	   while(GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_11) == 0 );
	   Delay_ms(20);
	   KEY_NUM = 2;
	   }
	//一开始的疑惑是为什么两个if写在一个函数里面,但是这段实现的功能就是,按键1按下LED1点亮,按键2按下LED2熄灭
	return KEY_NUM;
}

同样记得,在.h文件里声明,在main.c文件里加上头文件#include "Key.h"

顺便一看GPIO的读取函数

uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

*用来读取数据输入寄存器某一个端口的输入值,读取按键要用到这个函数
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);

*用来读取整个数据输入寄存器的
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

*用来读取数据输出寄存器某一个端口的输入值,这个函数一般用于输出模式下,用来看自己输出什么
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);

*用来读取整个数据输出寄存器的

就要用到ReadOutput这两个函数

 如果我们要实现按键按一下熄灭,再按一下点亮该如何实现呢?也就是实现按键按下,LED取反

这就需要用到GPIO_ReadOutputDataBit();,在LED里加上这段函数,调用它LED的状态取反

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);
}//实现了端口的电平反转

这段我的理解是,如果按下原来是关就给开,原来是开就给关


光敏传感器控制蜂鸣器

 光敏传感器,电位器可以调节高低电平的判断阈值(我不知道具体指哪个且不知道怎么调)

总体代码和上一个差不多

main.c

#include "stm32f10x.h"                  // Device header
#include "BUZZER.h"
#include "LIGHTSENSOR.h"

int main(void)
{	
	BUZZER_Init();
	LIGHTSENSOR_Init();
	while(1)
	{	
		if( LIGHT_GET() == 1 ){
		BUZZER_ON();
		}
		else BUZZER_OFF();
	} 
}

 BUZZER.c

#include "stm32f10x.h"                  // Device header
void BUZZER_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;//这里输入模式选择?YES
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	
	GPIO_SetBits(GPIOB, GPIO_Pin_12);
}

void BUZZER_ON(void){
	GPIO_ResetBits(GPIOB, GPIO_Pin_12);//一开始错误在参数GPIOA没改
}

void BUZZER_OFF(void){
	GPIO_SetBits(GPIOB, GPIO_Pin_12);
}

BUZZER.h

#ifndef __BUZZER_H
#define __BUZZER_H

void BUZZER_Init(void);
void BUZZER_ON(void);
void BUZZER_OFF(void);

#endif

LIGHTSENSOR.h

#include "stm32f10x.h"                  // Device header
void LIGHTSENSOR_Init(void){
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;//为什么这里选择上拉输入
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
}

uint8_t LIGHT_GET(void){
	return GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
}

LIGHTSENSOR.h 

#ifndef __LIGHTSENSOR_H
#define __LIGHTSENSOR_H

void LIGHTSENSOR_Init(void);
uint8_t LIGHT_GET(void);

#endif

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
STM32指南者开发板中,可以使用光敏传感器控制蜂鸣器的代码如下: ```c #include "stm32f4xx.h" void ADC_Configuration(void) { ADC_InitTypeDef ADC_InitStructure; GPIO_InitTypeDef GPIO_InitStructure; // 开启 ADC1 时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE); // 开启 GPIOA 时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA, ENABLE); // 配置 ADC1 通道1 对应的 GPIOA 引脚为模拟输入 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_Init(GPIOA, &GPIO_InitStructure); // ADC1 配置 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b; ADC_InitStructure.ADC_ScanConvMode = DISABLE; ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None; ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; ADC_InitStructure.ADC_NbrOfConversion = 1; ADC_Init(ADC1, &ADC_InitStructure); // 配置 ADC1 触发源为软件触发 ADC_ExternalTrigConvCmd(ADC1, DISABLE); } void Buzzer_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; // 开启 GPIOB 时钟 RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE); // 配置 GPIOB 引脚为推挽输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT; GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); } uint16_t ReadLightSensorValue(void) { uint16_t adc_value; // 配置 ADC1 通道1 ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 1, ADC_SampleTime_3Cycles); // 启动 ADC1 转换 ADC_Cmd(ADC1, ENABLE); // 等待转换完成 while (ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC) == RESET); // 读取转换结果 adc_value = ADC_GetConversionValue(ADC1); // 关闭 ADC1 ADC_Cmd(ADC1, DISABLE); return adc_value; } int main(void) { // 初始化 ADC ADC_Configuration(); // 初始化蜂鸣器 Buzzer_Configuration(); while (1) { // 读取光敏电阻传感器的模拟值 uint16_t light_value = ReadLightSensorValue(); // 判断光照强度是否超过阈值 if (light_value > 1000) { // 触发蜂鸣器 GPIO_SetBits(GPIOB, GPIO_Pin_8); } else { // 关闭蜂鸣器 GPIO_ResetBits(GPIOB, GPIO_Pin_8); } } } ``` 在上述代码中,首先通过配置GPIO和ADC初始化函数来设置ADC和蜂鸣器的引脚和参数。然后,在`ReadLightSensorValue`函数中,通过配置ADC的通道和采样时间,启动和等待ADC转换完成,并读取转换结果。在主函数中,使用`ReadLightSensorValue`函数读取光敏电阻传感器的模拟值,并根据阈值判断是否触发蜂鸣器。 请注意,此代码仅为示例,具体的配置和使用方法可能会因STM32型号和使用的开发环境而有所不同。在实际应用中,请参考相关的STM32文档和示例代码进行适当的修改和调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值