【stm32/CubeMX、HAL库】swjtu嵌入式实验七 ADC 实验
相关电路与IO引脚


注意:串口打印重定向后使用printf打印需要在keil里勾选 Use MicroLIB ,否则会卡住。
参看:https://zhuanlan.zhihu.com/p/565613666
串口重定向:
/* USER CODE BEGIN Includes */#include <stdio.h>// 包含标准输入输出头文件/* USER CODE END Includes */int fputc(int ch,FILE *f){//采用轮询方式发送1字节数据,超时时间设置为无限等待HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);return ch;}int fgetc(FILE *f){uint8_t ch=0;// 采用轮询方式接收 1字节数据,超时时间设置为无限等待HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );return ch;}
ADC的GPIO复用引脚表:

参考:
视频教程:14.1和14.2节
【【14.1】STM32 ADC模数转换器 感知世界的钥匙——Kevin带你读《STM32Cube高效开发教程基础篇》】 https://www.bilibili.com/video/BV1CV4y1k71M/?share_source=copy_web&vd_source=9332b8fc5ea8d349a54c3989f6189fd3
博客:
https://blog.csdn.net/little_grapes/article/details/121154513
ADC相关函数:

实验内容
1、利用 ADC1 通道 3 采样 PA3 的电压值,将 ADC 采样值和转换的电压值通过串行口返回, 调节电位器,观察运行结果。
根据前面的复用引脚表,选择ADC1的通道IN3。
CubeMX配置如下,

采样时间(sampling time)选择55.5cycles,采样时间长一些结果更准确。
因为也要使用中断方式,所以要开启中断

轮询方式:
/* USER CODE BEGIN 2 */HAL_ADCEx_Calibration_Start(&hadc1);/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 *///轮询HAL_ADC_Start(&hadc1);HAL_ADC_PollForConversion(&hadc1,50);//is it finished?if(HAL_IS_BIT_SET(HAL_ADC_GetState(&hadc1),HAL_ADC_STATE_REG_EOC)){adc_res=HAL_ADC_GetValue(&hadc1);printf("voltage value:%.1f V\r\n",adc_res*3.3/4095);}//延时一段时间再启动转换HAL_Delay(1000);}/* USER CODE END 3 */
中断方式(直接把轮询相关的代码替换,详见参考的文章)
/* USER CODE BEGIN 2 *///中断方式启动ADC转换HAL_ADC_Start_IT(&hadc1);/* USER CODE END 2 */
回调函数:
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){adc_res=HAL_ADC_GetValue(&hadc1);printf("voltage value:%.2f V,original value:%d \r\n",adc_res*3.3/4095,adc_res);}
}
2、编写程序,利用光敏电阻设计光电开关,控制 LED1 点亮和熄灭。
光敏电阻对应引脚PA2,选择ADC1的IN2通道,选择使用定时器作为中断源,注意此时要关闭连续转换,cubemx配置:

记得开启ADC中断。

然后配置定时器,这里用定时器3,频率为72mhz/(7200*5000)

代码:
/* USER CODE BEGIN 2 *///中断方式启动ADC转换HAL_ADC_Start_IT(&hadc1);//开启定时器3HAL_TIM_Base_Start(&htim3);/* USER CODE END 2 */
回调函数(这里设置设置计算电压的方法也是按照3.3V作为参考电压,大于2.1V就点亮灯(这里点亮了两个灯),灯的引脚看前面的GPIO实验)
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){adc_res=HAL_ADC_GetValue(&hadc1);// printf("voltage value:%.1f V\r\n",adc_res*3.3/4095);if(adc_res*3.3/4095>2.1){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,0);HAL_GPIO_WritePin(GPIOF,GPIO_PIN_0,1);} else{HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,1);HAL_GPIO_WritePin(GPIOF,GPIO_PIN_0,0);}}
}
3、设计一个室内温控系统,PA3 采样电压表示采集的温度,阈值上限为 2.5V,下限为 1V,采样电压显示在数码管上。
(1)当采样电压低于 1V(温度过低),蜂鸣器鸣叫(模拟声音报警),LED1 闪烁(模 拟光报警),全彩灯打开(模拟加热)。
(2)当采样电压位于 1V~2.5V 时,正常,蜂鸣器不叫,发光二极管不亮,电机不转。
(3)当采样电压高于 2.5V 时(温度过高),蜂鸣器鸣叫(模拟声音报警),LED1 闪烁 (模拟光报警),电机旋转(模拟风扇降温)。
这里蜂鸣器(PB8)用定时器4通道3输出一定频率的PWM控制,led闪烁间隔时间用cnt控制,循环了一定次数才翻转电平。配置如下:

段码表10以后是原来的数字加上了小数点显示
/* USER CODE BEGIN 0 */uint8_t flag=0;int res=0;
//uint8_t table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80 };//10表示'-'
uint8_t table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x80+0x3f,0x80+0x06,0x80+0x5b,0x80+0x4f,0x80+0x66,0x80+0x6d,0x80+0x7d,0x80+0x07,
0x80+0x7f,0x80+0x6f, };//10表示'-'
uint8_t s[]={0,0,0,0,0,0,10,0};
uint16_t adc_res=0;
int light_flag=0;uint8_t n1;uint8_t n2;void write_byte(uint8_t date){unsigned char i;for(i=0;i<8;i++){HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,(date>>(7-i))&0x01);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,1);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_5,0);}HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,1);HAL_GPIO_WritePin(GPIOA,GPIO_PIN_8,0);}int fputc(int ch,FILE *f){//采用轮询方式发鿿1字节数据,超时时间设置为无限等待HAL_UART_Transmit(&huart1,(uint8_t *)&ch,1,HAL_MAX_DELAY);return ch;}int fgetc(FILE *f){uint8_t ch=0;// 采用轮询方式接收 1字节数据,超时时间设置为无限等待HAL_UART_Receive( &huart1,(uint8_t*)&ch,1, HAL_MAX_DELAY );return ch;}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef* hadc)
{if(hadc->Instance==ADC1){adc_res=HAL_ADC_GetValue(&hadc1);float vol=adc_res*3.3/4095;printf("voltage value:%.2f V\r\n",vol);if(vol <1){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,0);light_flag=1;HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, 0);HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, 0);HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3);} else if(adc_res*3.3/4095 >=1 &&adc_res*3.3/4095<=2.5){HAL_GPIO_WritePin(GPIOB,GPIO_PIN_13,1);HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, 0);HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, 0);HAL_TIM_PWM_Stop(&htim4,TIM_CHANNEL_3);light_flag=0;}else{light_flag=1;HAL_GPIO_WritePin(GPIOD, GPIO_PIN_12, 1);HAL_GPIO_WritePin(GPIOD, GPIO_PIN_13, 0);HAL_TIM_PWM_Start(&htim4,TIM_CHANNEL_3); }n1=(uint8_t)vol;n2=(uint8_t)(vol*10)%10;//printf(" value:%d V\r\n",n1);//printf(" value:%d V\r\n",n2);}
}
int cnt=0;/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if(light_flag==1){cnt++;if(cnt==50){cnt=0;HAL_GPIO_TogglePin(GPIOF,GPIO_PIN_0);}}else{HAL_GPIO_WritePin(GPIOF,GPIO_PIN_0,0);cnt=0;}s[7]=n2;s[6]=n1+10;for(int i=8;i<11;i++){write_byte(table[s[15-i]]);HAL_GPIO_WritePin(GPIOF,0x01<<i,0);HAL_Delay(1);HAL_GPIO_WritePin(GPIOF,0x01<<i,1);}}/* USER CODE END 3 */
源文件见个人主页。
相关文章:
【stm32/CubeMX、HAL库】swjtu嵌入式实验七 ADC 实验
相关电路与IO引脚 注意:串口打印重定向后使用printf打印需要在keil里勾选 Use MicroLIB ,否则会卡住。 参看:https://zhuanlan.zhihu.com/p/565613666 串口重定向: /* USER CODE BEGIN Includes */#include <stdio.h>//…...
springboot 解耦、隔离、异步的原则以及实战
在Spring Boot中实现解耦、隔离和异步的原则,能够提升应用程序的可维护性、可扩展性和性能。下面我会先介绍这三个原则的基本概念和意义,然后通过实战示例展示如何在Spring Boot应用中应用这些原则。 解耦 解耦是减少或消除应用程序组件之间依赖关系的过程,以提高模块的独…...
设计模式详解(八):外观模式——Facade
目录导航 什么是外观模式现实生活类比实战示例门面模式的好处门面模式源码举例 什么是外观模式 外观模式的英文名是Facade,意思是the front of a building,即建筑物的正面(门面),我个人更喜欢翻译成门面模式。门面模式…...
R语言绘图 | 双Y轴截断图
教程原文:双Y轴截断图绘制教程 本期教程 本期教程,我们提供的原文的译文,若有需求请回复关键词:20240529 小杜的生信笔记,自2021年11月开始做的知识分享,主要内容是R语言绘图教程、转录组上游分析、转录组…...
使用PNP管控制MCU是否需要复位
这两台用到一款芯片带电池,希望电池还有电芯片在工作的时候插入电源不要给芯片复位,当电池没电,芯片不在工作的时候,插入电源给芯片复位所以使用一个PNP三极管,通过芯片IO控制是否打开复位,当芯片正常工作的…...
二重,三重积分和曲面,曲线积分的关系和区别
这是我在学习完曲面曲线积分概念后容易和二重三重积分混淆而大概总结和区分了一下,如果有错误请大佬指出,多谢!!!...
处理STM32 DMA方式下的HAL_UART_ERROR_ORE错误
1. 检查并调整DMA和UART配置 确保初始化顺序:需要确保USART的CR寄存器UE位开关留到最后打开,即完成USART和DMA的所有配置初始化后再使能USART。这样可以避免初始化顺序不当导致的通信问题。配置合适的DMA缓冲区:确保DMA缓冲区足够大…...
初学者如何对大模型进行微调?
粗略地说,大模型训练有四个主要阶段:预训练、有监督微调、奖励建模、强化学习。 预训练消耗的时间占据了整个训练pipeline的99%,其他三个阶段是微调阶段,更多地遵循少量 GPU 和数小时或数天的路线。预训练对于算力和数据的要求非…...
【Qt知识】disconnect
在Qt框架中,disconnect函数用于断开信号与槽之间的连接。当不再需要某个信号触发特定槽函数时,或者为了防止内存泄漏和重复执行问题,你可以使用disconnect来取消这种关联。disconnect函数的基本用法可以根据不同的需求采用多种形式࿰…...
String,StringBuffer,StringBuilder的区别?
String是不可变的,StringBuffer和StringBuilder是可变的。StringBuffer是线程安全的,StringBuilder是非线程安全的。 String的 是如何实现的 使用拼接字符串,其实只是Java提供的一个语法糖。 其实String的 底层是new 了一个StringBuilde…...
vue基础知识点
一、Vue 1. 简介 Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的 JavaScript 框架 它基于标准 HTML、CSS 和 JavaScript 构建,并提供了一套声明式的、组件化的编程模型 由个人维护:尤雨溪,华人 官网 Vue.js - 渐进…...
正则表达式三
运算符的优先级 相同优先级的从左到右计算,不同优先级,优先级高得先运算。从高到低为: 转义字符: 圆括号或方括号:(),[] 限定符:指限定前面元素的次数如:*,,?,{n},{n,},{n,m} 字符…...
MYSQL数据库细节详细分析
MYSQL数据库的数据类型(一般只需要用到这些) 整型类型:用于存储整数值,可以选择不同的大小范围来适应特定的整数值。 TINYINTSMALLINTMEDIUMINTINTBIGINT 浮点型类型:用于存储带有小数部分的数值,提供了单精度(FLOA…...
vue 将图片url转base64
<img :src"imgList[0]" width"600" error"handleImageError" alt"0" load"onloadImg" />//当图片加载完成时,将图片url转成base64onloadImg(event) {this.urlTobase64(event.target.src, event.target.alt…...
Unity之XR Interaction Toolkit如何使用XRSocketInteractable组件
前言 在虚拟现实(VR)和增强现实(AR)开发中,交互性是提升用户体验的关键。Unity作为一个领先的游戏开发引擎,提供了多种工具支持VR/AR开发。Unity的OpenXR插件扩展了这一功能,提供了更强大和灵活的交互系统。其中一个非常有用的组件是XRSocketInteractable。本文将详细介…...
flutter3-os:基于flutter3.x+dart3+getx手机版os管理系统
flutter3-os-admin跨平台手机后台OS系统。 原创Flutter3.22Dart3.4Getxfl_chart等技术开发仿ios手机桌面OA管理系统。自研栅格化布局引擎、自定义桌面壁纸、小部件、底部Dock菜单、可拖拽悬浮球等功能。 全新自研栅格化OS菜单布局引擎。 使用技术 编辑器:VScode技术…...
C++ 用数组模拟队列
在C中,使用数组模拟队列通常涉及到两个主要的操作:入队(enqueue)和出队(dequeue)。由于数组是一个固定大小的数据结构,当使用数组模拟队列时,需要手动管理队列的头部和尾部位置。以下…...
每日一题34:数据分组之查找每个员工花费的总时间
一、每日一题 表: Employees ------------------- | Column Name | Type | ------------------- | emp_id | int | | event_day | date | | in_time | int | | out_time | int | ------------------- 在 SQL 中,(emp_id, event_day, in_time) 是…...
语言模型解构——Tokenizer
1. 认识Tokenizer 1.1 为什么要有tokenizer? 计算机是无法理解人类语言的,它只会进行0和1的二进制计算。但是呢,大语言模型就是通过二进制计算,让你感觉计算机理解了人类语言。 举个例子:单1,双2&#x…...
前端经验:导出表格为excel并设置样式
应用场景 将网页上的table标签内容导出为excel,并且导出的excel携带样式,比如字色、背景色、对齐等等 实施步骤 必备引入包 npm install xlsx-js-style步骤1:准备好table table可以是已经存在与页面中的,也可以动态创建。 行…...
stm32G473的flash模式是单bank还是双bank?
今天突然有人stm32G473的flash模式是单bank还是双bank?由于时间太久,我真忘记了。搜搜发现,还真有人和我一样。见下面的链接:https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...
智慧医疗能源事业线深度画像分析(上)
引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...
工业安全零事故的智能守护者:一体化AI智能安防平台
前言: 通过AI视觉技术,为船厂提供全面的安全监控解决方案,涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面,能够实现对应负责人反馈机制,并最终实现数据的统计报表。提升船厂…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
【JavaSE】绘图与事件入门学习笔记
-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角,以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向,距离坐标原点x个像素;第二个是y坐标,表示当前位置为垂直方向,距离坐标原点y个像素。 坐标体系-像素 …...
分布式增量爬虫实现方案
之前我们在讨论的是分布式爬虫如何实现增量爬取。增量爬虫的目标是只爬取新产生或发生变化的页面,避免重复抓取,以节省资源和时间。 在分布式环境下,增量爬虫的实现需要考虑多个爬虫节点之间的协调和去重。 另一种思路:将增量判…...
C++.OpenGL (20/64)混合(Blending)
混合(Blending) 透明效果核心原理 #mermaid-svg-SWG0UzVfJms7Sm3e {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-icon{fill:#552222;}#mermaid-svg-SWG0UzVfJms7Sm3e .error-text{fill…...
Scrapy-Redis分布式爬虫架构的可扩展性与容错性增强:基于微服务与容器化的解决方案
在大数据时代,海量数据的采集与处理成为企业和研究机构获取信息的关键环节。Scrapy-Redis作为一种经典的分布式爬虫架构,在处理大规模数据抓取任务时展现出强大的能力。然而,随着业务规模的不断扩大和数据抓取需求的日益复杂,传统…...
掌握 HTTP 请求:理解 cURL GET 语法
cURL 是一个强大的命令行工具,用于发送 HTTP 请求和与 Web 服务器交互。在 Web 开发和测试中,cURL 经常用于发送 GET 请求来获取服务器资源。本文将详细介绍 cURL GET 请求的语法和使用方法。 一、cURL 基本概念 cURL 是 "Client URL" 的缩写…...
