02:(寄存器开发)流水灯/按键控制LED

news/2024/12/22 0:08:32/

寄存器开发

  • 1、LED流水灯
  • 2、按键控制LED

1、LED流水灯

通过第一章的学习,我们已然知晓了LED的点亮和熄灭的方式,下面学习流水灯的制作流程。
流水灯呈现的样子:就是第一个LED灯点亮,延迟一段时间,第一个LED灯熄灭+第二个LED灯点亮,延迟一段时间,第二个LED灯熄灭+第三个LED灯点亮…依次循环下去。其中延迟一段时间就是让单片机不做任何与LED灯有关的事情,这里使用延迟函数来实现。

在工程目录里面新建Driver文件夹用来保存配置片上外设的代码文件,如下图所示:
在这里插入图片描述
LED连接的实物图如下图所示:
在这里插入图片描述

①LED.c文件的代码如下:

#include "stm32f10x.h"                  
#include "LED.h"/** @Function:PA0~PA7引脚选择性的初始化* @para:对应的GPIOA的引脚PA_0~PA_7*/
void LED_Init(uint32_t PA_x)
{/* 1. 打开GPIOA的时钟 */RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;/* 2. 将PA0~PA7配置为通用输出开漏模式  */if(PA_x != PA_ALL){GPIOA->CRL |= PA_x; GPIOA->CRL &= ~(PA_x << 2);}else{GPIOA->CRL |= PA_ALL;GPIOA->CRL &= PA_ALL;}}/** @Function:输出1点亮LED灯* @para:对应的GPIOA的引脚输出值LED0~LED7*/
void LED_ON(uint16_t LEDx)
{GPIOA->ODR |= LEDx;
}/** @Function:熄灭LED灯* @para:对应的GPIOA的引脚输出值LED0~LED7*/
void LED_OFF(uint16_t LEDx)
{GPIOA->ODR &= ~LEDx;
}/** @Function:翻转LED灯* @para:对应的GPIOA的引脚输出值LED0~LED7*/
void LED_Turn(uint16_t LEDx)
{/* 如果是关闭那么就打开,如果是打开那么就关闭 */if((GPIOA->ODR & LEDx) == 0)//关闭{LED_ON(LEDx);}else{LED_OFF(LEDx);}
}

②LED.h文件的代码如下:

#ifndef __LED_H
#define __LED_H
#include "stm32f10x.h"                  #define PA_0  0x00000003 //GPIO_CRH_MODE0
#define PA_1  0x00000030 //GPIO_CRH_MODE1
#define PA_2  0x00000300 //GPIO_CRH_MODE2
#define PA_3  0x00003000 //GPIO_CRH_MODE3
#define PA_4  0x00030000 //GPIO_CRH_MODE4
#define PA_5  0x00300000 //GPIO_CRH_MODE5
#define PA_6  0x03000000 //GPIO_CRH_MODE6
#define PA_7  0x30000000 //GPIO_CRH_MODE7
#define PA_ALL  0x33333333 //GPIO_CRH_MODE#define LED0 GPIO_ODR_ODR0
#define LED1 GPIO_ODR_ODR1
#define LED2 GPIO_ODR_ODR2
#define LED3 GPIO_ODR_ODR3
#define LED4 GPIO_ODR_ODR4
#define LED5 GPIO_ODR_ODR5
#define LED6 GPIO_ODR_ODR6
#define LED7 GPIO_ODR_ODR7void LED_Init(uint32_t PA_x);
void LED_ON(uint16_t LEDx);
void LED_OFF(uint16_t LEDx);
void LED_Turn(uint16_t LEDx);#endif

③主函数文件的代码如下:

#include "stm32f10x.h"                
#include "Delay.h"
#include "LED.h"#define timer 500/*LED流水灯,LED灯的负极连接着GND,正极连接着单片机的引脚(PA0~PA4)一共5个LED灯,引脚输出1点亮,输出0熄灭
*/
int main(void)
{LED_Init(PA_ALL);//将所有的引脚都配置为通用输出推挽模式while(1){LED_ON(LED0);//点亮LED0Delay_ms(timer);LED_OFF(LED0);//熄灭LED0LED_ON(LED1);//点亮LED1Delay_ms(timer);LED_OFF(LED1);//熄灭LED1LED_ON(LED2);//点亮LED2Delay_ms(timer);LED_OFF(LED2);//熄灭LED2LED_ON(LED3);//点亮LED3Delay_ms(timer);LED_OFF(LED3);//熄灭LED3LED_ON(LED4);//点亮LED4Delay_ms(timer);LED_OFF(LED4);//熄灭LED4}
}

