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

news2024/10/4 20:39:53

寄存器开发

  • 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_ODR7

void 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);//点亮LED0
        Delay_ms(timer);
        LED_OFF(LED0);//熄灭LED0
    
        LED_ON(LED1);//点亮LED1
        Delay_ms(timer);
        LED_OFF(LED1);//熄灭LED1
        
        LED_ON(LED2);//点亮LED2
        Delay_ms(timer);
        LED_OFF(LED2);//熄灭LED2
        
        LED_ON(LED3);//点亮LED3
        Delay_ms(timer);
        LED_OFF(LED3);//熄灭LED3
        
        LED_ON(LED4);//点亮LED4
        Delay_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();         //初始化GPIOB0
    
    LED_OFF(LED0);      //关闭LED0
    
	while(1)
	{
        if(Key_Num() == 1)//代表按键按下
        {
            LED_Turn(LED0);//LED灯翻转
        }   
	}
}

演示效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2188662.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2020大厂web前端面试常见问题总结

本篇收录了一些面试中经常会遇到的经典面试题以及自己面试过程中遇到的一些问题。通过对本篇知识的整理以及经验的总结&#xff0c;希望能帮到更多的前端面试者。 1.web前端项目的结构是怎样的&#xff1f;文件有哪些命名规范&#xff1f; 项目结构规范 页面文件&#xff1a;以…

树莓派5:换源(针对Debian12)+安装包管理器Archiconda(图文教程+详细+对初学者超级友好)

目录 一、安装官方发行版系统&#xff08;Debian&#xff09;二、换源&#xff08;记得参考上述教程ssh连接到树莓派Terminal&#xff0c;or外接一块Hdmi显示屏&#xff09;2.1 查看自己安装的树莓派镜像架构2.2 查询自己的系统版本2.3 打开清华大学开源软件镜像站网站2.3.1 传…

浅析Golang的Context

文章目录 1. 简介2. 常见用法2.1 控制goroutine的生命周期&#xff08;cancel&#xff09;2.2 传递超时&#xff08;Timeout&#xff09;信息2.3 传递截止时间&#xff08;Deadline&#xff09;2.4 传递请求范围内的全局数据 &#xff08;value&#xff09; 3 特点3.1 上下文的…

FWA(固定无线接入),CPE(客户终端设备)简介

文章目录 FWA&#xff08;Fixed Wireless Access&#xff09;&#xff0c;固定无线接入CPE&#xff08;Customer Premise Equipment&#xff09;&#xff0c;用户驻地设备 FWA&#xff08;Fixed Wireless Access&#xff09;&#xff0c;固定无线接入 固定无线接入&#xff08…

Geogebra009—构建正六边形

继续巩固一下基础&#xff0c;本篇我们来做一个正六边形 目录 一、成品展示二、涉及内容三、做图步骤1. 绘制一个以A点为圆心过B点的圆circle1&#xff1b;2. 以B点为圆心过A点绘制另外一个圆circle2&#xff1b;3. 绘制两个圆的交点&#xff0c;得到顶点C和D&#xff1b;4. 以…

Leetcode: 0001-0010题速览

Leetcode: 0001-0010题速览 本文材料来自于LeetCode solutions in any programming language | 多种编程语言实现 LeetCode、《剑指 Offer&#xff08;第 2 版&#xff09;》、《程序员面试金典&#xff08;第 6 版&#xff09;》题解 遵从开源协议为知识共享 版权归属-相同方式…

奔驰GLS450升级原厂电吸门效果怎么样

奔驰GLS450升级原厂电吸门后&#xff0c;能带来以下效果&#xff1a; • 关门更优雅&#xff1a;只需轻轻推车门到基本关闭的位置&#xff0c;当车门距离车门锁大约6毫米时&#xff0c;传感器便会启动电动马达将车门安静地拉入&#xff0c;然后固定住&#xff0c;告别传统关门…

HTML+CSS基础用法介绍五

目录&#xff1a; 结构伪类选择器盒子模型-边框线盒子模型-内边距盒子模型-解决盒子被撑大盒子模型-外边距与版心居中小知识&#xff1a;清除浏览器中所有标签的默认样式内容溢出控制显示方式盒子模型-圆角 &#x1f40e;正片开始 结构伪类选择器 什么是结构伪类选择器&…

