【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可以是已经存在与页面中的,也可以动态创建。 行…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
leetcodeSQL解题:3564. 季节性销售分析
leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...
[Java恶补day16] 238.除自身以外数组的乘积
给你一个整数数组 nums,返回 数组 answer ,其中 answer[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积 。 题目数据 保证 数组 nums之中任意元素的全部前缀元素和后缀的乘积都在 32 位 整数范围内。 请 不要使用除法,且在 O(n) 时间复杂度…...