代码优化如下:

#include "stm32f10x.h"                
#include "Delay.h"
#include "LED.h"#define timer 500
/*LED流水灯,LED灯的负极连接着GND,正极连接着单片机的引脚(PA0~PA4)一共5个LED灯,引脚输出1点亮,输出0熄灭
*/
int main(void)
{LED_Init(PA_ALL);//将所有的引脚都配置为通用输出推挽模式while(1){for(uint8_t i = 0; i<5 ;i++){LED_ON(LED0 << i);Delay_ms(timer);LED_OFF(LED0 << i);}   }
}

代码优化2:制作来回流水灯

#include "stm32f10x.h"                
#include "Delay.h"
#include "LED.h"#define timer 500
/*LED流水灯,LED灯的负极连接着GND,正极连接着单片机的引脚(PA0~PA4)一共5个LED灯,引脚输出1点亮,输出0熄灭
*/
int main(void)
{LED_Init(PA_ALL);//将所有的引脚都配置为通用输出推挽模式while(1){/*代码改进:来回流水灯*/ for(uint8_t i = 0; i<4 ;i++){LED_ON(LED1 << i);Delay_ms(timer);LED_OFF(LED1 << i);}for(uint8_t i = 0; i<4 ;i++){LED_ON(LED3 >> i);Delay_ms(timer);LED_OFF(LED3 >> i);}   }
}

演示效果如下:

VID_20241004_105203

2、按键控制LED

使用按键控制则需要按键检测,检测引脚的输入输入电平,所以需要用到端口输入寄存器GPIO_IDR,如下图所示:
在这里插入图片描述
所以被检测的引脚要配置为输入模式。
在这里插入图片描述

实物连接如下图所示:

在这里插入图片描述

在这里插入图片描述
①Key.c文件的代码如下:

#include "stm32f10x.h"                  
#include "Delay.h"/** @Function:按键引脚(GPIOB0)的初始化*/
void Key_Init(void)
{//1、开始GPIOB的时钟RCC->APB2ENR |= RCC_APB2ENR_IOPBEN;//2、配置引脚GPIOB0的输入模式:上拉输入,MODE0 = 00,CNF0 = 10,ODR0 = 1。GPIOB->CRL &= ~GPIO_CRL_MODE0;GPIOB->CRL &= ~GPIO_CRL_CNF0_0;GPIOB->CRL |= GPIO_CRL_CNF0_1;GPIOB->ODR |= GPIO_ODR_ODR0;//表示上拉模式
}/** @Function:按键按下并返回一个值*/
uint8_t Key_Num(void)
{uint8_t Number = 0;//引脚配置为上拉输入,则默认输入为高电平,按键按下由高电平变为低电平if((GPIOB->IDR & GPIO_IDR_IDR0)!= 0)//代表按键没有按下{Delay_ms(5);//软件消抖if((GPIOB->IDR & GPIO_IDR_IDR0)== 0)//代表按键按下{Number = 1;}}return Number;
}

②LED.c文件代码如下:

#include "stm32f10x.h"                  
#include "LED.h"/** @Function:PA0~PA7引脚选择性的初始化* @para:对应的GPIOA的引脚PA_0~PA_7*/
void LED_Init(uint32_t PA_x)
{/* 1. 打开GPIOA的时钟 */RCC->APB2ENR |= RCC_APB2ENR_IOPAEN;/* 2. 将PA0~PA7配置为通用输出开漏模式  */if(PA_x != PA_ALL){GPIOA->CRL |= PA_x; GPIOA->CRL &= ~(PA_x << 2);}else{GPIOA->CRL |= PA_ALL;GPIOA->CRL &= PA_ALL;}}/** @Function:输出1点亮LED灯* @para:对应的GPIOA的引脚输出值LED0~LED7*/
void LED_ON(uint16_t LEDx)
{GPIOA->ODR |= LEDx;
}/** @Function:熄灭LED灯* @para:对应的GPIOA的引脚输出值LED0~LED7*/
void LED_OFF(uint16_t LEDx)
{GPIOA->ODR &= ~LEDx;
}/** @Function:翻转LED灯* @para:对应的GPIOA的引脚输出值LED0~LED7*/
void LED_Turn(uint16_t LEDx)
{/* 如果是关闭那么就打开,如果是打开那么就关闭 */if((GPIOA->ODR & LEDx) == 0)//关闭{LED_ON(LEDx);}else{LED_OFF(LEDx);}
}

