【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可以是已经存在与页面中的,也可以动态创建。 行…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
服务器硬防的应用场景都有哪些?
服务器硬防是指一种通过硬件设备层面的安全措施来防御服务器系统受到网络攻击的方式,避免服务器受到各种恶意攻击和网络威胁,那么,服务器硬防通常都会应用在哪些场景当中呢? 硬防服务器中一般会配备入侵检测系统和预防系统&#x…...
selenium学习实战【Python爬虫】
selenium学习实战【Python爬虫】 文章目录 selenium学习实战【Python爬虫】一、声明二、学习目标三、安装依赖3.1 安装selenium库3.2 安装浏览器驱动3.2.1 查看Edge版本3.2.2 驱动安装 四、代码讲解4.1 配置浏览器4.2 加载更多4.3 寻找内容4.4 完整代码 五、报告文件爬取5.1 提…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
网站指纹识别
网站指纹识别 网站的最基本组成:服务器(操作系统)、中间件(web容器)、脚本语言、数据厍 为什么要了解这些?举个例子:发现了一个文件读取漏洞,我们需要读/etc/passwd,如…...
android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