18.安卓逆向-frida基础-调试实战2

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

Windows UAC权限详解以及因为权限不对等引发软件工具无法正常使用的实例分析

目录 ​1、什么是UAC&#xff1f; 2、微软为什么要设计UAC&#xff1f; 3、标准用户权限与管理员权限 4、程序到底以哪种权限运行&#xff1f;与哪些因素有关&#xff1f; 4.1、给程序设置以管理员权限运行的属性 4.2、当前登录用户的类型 4.3、如何通过代码判断某个进程…

智能 AI 写作软件:开启创作新纪元

不论你在哪行哪业应该都躲不开写作这件事被。写作已经成为了我们生活和工作中不可或缺的一部分。随着人工智能技术的飞速发展&#xff0c;AI 智能写作工具应运而生。接下来&#xff0c;让我们一起揭开智能ai写作工具的神秘面纱。 1.笔灵AI写作 直通车&#xff1a;https://ibi…

②EtherCAT转ModbusTCP, EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关

EtherCAT/Ethernet/IP/Profinet/ModbusTCP协议互转工业串口网关https://item.taobao.com/item.htm?ftt&id822721028899 协议转换通信网关 EtherCAT 转 Modbus TCP (接上一章&#xff09; GW系列型号 配置说明 上载 网线连接电脑到模块上的 WEB 网页设置网口&#…

论文笔记:Online Class-Incremental Continual Learning with Adversarial Shapley Value

这篇工作的focus 是 memory-based approach 1. 挑战/问题&#xff1a; 灾难性遗忘&#xff1a;深度神经网络在学习新任务时往往会忘记先前任务的知识。内存和计算效率&#xff1a;在个人设备上执行深度学习任务时&#xff0c;需要最小化内存占用和计算成本。数据流增量学习&am…

系统安全 - 大数据组件的安全及防护

文章目录 导图1. Hadoop的安全风险2. 常见攻击方式3. Hadoop的自带安全功能4. Apache Knox和Apache Ranger等安全框架5. 安全策略建议 导图 1. Hadoop的安全风险 Hadoop最初设计为在可信网络中运行&#xff0c;因此默认安全性较低。常见的安全风险包括&#xff1a; 未经授权的…

探索未来:揭秘pymqtt,AI与物联网的新桥梁

文章目录 探索未来&#xff1a;揭秘pymqtt&#xff0c;AI与物联网的新桥梁背景&#xff1a;为什么选择pymqtt&#xff1f;什么是pymqtt&#xff1f;如何安装pymqtt&#xff1f;简单的库函数使用方法1. 配置MQTT连接2. 创建Mqtt对象3. 发布消息4. 订阅主题5. 运行MQTT客户端 场景…

Java项目实战II基于Java+Spring Boot+MySQL的小徐影城管理系统设计与实现(源码+数据库+文档)

目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发&#xff0c;CSDN平台Java领域新星创作者 一、前言 随着文化娱乐产业的快速发展&#xff0c;影城管理面临着日益复杂的挑战&#xff0c;包括票务管理、座…

Redis操作常用API

说明&#xff1a;Redis应用于java项目中&#xff0c;操作Redis数据可以使用API&#xff0c;相较于命令行更方便。使用前&#xff0c;需先添加依赖。 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-re…

HIKVISION 海康威视对讲服务配置平台弱口令

漏洞描述 杭州海康威视系统技术有限公司对讲服务配置平台存在弱口令 漏洞复现 FOFA "document.write(TITLE_SYSTEM);" POC admin #账号 12345 #密码 登录成功

利用Spring Boot打造新闻推荐解决方案

1系统概述 1.1 研究背景 如今互联网高速发展&#xff0c;网络遍布全球&#xff0c;通过互联网发布的消息能快而方便的传播到世界每个角落&#xff0c;并且互联网上能传播的信息也很广&#xff0c;比如文字、图片、声音、视频等。从而&#xff0c;这种种好处使得互联网成了信息传…

Kotlin基本知识

Kotlin是一种现代的静态类型编程语言&#xff0c;由JetBrains公司在2010年推出&#xff0c;并被Google在2019年宣布为Android开发的首选语言。 超过 50% 的专业 Android 开发者使用 Kotlin 作为主要语言&#xff0c;而只有 30% 使用 Java 作为主要语言。 70% 以 Kotlin 为主要语…