③主函数文件的代码如下:

#include "stm32f10x.h"                
#include "Delay.h"
#include "LED.h"
#include "Key.h"/*按键控制LED
*/
int main(void)
{LED_Init(PA_0);     //将GPIOA0引脚都配置为通用输出推挽模式Key_Init();         //初始化GPIOB0LED_OFF(LED0);      //关闭LED0while(1){if(Key_Num() == 1)//代表按键按下{LED_Turn(LED0);//LED灯翻转}   }
}

演示效果如下:


http://www.ppmy.cn/news/1534557.html

相关文章

UE4_Niagara基础实例—5、骨架网格体表面生成粒子及过滤骨骼位置生成粒子

效果图&#xff1a; 步骤&#xff1a; 1、学习了静态网格体位置生成粒子之后这个就比较简单了&#xff0c;把粒子生成位置更改为SkeletalMeshLocation。 2、小白人的骨骼网格体为&#xff1a; 你会发现骨骼的每一个节点处都有粒子产生。 3、我们还可以修改骨骼采样类型 4、我们…

React表单:formik、final-form和react-hook-form

表单无处不在&#xff0c;它是每个网站的必备部分。在用React构建web应用时&#xff0c;处理表单是不可避免的。 你可以选择自己的方式来处理&#xff0c;或者选择社区中现成的库。然而&#xff0c;当你选择一个第三方库时&#xff0c;你会立即面临一个问题&#xff1a;有太多的…

2.4 Spring系列教程4-Spring的数据库编程

数据库用于处理持久化业务产生的数据&#xff0c;应用程序在运行过程中经常要操作数据库。一般情况下&#xff0c;数据库的操作由持久层来实现。作为扩展性较强的一站式开发框架&#xff0c;Spring也提供了持久层Spring JDBC功能&#xff0c;Spring JDBC可以管理数据库连接资源…

黑马程序员pink 教js ,查漏补缺版,耗时4天

JS基础-D1 变量类型 1.js编程语言&#xff0c;html标记语言 2.不用jdk&#xff0c;运行在浏览器 3.交互&#xff0c;用户点击1就数值1 4.服务端编程&#xff0c;nodejs 5.js遵循ecma-script的语法规范 6.js由ecma-s和dom bom组成&#xff0c;或者也可以叫做ecma-s和weba…

新高考的五大变化‌‌(AI生成)

新高考的五大变化‌‌1 考试科目和考试时间的变化 ‌考试科目‌&#xff1a; 改革前&#xff0c;考试科目为‌语文、‌数学&#xff08;文/理&#xff09;、‌外语、‌理科综合/文科综合。 改革后&#xff0c;实行“312”模式&#xff0c;即全国统考科目3门&#…

安全服务面试

118.什么叫脱壳? 而从技术的角度出发&#xff0c;壳是一段执行于原始程序前的代码。原始程序的代码在加 壳的过程中可能被压缩、加密……。当加壳后的文件执行时&#xff0c;壳&#xff0d;这段代码先于 原始程序运行&#xff0c;他把压缩、加密后的代码还原成原始程序代码…

TCP BIC 的拟合函数分析

前面说了这么多&#xff0c;还没有对 bic 的数学性质进行分析&#xff0c;本文补上。 tcp reno 完全依赖 ack 时钟以 rtt 为单位线性增窗&#xff0c;增窗速度与 rtt 负相关&#xff0c;如何在 rtt 比较大时增加增窗速度&#xff0c;这就是 bic&#xff0c;以二分替换遍历。 …

【重学 MySQL】五十一、更新和删除数据

【重学 MySQL】五十一、更新和删除数据 更新数据删除数据注意事项 在MySQL中&#xff0c;更新和删除数据是数据库管理的基本操作。 更新数据 为了更新&#xff08;修改&#xff09;表中的数据&#xff0c;可使用UPDATE语句。UPDATE语句的基本语法如下&#xff1a; UPDATE ta…