【STM32嵌入式系统设计与开发】——17ADC(ADC按键应用)

news2024/11/28 12:42:40

这里写目录标题

    • STM32资料包: 百度网盘下载链接:链接:https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd=8888 提取码:8888
  • 一、任务描述
  • 二、任务实施
    • 1、工程文件夹创建
    • 2、函数编辑
      • (1)主函数编辑
      • (2)ADC模拟数字转化函数()
      • (3)获得ADC值函数(Get_Adc())
      • (4)获得ADC的平均值函数(Get_Adc_Average())
      • (5)ADC按键初始化函数(AdKeyScan())
    • 3、头文件添加
    • 4、头文件编辑
    • 4、知识链接
      • (1)ADC框图理解
      • (2)按键原理
    • 5、工程测试


STM32资料包:
百度网盘下载链接:链接:https://pan.baidu.com/s/1mWx9Asaipk-2z9HY17wYXQ?pwd=8888
提取码:8888

一、任务描述

在这里插入图片描述

二、任务实施

观察电路图:
TXD(底板) ————————> PA10
RXD(底板) ————————> PA9
AD按键端口(底板) ————————> PA1
通过 ADC 采样获取按键的状态,根据采样值判断按键是否被按下,并返回对应的按键编号(ADKEY_AK1、ADKEY_AK2、ADKEY_AK3、ADKEY_AK4)或者无按键情况(ADKEY_NO),并打印在串口助手中
在这里插入图片描述

1、工程文件夹创建

步骤1:复制工程模板“1_Template”重命名为“14_ADC”。
在这里插入图片描述
步骤2:修改项目工程名,先删除projects文件夹内除了Template.uvprojx文件外的所有内容并修改为“ADC.uvprojx”。并删除output/obj和output/lst中的所有文件。
在这里插入图片描述
步骤3:运行“PassiveBeep.uvprojx”打开目标选项“Options for Target”中的“Output”输出文件,并修改可执行文件名称为“ADC”点击“OK”保存设置。最后点击“Rebuild”编译该工程生成Usart文件。
在这里插入图片描述
步骤4:复制2_LEDTest中的"1_LED"和文件复制到hardware中。
在这里插入图片描述
步骤5:在system文件夹中新建一个adc文件夹并在该文件夹下新建adc.c和adc.h两个文件。
在这里插入图片描述
步骤6:工程组文件中添加“1_LED”和“2_ADCKEY”文件夹内的所有文件。
在这里插入图片描述
步骤7:工程组文件中添加“adc”文件夹内的所有文件。
在这里插入图片描述
步骤6:目标选项添加添加头文件路径。
在这里插入图片描述

2、函数编辑

(1)主函数编辑

基于STM32的检测定时器超时状态并翻转LED的状态,同时检测AD按键状态并输出按下的按键编号到串口。
请添加图片描述
步骤2:循环函数编写

while(1) // 进入无限循环
{	
	if(WaitTimerOut(3))                  // 如果等待计时器超时(3秒)
		LED = !LED;                      // 切换 LED 的状态(取反)
	
	temp = AdKeyScan();                  // 读取 AD 按键的状态
	if(temp)                             // 如果检测到按键按下(按键值不为0)
		printf("AK%d被按下!\r\n", temp); // 打印按下的按键编号
}	

在这里插入图片描述

(2)ADC模拟数字转化函数()

步骤1:初始化ADC

