IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> 适合学习的基于stm32系列--按键控制心形红绿流水灯的转换 -> 正文阅读

[嵌入式]适合学习的基于stm32系列--按键控制心形红绿流水灯的转换

一.硬件设计

?

1,按键电路

在这次设计中,用到的按键只有WK-UP和KEY2两个按键,按下WK-UP按键红灯闪烁,按下KEY2按键绿灯闪烁。

? ? ? ? ?WK_UP电路采用的是下拉模式,常态下是低电平,当按键按下时低电平转化为高电平,所以是上升沿触发的方式;KEY1--KEY3采用的是上拉模式,常态下是高电平,当按键按下时,由高电平转化为低电平,所以是下降沿触发的方式。

510c28e32d0e45f08886e1ce64983056.jpg

?KEY0->PH3 上拉输入

KEY1->PH2 上拉输入

KEY2->PC13 上拉输入

WK_UP->PA0 下拉输入

?

流水灯电路

三脚二极管:如图所示的这中采用的是共阴极的封装方式。中间引脚为阴极,两边为阳极。当较长的引脚输入高电平时,二极管发红色光;当较短引脚输入高电平时,二极管发绿色光。

47a688e97013461489ab24144c9fe7ae.jpg

?

连接方式:采用的是共阳极连接,分别把二极管的两个阳极用电烙铁连接到一起,再用一根线引出,阳极初始化为高电平,通过给阴极输入高低电平来控制灯的亮灭。并且编写按键程序,通过按键输入,来控制红色光和绿色光的反转。

00a7e2b47a82494f8159f62f434bc9c7.jpg

27d4f76fa36d4e8ab3279e8e6b338eeb.jpg?

?二.软件设计

1,主函数程序设计

所需文件

18991d0622794446bf1a2819a9e1b374.jpg

?主函数程序介绍

在主函数中,首先我们要做的是对我们所用到的库函数,延迟函数,时钟,led灯函数和按键函数进行初始化,初始化之后,进入while循环,由于while里边参数一直为1(即真),所以单片机就一直执行while循环里边的程序。

#include "sys.h"

#include "delay.h"

#include "usart.h"

#include "led.h"

#include "key.h"

#include "lsd.h"

#include "lsdd.h"

#define a 100

//int i,j;

int main(void)

{

? ? u8 key;

? ? HAL_Init(); //初始化HAL库

? ? Stm32_Clock_Init(360,25,2,8); //设置时钟

? ? delay_init(180); //初始化延时函数

? ? uart_init(115200); //初始化USART

? ? LED_Init(); //初始化LED

? ? KEY_Init(); //初始化按键

如下图所示。我们来讲一下while循环里边的程序。

首先,他是调用了按键扫描函数,并且给的参数为1,按键扫描程序的主要功能,大家可以先去看本文章的第二节按键扫描函数,在来看这里会比较轻松。这里调用按键扫描函数之后,当我们按下按键后,按键扫描函数会相应地给主调函数(即这里的key=KEY_Scan(1)函数)一个返回值,然后使用switch(key)函数可以匹配出是返回的哪一个返回值,匹配成功之后就可以执行我们的心形流水灯代码,执行之后跳出再进行按键扫描。最后还有一个延迟函数,是用来设置扫描的频率。这里设置的是十号秒扫描一次,可以根据自己的爱好设置按键扫描的频率。

?while(1)

? ? {?

? ? ? ? key=KEY_Scan(1); //扫描按键

? ? switch(key)

? ? {? ? ?

? ? ?case WKUP_PRES: //控制红色流水灯

? ? ? lsd_nice();?

? ? ? break;

? ? ?case KEY2_PRES: //控制绿的流水灯

? ? ? lsd_fuor();

? ? ? ? break;

? ? ?case KEY1_PRES: //红色先亮,绿色再亮

? ? ? lsd_nice();lsd_fuor();

? ? ? ?break;

? ? ?case KEY0_PRES: //绿色先亮,红色再亮

? ? ? lsd_fuor();lsd_nice();

? ? ? ?break;

? ?}

? ? ? ? delay_ms(10); //每十毫秒扫描一次

? }

}

2,按键key.c初始化

按键初始化函数。首先是一个对结构体变量的重命名。通过访问新名词GPIO_Initure即可完成对GPIO_InitTypeDef结构体的访问。接着是打开了GPIOA,C,H的时钟。在配置任何GPIO口的时候,我们第一步都是要先打开对应的时钟,大家可以理解为,这个时钟就是我们的大门,只有大门打开了,我们才可以进出,单片机也一样,只有时钟打开了,我们才可以配置他的引脚,具体打开哪几个引脚,是输入还是书痴,是高速还是低速,是上拉还是下拉等等。设置完之后按键初始化也就完成了。

#include "key.h"

#include "delay.h"

void KEY_Init(void)

