STM32单片机基本原理与应用(三)
矩阵键盘工作原理
矩阵键盘由多个独立按键组成,按键的一端接地,一端接MCU的GPIO。当按键没有被按下时,电路其实是一个断路,将单片机该引脚设置成输入上拉状态,读到的电平为高电平。当按下按键时,引脚会被拉低,此时读到的电平为低电平,说明按键已经被按下。
4*4的矩阵键盘,通常采用逐行逐列进行扫描。先扫描第一行,将该行输出高电平,其他行输出低电平,记为0xF7(1111 0111)。然后开始扫描列,控制列的引脚为输入引脚,将其和0XF7相与,如果哪一位为0,那么就证明哪一个被按下。
其本质就是进行逐行扫描和逐列扫描,然后判断是第几行的第几列个按键,进而进行整体按键值得确定。

实验案例
随机按下矩阵键盘按键,可以在TFTLCD屏上观察到相应的数值。
- 实验需要:STM32核心板 和 4*4矩阵键盘
- 电路原理图:

其中KR-0对应单片机PC0,KR-1对应PC1,KR-2对应PC2,KR-3对应PC3,KC-0对应PC4,KC-1对应PC5,KC-2对应PC6,KC-3对应PC7。
程序源码:
首先,要对矩阵键盘IO进行初始化,定义好矩阵键盘的行和列。然后需要定义好矩阵键盘扫描函数,用于判断键盘按键是否按下。矩阵键盘扫描函数如下。
u8 keyscan(void)
{ uint8_t LIE,HANG,k,i=0;GPIO_Write(GPIOC, 0xF0); //D0-D3拉低,D4-D7拉高if((GPIO_ReadInputData(GPIOC)&0xF0)!=0xF0) //有按键按下{delay_ms(40); //去抖if((GPIO_ReadInputData(GPIOC)&0xF0)!=0xF0) //再次判断是否按下{LIE=GPIO_ReadInputData(GPIOC); //读取按键按下后得到的代码HANG=LIE; //将代码复制给行LIE=~LIE; //将键码取反,例如:按下某个键得到0111 0000,取反后得到1000 1111LIE=LIE&0XF0; //得到列1000 1111&1111 0000得到1000 0000,得到列数for(i=0;i<4&&((HANG&0xF0)!=0xF0);i++) //逐次将行拉高,判断列数中原来变低的位是否变高{ //读到之前检测到为低的列变高则推出GPIO_Write(GPIOC, (HANG&0xF0)|(0x01<<i)); //进行行扫描,逐次将行口线拉高,列保持为按下的状态HANG=GPIO_ReadInputData(GPIOC); //读取IO口,用以判断是否扫描到行坐标 }HANG&=0x0F; //将航值取出k=LIE|HANG; //行列相加则得到键码GPIO_Write(GPIOC, 0xF0); //D0-D3拉低,D4-D7拉高,此处用来将行状态初始化为未按下时的状态while((GPIO_ReadInputData(GPIOC)&0xF0)!=0xF0) //判释放{delay_ms(40); //后延消抖。时间需要长一点}return k; //返回键码}} return (0); //无键按下,返回0
}
在主函数中实现功能,进行函数调用。为方便验证按键是否按下并方便观察,使其在屏幕中显示,主函数中包含显示功能。主函数如下。
int main(void){ u8 x=0;u8 lcd_id[12]; //存放LCD ID字符串u8 key_value;u8 buf[20]; delay_init(); //延时函数初始化 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级uart_init(115200); //串口初始化为115200LED_Init(); //LED端口初始化LCD_Init();KEY_Init(); //矩阵按键初始化!!! sprintf((char*)lcd_id,"LCD ID:%04X",lcddev.id);//将LCD ID打印到lcd_id数组。 POINT_COLOR=RED; LCD_ShowString(30,40,210,24,24,"STM32 ^_^"); LCD_ShowString(30,70,200,16,16,"TFTLCD TEST");LCD_ShowString(30,90,200,16,16,"STM32F103ZET6");LCD_ShowString(30,110,200,16,16,lcd_id); //显示LCD IDLCD_ShowString(30,130,200,12,12,"2020/5/4");while(1) { key_value = keyscan();if(key_value > 0){ LCD_ShowNum(30,170,key_value,4,12);}}
}
实验现象:
矩阵键盘从左上角到右下角显示的数值依次为1~16。
红外对管测速原理
红外对管实质上是一种光电转换器件,由发射管和接收管组成。发射管发出的光束经过聚焦后照射到被测物体上。接收管则负责接反射回来的光束,将光信号转换为电信号,产生光电效应。转换的这个电信号的大小取决于接收到的光强度。
为了能够准确地检测物体的移动速度,需要对接收管产生的电信号进行适当的处理。常见的信号处理电路包括放大器、滤波器、比较器等。放大器用于放大微弱的电信号,滤波器用于消除噪声,比较器用于将信号转换为数字信号。
实验案例
在实验中,我们采用定时器中断,实现红外对管的测速。
- 实验需要:STM32核心板+直流电机+蜂鸣器+光电对管
- 电路原理图:

LM393会将光电对管输出的电压变化转换为高低电平方波并通过IRS-IO输出到单片机,其中滑动电阻用于控制光电对管的灵敏度。
光电对管的输出口会通过选择开关与单片机的PB13接口相连。
程序源码:
1、中断函数和中断服务程序
void EXTIX_Init(void)
{EXTI_InitTypeDef EXTI_InitStructure;NVIC_InitTypeDef NVIC_InitStructure;INFRARED_Init();RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); //使能复用功能时钟//PB13 中断线以及中断初始化配置 下降沿触发 PB13 //红外对管对应PB13GPIO_EXTILineConfig(GPIO_PortSourceGPIOB,GPIO_PinSource13); EXTI_InitStructure.EXTI_Line=EXTI_Line13;EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; EXTI_InitStructure.EXTI_LineCmd = ENABLE;EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; // 下降沿EXTI_Init(&EXTI_InitStructure); //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器NVIC_InitStructure.NVIC_IRQChannel = EXTI15_10_IRQn; //使能红外对管所在的外部中断通道NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02; //抢占优先级2, NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x03; //子优先级3NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能外部中断通道NVIC_Init(&NVIC_InitStructure);
}
//外部中断13服务程序
void EXTI15_10_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line13)==SET){count ++ ; BEEP=!BEEP; EXTI_ClearITPendingBit(EXTI_Line13); //清除LINE13 上的中断标志位 }
}
2、主函数
int main(void){ delay_init(); //延时函数初始化¯ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); /设置NVIC中断分组2:2抢占优先级,2响应优先级uart_init(115200); //´串口初始化为115200DCMOTOR_Init(); //直流电机初始化 LCD_Init();POINT_COLOR=RED;INFRARED_Init(); //初始化红外对管的硬件接口DCMOTOR1 = 1; //启动直流电机LED_Init(); //LED初始化 LCD_ShowString(30,40,210,24,24,"STM32 ^_^"); LCD_ShowString(30,70,200,16,16,"TFTLCD TEST");LCD_ShowString(30,90,200,16,16,"STM32F103ZET6");LCD_ShowString(30,130,200,12,12,"2020/5/4"); LCD_ShowString(30,170,200,16,16,"COUNT:"); TIM3_Int_Init(4999,7199);//10Khz的技术频率,技术到5000为500msEXTIX_Init(); //外部中断初始化¯count = 0 ;timer_count = 0 ;while(1){ if(timer_count > 0){ count_temp = count;count = 0;timer_count = 0; LCD_ShowNum(78,170,count_temp,4,16); //当前显示的为1s内转的格数 count_temp = 0 ;} }}
实验现象:
下载成功后,复位,两个直流电机带动码盘转动。通过红外对管检测码盘计数,并在液晶屏上显示0.5秒内码盘转动格子数。
相关文章:
STM32单片机基本原理与应用(三)
矩阵键盘工作原理 矩阵键盘由多个独立按键组成,按键的一端接地,一端接MCU的GPIO。当按键没有被按下时,电路其实是一个断路,将单片机该引脚设置成输入上拉状态,读到的电平为高电平。当按下按键时,引脚会被拉…...
Android studio布局详解
文章目录 一、Android studio布局详解二、Android studio六大布局案例三、优缺点四、热门文章 一、Android studio布局详解 Android Studio是一种用于开发Android应用程序的集成开发环境(IDE),用于设计和编辑Android应用程序的用户界面布局。在Android …...
第四篇:怎么写express的路由(接口+请求)
🎬 江城开朗的豌豆:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 📝 个人网站 :《 江城开朗的豌豆🫛 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 📘 引言: Ǵ…...
算法学习记录:有关树的基础
前言: 算法学习记录不是算法介绍,本文记录的是从零开始的学习过程(见到的例题,代码的理解……),所有内容按学习顺序更新,而且不保证正确,如有错误,请帮助指出。 学习工具…...
2. 《大数据之路:阿里巴巴大数据实践》学习笔记,持续更新ing
笔记链接(飞书):https://t0s016els2a.feishu.cn/docx/JrNydGljUonH1ExcGCpcoC8unTb 密码:r661391 该书籍部分目录如下: 文章目录 第1篇 数据技术篇第2章 日志采集2.1 浏览器的页面日志采集2.1.1 页面浏览日志采集流程2.1.2 页面交互日志采集…...
编程笔记 html5cssjs 062 JavaScrip如何使用
编程笔记 html5&css&js 062 JavaScrip如何使用 一、 引入JavaScript二、DOM操作三、事件处理四、数据验证五、异步编程六、使用库和框架七、模块化开发小结 开始学习使用JavaScript进行前端开发的基本步骤和常见实践。 这里先列示基本的步骤和内容,后面慢慢…...
【前端基础--7】
DOM操作 DOM,全称(Document Object Model),文档对象模型。 提供操作HTML的方法(操作页面元素) 获取节点 --- 操作元素标签 <body><div id"box">我是盒子标签</div><p class"text"&g…...
微信小程序如何搜索iBeacon设备
1.首先在utils文件夹下创建bluetooth.js和ibeacon.js 2.在 bluetooth.js文件中写入 module.exports {initBluetooth: function () {// 初始化蓝牙模块wx.openBluetoothAdapter({success: function (res) {console.log(蓝牙模块初始化成功);},fail: function (res) {console.l…...
JVM篇:垃圾回收算法
标记清除 通过遍历GC Root后得到不再被引用的对象,对没被引用的对象做一个标记处理,然后对其进行清除。 优点:速度快 缺点:会产生内存碎片,可能会导致空闲的内存足够保存对象,但由于不连续而保存失败。 标…...
2024年数学建模美赛 分析与编程
2024年数学建模美赛 分析与编程 1、本专栏将在2024年美赛题目公布后,进行深入分析,建议收藏; 2、本专栏对2023年赛题,其它题目分析详见专题讨论; 2023年数学建模美赛A题(A drought stricken plant communi…...
05-Nacos-配置中心接入
1、pom依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency> 2、配置文件 spring:application:name: nacos-config## 当前环境,这个和…...
服务端开发小记02——Maven
这里写目录标题 Maven简介Maven在Linux下的安装Maven常用命令 Maven简介 Apache Maven Project是一个apache的开源项目,是用于构建和管理Java项目的工具包。 用Maven可以方便地创建项目,基于archetype可以创建多种类型的java项目;Maven仓库…...
DjangoURL调度器(一)
一、介绍 当一个用户请求 Django 站点的一个页面,下面是 Django 系统决定执行哪个 Python 代码使用的算法: Django确定要使用的根URLconf模块,一般是在settings中的ROOT_URLCONF设置的值,但是如果传入 HttpRequest 对象具有一个ur…...
Typora 无法导出 pdf 问题的解决
目录 问题描述 解决困难 解决方法 问题描述 我的 Windows 下,以前(Windows 11) Typora 可以顺利较快地由 .md 导出 .pdf 文件,此功能当然非常实用与重要。 然而,有一次电脑因故重装了系统(刷机&#x…...
uniapp封装公共的方法或者数据请求方法
仅供自己参考,不是每个页面都用到这个方法,所以我直接在用到的页面引用该公用方法: 1、新建一个util.js文件 export const address function(options){return new Promise((resolve,reject)>{uni.request({url:"https://x.cxniu.…...
SpringBoot AOP应用(公共字段填充)
背景 在很多场景下,我们对需要对一些公共字段进行赋值操作,如果我们每一个公共字段都进行代码赋值那无疑会增加很多重复无用代码,都会导致我们的 代码臃肿,所以我们使用AOP切面编程,实现功能增强,来完成公…...
NIO案例-聊天室
NIO案例-聊天室 1. 聊天室服务端编写 package com.my.io.chat.server; import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.nio.charset.StandardCharsets; import java.util.Iterato…...
文心一言情感关怀之旅
【AGIFoundathon】文心一言情感关怀之旅,让我们一起来体验吧! 上传一张照片,用ernie-bot生成专属于你的小故事! 此项目主要使用clip_interrogator获取图片的关键信息,然后将此关键信息用百度翻译API翻译成中文后,使用封装了⼀⾔API的Ernie Bot SDK(ernie-bot)生成故事…...
mac电脑安卓文件传输工具:Android File Transfer直装版
Android File Transfer(AFT)是一款用于在Mac操作系统上与Android设备之间传输文件。它允许用户将照片、音乐、视频和其他文件从他们的Android手机或平板电脑传输到Mac电脑,以及将文件从Mac上传到Android设备。 下载地址:https://w…...
第九篇【传奇开心果系列】beeware的toga开发移动应用示例:人口普查手机应用
传奇开心果博文系列 系列博文目录beeware的toga开发移动应用示例系列博文目录一、项目目标二、安装依赖三、实现应用雏形示例代码四、扩展功能和组件的考量五、添加更多输入字段示例代码六、添加验证功能示例代码七、添加数据存储功能示例代码八、添加数据展示功能示例代码九、…...
IDEA运行Tomcat出现乱码问题解决汇总
最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
【Oracle APEX开发小技巧12】
有如下需求: 有一个问题反馈页面,要实现在apex页面展示能直观看到反馈时间超过7天未处理的数据,方便管理员及时处理反馈。 我的方法:直接将逻辑写在SQL中,这样可以直接在页面展示 完整代码: SELECTSF.FE…...
YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
sipsak:SIP瑞士军刀!全参数详细教程!Kali Linux教程!
简介 sipsak 是一个面向会话初始协议 (SIP) 应用程序开发人员和管理员的小型命令行工具。它可以用于对 SIP 应用程序和设备进行一些简单的测试。 sipsak 是一款 SIP 压力和诊断实用程序。它通过 sip-uri 向服务器发送 SIP 请求,并检查收到的响应。它以以下模式之一…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险
C#入门系列【类的基本概念】:开启编程世界的奇妙冒险 嘿,各位编程小白探险家!欢迎来到 C# 的奇幻大陆!今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类!别害怕,跟着我,保准让你轻松搞…...
CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝
目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为:一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...