/*********************************************************************
 @Function  : 初始化ADC
 @Parameter : N/A
 @Return    : N/A
**********************************************************************/
void Adc_Init(void)
{ 
	/*初始化结构体*/
	ADC_InitTypeDef ADC_InitStructure;                                  // 定义 ADC 初始化结构体
	GPIO_InitTypeDef GPIO_InitStructure;                                // 定义 GPIO 初始化结构体
		
	/* 时钟使能 */
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_ADC1, ENABLE);	

	/* 设置ADC分频因子 */
	RCC_ADCCLKConfig(RCC_PCLK2_Div6);                                   // 将ADC时钟设置为PCLK2的1/6,此处PCLK2为72MHz,分频后为12MHz
		
	/* 引脚配置 */
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;                           // 配置PA1为ADC输入
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;                       // 模拟输入模式
	GPIO_Init(GPIOA, &GPIO_InitStructure);                              // 初始化GPIOA	

	/* 复位ADC1 */
	ADC_DeInit(ADC1);  
		
	/* ADC配置 */
	ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;                  // 独立模式,单独使用ADC1
	ADC_InitStructure.ADC_ScanConvMode = DISABLE;                       // 关闭扫描模式,单通道模式
	ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;                 // 关闭连续转换模式,单次转换模式
	ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; // 软件触发转换
	ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;              // 数据右对齐
	ADC_InitStructure.ADC_NbrOfChannel = 1;                             // 转换通道数量为1
	ADC_Init(ADC1, &ADC_InitStructure);                                 // 初始化ADC1
		
	/* 使能ADC */
	ADC_Cmd(ADC1, ENABLE);

	/* 复位校准 */
	ADC_ResetCalibration(ADC1);
	while (ADC_GetResetCalibrationStatus(ADC1));                        // 等待复位校准结束

	/* 开始校准 */
	ADC_StartCalibration(ADC1);
	while (ADC_GetCalibrationStatus(ADC1));                             // 等待校准结束

	/* 使能软件转换启动功能(可根据需要启用) */
	// ADC_SoftwareStartConvCmd(ADC1, ENABLE);	

}

在这里插入图片描述

(3)获得ADC值函数(Get_Adc())

/*********************************************************************
 @Function  : 获得ADC值
 @Parameter : ch : 通道值 0~3
 @Return    : ADC值
**********************************************************************/
uint16_t Get_Adc(uint8_t ch)   
{
	/*设置指定ADC的规则组通道,一个序列,采样时间*/
	ADC_RegularChannelConfig(ADC1, ch, 1, ADC_SampleTime_239Cycles5 );	//ADC1,ADC通道,采样时间为239.5周期	  
	
	ADC_SoftwareStartConvCmd(ADC1, ENABLE);		                        //使能指定的ADC1的软件转换启动功能
	
	while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));                     //等待转换结束

	return ADC_GetConversionValue(ADC1);	                            //返回最近一次ADC1规则组的转换结果
	
}

在这里插入图片描述

(4)获得ADC的平均值函数(Get_Adc_Average())

/*********************************************************************
 @Function  : 获得ADC的平均值
 @Parameter : ch : 通道值 0~3
						  times :采集次数
 @Return    : ADC平均值
**********************************************************************/
uint16_t Get_Adc_Average(uint8_t ch, uint8_t times)
{

	uint32_t temp_val = 0;      // 初始化累加变量为0
	uint8_t t;                  // 循环计数变量

	for (t = 0; t < times; t++) // 循环执行指定次数
	{
		temp_val += Get_Adc(ch);  // 获取指定通道的ADC值并累加到temp_val
		delay_ms(5);              // 延时5毫秒,等待下一次采样		
	}
	return temp_val / times;    // 返回ADC采样值的平均值

}

在这里插入图片描述

(5)ADC按键初始化函数(AdKeyScan())


/*********************************************************************
 @Function  : AD按键初始化
 @Parameter : N/A
 @Return    : N/A
**********************************************************************/
uint8_t AdKeyScan(void)
{
	uint16_t adcx; // 定义ADC采样值变量adcx
	/* 读取ADC */
  adcx = Get_Adc_Average(ADC_Channel_1, 10);         // 读取ADC通道1的平均值,采样次数为10次
	
	/* 键值判断 */
	if (adcx > 500)                                  // 如果ADC值大于500
	{
		if ((adcx > 3500) && (adcx < 4200))
				return ADKEY_AK1;                    // 返回ADKEY_AK1,表示检测到按键1被按下

		if ((adcx > 2500) && (adcx < 3200))
				return ADKEY_AK2;                    // 返回ADKEY_AK2,表示检测到按键2被按下

		if ((adcx > 1500) && (adcx < 2200))
				return ADKEY_AK3;                    // 返回ADKEY_AK3,表示检测到按键3被按下

		if ((adcx > 800) && (adcx < 1200))
				return ADKEY_AK4;                    // 返回ADKEY_AK4,表示检测到按键4被按下
	}

}