{

? ? GPIO_InitTypeDef GPIO_Initure;

? ??

? ? __HAL_RCC_GPIOA_CLK_ENABLE(); //打开GPIOA时钟

? ? __HAL_RCC_GPIOC_CLK_ENABLE(); //打开GPIOC时钟

? ? __HAL_RCC_GPIOH_CLK_ENABLE(); //打开GPIOH时钟

? ??

? ? GPIO_Initure.Pin=GPIO_PIN_0; //PA0

? ? GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入

? ? GPIO_Initure.Pull=GPIO_PULLDOWN; //?下拉

? ? GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速

? ? HAL_GPIO_Init(GPIOA,&GPIO_Initure);

? ??

? ? GPIO_Initure.Pin=GPIO_PIN_13; //PC13

? ? GPIO_Initure.Mode=GPIO_MODE_INPUT; //输入

? ? GPIO_Initure.Pull=GPIO_PULLUP; //上拉

? ? GPIO_Initure.Speed=GPIO_SPEED_HIGH; //高速

? ? HAL_GPIO_Init(GPIOC,&GPIO_Initure);

? ??

? ? GPIO_Initure.Pin=GPIO_PIN_2|GPIO_PIN_3; //PH2,3

? ? HAL_GPIO_Init(GPIOH,&GPIO_Initure);

}

按键key.c扫描函数

按键扫描函数。这里是重点也是难点。在主函数里边我们调用了KEY_Scan(u8 mode)这个函数,这个函数就是按键扫描函数。在该函数中,当mode=1的时候支持连按,当mode=0的时候不支持连按。他是怎样作用的呢?首先,大家要了解这个静态变量static,他是一个静态变量。当该函数第一次被调用的时候,他会被执行一次,给kup_up赋初值为1,当第二次以及以后再被调用的时候,他就不在执行了,所以在这里首先key_up为1,接下来是一个if判断,当mode等1的时候,支持连按,这里是1,所以到这里,key_up的值还是等于1,接着进入if判断,这里是key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1)这两个条件的与运算,当都为真的时候,才会执行下边的程序。首先key_up是为1的,现在就是判断有没有按键被按下。当有按键被按下的时候,就会使后边的为1,if里边的语句也就执行了。首先是延迟函数,用来消除按键的抖动。然后这里又给key_up赋值为0。注意!在这个地方,key_up的值变为0了。接着往下执行,这时候又是一个if语句,用来判断那个按键被按下,然后返回被按下的按键值。如果没有按键被按下的时候,又给kup_up赋值为1,不影响以后得调用。

优先级:KEY0>KEY1>KEY2>WK_UP!!

u8 KEY_Scan(u8 mode)

{

? ? static u8 key_up=1; //按键松开标志

? ? if(mode==1) //mode=0:不支持连按,=1,支持连按

? key_up=1; //支持连按

? ? if(key_up&&(KEY0==0||KEY1==0||KEY2==0||WK_UP==1))

? ? {

? ? ? ? delay_ms(10);

? ? ? ? key_up=0;

? ? ? ? if (KEY0==0) return KEY0_PRES;

? ? ? ? else if(KEY1==0) return KEY1_PRES;

? ? ? ? else if(KEY2==0) return KEY2_PRES;

? ? ? ? else if(WK_UP==1) return WKUP_PRES;? ? ? ? ??

? ? }

?else if(KEY0==1&&KEY1==1&&KEY2==1&&WK_UP==0)

?key_up=1;

return 0; //无按键按下

??

?3,流水灯程序lsd.c

流水灯程序是用来控制流水灯的亮灭的,这里用了一个for循环来设置循环的次数,一个宏定义来统一调整循环的时间。这个函数比较简单,就不在一一赘述。如果不太明白,欢迎评论。bilibili网站有配套的视频,讲解的更为清晰。打开bilibili->搜索->文静之森->按键扫描函数。里边有对静态变量static,按键原理,按键扫描函数作用原理的详细讲解,欢迎大家查看

#include "lsd.h"

#include "sys.h"

#include "delay.h"

#include "usart.h"

#include "led.h"

#define a 100

int i;

void lsd_nice(void)

{

?for(i=0;i<=0;i++)

?{

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_14,GPIO_PIN_RESET);

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET); //

? delay_ms(a); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_RESET); //

? delay_ms(a); //?

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET); //

? delay_ms(a); //

HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_2,GPIO_PIN_RESET); //

? delay_ms(a); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_3,GPIO_PIN_RESET); //

? delay_ms(a); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET); //

? delay_ms(a); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET); //

? delay_ms(a); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_6,GPIO_PIN_RESET); //

? delay_ms(a); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_7,GPIO_PIN_RESET); //

? delay_ms(a); //?

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_0,GPIO_PIN_SET); //

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_8,GPIO_PIN_RESET); //

? delay_ms(a);? ? ? ? ?

? }? ? ? ??

? HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);

}

?

?

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2022-09-30 01:07:48  更:2022-09-30 01:09:32 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 16:48:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码