在这里插入图片描述

3、头文件添加

步骤1:adc所需头文件添加

#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_adc.h"
#include ".\adc\adc.h"
#include ".\delay\delay.h"

在这里插入图片描述
步骤2:添加adckey源文件所需的头文件

#include "stm32f10x_adc.h"
#include ".\adc\adc.h"
#include "adckey.h"

在这里插入图片描述
步骤3:函数声明

	uint32_t temp=0;
	delay_init();                   //启动滴答定时器
    usart1_init(9600);              //USART1初始化
	SystemTinerInit(1000-1,3600-1); //系统时间初始化 定时100ms
    AdKeyInit();                    //AD按键初始化	

在这里插入图片描述

4、头文件编辑

//bord.h
#ifndef __BORD_H_
#define __BORD_H_
#include "system_config.h"

//头文件包含
/*************SYSTEM*****************/
/*#include ".\sys\sys.h"*/
#include ".\delay\delay.h"
#include ".\usart\usart.h"
#include ".\timer\timer.h"
#include ".\adc\adc.h"

/***********Hardweare***************/
#include "led.h"
#include "adckey.h"

/***********Funlibrary***************/





#endif

在这里插入图片描述

步骤2:添加函数声明

//adc.h
#ifndef __ADC_H_
#define __ADC_H_	
#include <stdint.h>

/*函数声明*/
void Adc_Init(void);
uint16_t Get_Adc(uint8_t ch); 
uint16_t Get_Adc_Average(uint8_t ch,uint8_t times); 


#endif

在这里插入图片描述

步骤2:添加中断源文件所需的头文件

//adckey.h
#ifndef __ADKEY_H_
#define __ADKEY_H_	

#include <stdint.h> 

//AD键值枚举
enum ADkey 
{
  ADKEY_NO=0,
	ADKEY_AK1,
	ADKEY_AK2,
	ADKEY_AK3,
	ADKEY_AK4
};

/*函数声明*/
void AdKeyInit(void);
uint8_t AdKeyScan(void);

#endif

在这里插入图片描述

4、知识链接

(1)ADC框图理解

在这里插入图片描述
ADC引脚:
ADC 框图中的引脚用于连接外部模拟信号。通常有一个或多个引脚作为模拟输入,将待转换的模拟信号输入给 ADC。此外,可能还有其他引脚用于控制、时钟输入和数字输出。

ADC输入通道:
ADC 输入通道是连接到 ADC 的引脚,用于接收模拟信号。每个输入通道对应一个物理引脚或者电路连接,可以选择不同的通道来进行模拟信号的采集和转换。

规则通道组和注入通道组:

规则通道组和注入通道组是 ADC 中用于管理转换通道的组织方式。
规则通道组用于常规的模拟输入信号转换,可以选择一个或多个通道进行顺序转换。
注入通道组允许在常规转换中插入一个或多个优先级更高的转换(例如紧急事件处理),通常用于特殊需求或优先级较高的采样。
触发源:
ADC 可以通过不同的触发源启动转换。触发源可以是软件触发(通过编程触发)、定时器触发(定时器计数到特定值触发)、外部触发(外部引脚触发)等。选择合适的触发源可以灵活控制 ADC 的转换时机。

转换时间:
转换时间是 ADC 完成一次模拟到数字转换所需的时间。这个时间取决于 ADC 的工作模式、时钟频率以及转换精度等因素。在设计中需要考虑转换时间来确定系统的响应速度和性能。

数据寄存器:
转换完成后,ADC 将数字化的采样值存储在数据寄存器中。系统可以通过读取数据寄存器来获取 ADC 的转换结果,进而进行后续的数据处理和分析。

中断:
ADC 可以通过中断来提醒系统转换完成或者出现特定的转换事件。通过配置中断使能和中断优先级,可以实现在转换完成后自动触发特定的处理程序,提高系统的实时性和效率。

(2)按键原理

在这里插入图片描述
基本原理是利用电阻分压的方式,通过按下不同的按键改变电路中的电压值,然后使用 ADC(模数转换器)引脚对这些电压进行采集。采集到的电压值随后用于判断按下了哪个按键,从而实现按键功能。

5、工程测试

在这里插入图片描述

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

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

相关文章

DTC 子故障类型说明

在配置cdd的时候&#xff0c;需要知道子故障类型&#xff0c;例如一个DTC &#xff1a;0xC128187, 这个0x87就是子故障类型&#xff0c;是一种常见的故障类型&#xff0c;对手件timeout

微商商城源码小程序好用么?

商城APP作为电子商务行业的重要组成部分&#xff0c;已经成为了人们购物的主要方式之一。为了在竞争激烈的市场中脱颖而出&#xff0c;开发一款专业且思考深度的商城APP方案显得尤为关键。本文将从专业性和思考深度两个方面&#xff0c;探讨商城APP的开发方案。 一、专业性的重…

计算机网络常见面试总结

文章目录 1. 计算机网络基础1.1 网络分层模型1. OSI 七层模型是什么&#xff1f;每一层的作用是什么&#xff1f;2.TCP/IP 四层模型是什么&#xff1f;每一层的作用是什么&#xff1f;3. 为什么网络要分层&#xff1f; 1.2 常见网络协议1. 应用层有哪些常见的协议&#xff1f;2…

jetbrains全家桶历史版本下载(IDEA/PyCharm...)

IDEA&#xff1a; 其他版本 - IntelliJ IDEA (jetbrains.com)https://www.jetbrains.com/zh-cn/idea/download/other.html PyCharm: 其他版本 - PyCharm (jetbrains.com)https://www.jetbrains.com/zh-cn/pycharm/download/other.html Goland: 其他版本 - GoLand (jetbrain…

TQ15EG开发板教程:在MPSOC上运行ADRV9371

首先需要在github上下载两个文件&#xff0c;本例程用到的文件以及最终文件我都会放在网盘里面&#xff0c; 地址放在本文最后。首先在github搜索hdl选择第一个&#xff0c;如下图所示 GitHub网址&#xff1a;https://github.com/analogdevicesinc/hdl/releases 点击releases…

python+django电子资源类学习资料分享网站flask

本设计是电子资源类的网站设计与实现&#xff0c;。系统前台实现了首页&#xff0c;分享资源&#xff0c;交流论坛&#xff0c;公告信息&#xff0c;个人中心&#xff0c;后台管理等功能。系统的后台实现了首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;分享资源管…

Android零基础入门(一)配置环境和安装Android Studio

闲来无事学一下Android&#xff0c;本人目前java为主&#xff0c;jdk的环境就不赘述了 配置环境 Java JDK5 或 以后版本 Android SDK Java运行时环境&#xff08;JRE&#xff09; Android Studio 你可以从 Oracle 的 Java 网站&#xff1a;JDKJava SE下载下载最新版本的 Jav…

基于PyAutoGUI图片定位的自动化截图工具--jmeter部分

1、计划 压测完成后需要编写性能测试报告&#xff0c;报告中所需数据截图较多&#xff0c;使用自动化操作方便快捷&#xff0c;就编写一个界面工具以便后续复用。之前编写过loadrunner报告的自动化截图脚本&#xff0c;现在用jmeter也比较多&#xff0c;就编写jmeter部分&#…

使用Android Studio制作一个蓝牙软件 ---(一)

一、创建项目&#xff08;项目名称---BluetoothActivity&#xff09; 二、创建HomeActivity页面 1.点击一个文件夹 --- 鼠标右击 --- 新建 --- Acyivity --- Empty Views Activity 三、创建styles.xml 点击 values文件夹 --- 鼠标右击 --- 新建 --- Values Resource File sty…

SLA——让你的信息更安全

在单一的静态密码登录验证机制下&#xff0c;非法入侵者若窃听到Windows桌面登录账号的用户名和密码&#xff0c;便可通过合法权限访问内部系统&#xff0c;此时企业信息安全将面临严峻挑战。 企业为了防止账号信息泄露&#xff0c;通常会强制要求员工定期更换登录密码&#x…

机器学习 -- 端到端的机器学习项目

场景 我们将一个端到端的项目&#xff08;一个从开始到结束包含了所有必要步骤和组件的完整项目&#xff09;案例&#xff0c;步骤大概有&#xff1a; 1.观察大局。 2.获得数据。 3.从数据探索和可视化中获得洞见。 4.机器学习算法的数据准备。 5.选择和训练模型。 6.微调模型…

集合系列(十九) -List与数组互转操作介绍

一、数组转List 方式一 通过 Arrays.asList(strArray) 方式&#xff0c;将数组转换List&#xff0c;但不能对List增删&#xff0c;只能查改&#xff0c;否则抛异常&#xff0c;例子如下&#xff1a; public static void main(String[] args) {//创建一个字符串数组String[] …

Redis(三) String字符串

文章目录 前言常见命令SETGETMSETMGETINCRINCRBYDECRDECRBYINCRBYFLOATAPPENDGETRANGESETRANGESTRLEN命令小结 前言 Redis 的数据有很多种数据类型&#xff0c;包括字符串类型、列表类型、哈希类型、集合类型、有序集合类型等。这几种数据类型是针对于 value 来说的&#xff0…

【算法练习】30:快速排序学习笔记

一、快速排序的算法思想 原理&#xff1a;快速排序基于分治策略。它的基本思想是选择一个元素作为“基准”&#xff0c;将待排序序列划分为两个子序列&#xff0c;使得左边的子序列中的所有元素都小于基准&#xff0c;右边的子序列中的所有元素都大于基准。这个划分操作被称为分…

大量excel文件私密性较强 需要密码保护 如何给excel文件批量加密

一&#xff0c;前言 在现代办公环境中&#xff0c;Excel文件已成为数据存储和交流的常见工具。然而&#xff0c;随着数据泄露和信息安全问题的日益严重&#xff0c;如何保护Excel文件的安全性成为了我们关注的焦点。批量加密Excel文件成为了一种有效的解决方案&#xff0c;它可…

uniapp的h5项目 用命令起这个项目(vue-cli)

这里其实就相当于给uniapp h5套了一个vue-cli的壳&#xff08;纯属个人感觉&#xff09; 首先需要安装vue-cli 脚手架 npm install -g vue/cli然后创建项目&#xff08;这里需要在hbuilder创建&#xff09; vue create -p dcloudio/uni-preset-vue uniapp安装成功后它的结构…

大数据深度学习:基于Tensorflow深度学习的神经网络CNN算法垃圾分类识别系统

文章目录 大数据深度学习&#xff1a;基于Tensorflow深度学习的神经网络CNN算法垃圾分类识别系统一、项目概述二、深度学习卷积神经网络&#xff08;Convolutional Neural Networks&#xff0c;简称CNN&#xff09;三、部分数据库架构四、系统实现系统模型部分核心代码模型训练…

AJAX 入门到实战 第1天 2024 笔记

1.1-AJAX入门与axios使用 1.2-认识URL 1.3-查询参数 1.4-案例_地区查询 <script src"https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script><script>/*获取地区列表: http://hmajax.itheima.net/api/area查询参数:pname: 省份或直辖市…

ios包上架系列 一、打包机Flutter项目环境配置

打包的时候一定要断开网络&#xff0c;上线包名只能在打包机配置 1、Xcode 需要从其它电脑空投 版本号&#xff1a;14.3.1 升级到Xcode14.3后发现,从这个版本开始,苹果从Xcode中移除了ARC相关的库,会导致fluter项目下的原生工程使用Xcode编译原生代码没 有问题, 但是flutter项…

Linux系统使用Docker部署Dashy导航页服务并实现公网环境访问

文章目录 简介1. 安装Dashy2. 安装cpolar3.配置公网访问地址4. 固定域名访问 简介 Dashy 是一个开源的自托管的导航页配置服务&#xff0c;具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一些网站聚合起来放在一起&#xff0c;形成自己的导航…