STM32项目实战:ADC采集

news2025/5/24 2:45:14

        STM32F103C8T6的ADC配置。PB0对应的是ADC1的通道8。在标准库中,需要初始化ADC,设置通道,时钟,转换模式等。需要配置GPIOB的第0脚为模拟输入模式,然后配置ADC1的通道8,设置转换周期和触发方式。

        接下来是I2C屏幕的驱动,通常使用SSD1306 OLED屏,I2C地址一般为0x7a或0X7b。需要编写I2C的初始化函数,包括GPIO配置(PB8和PB9作为SCL和SDA),设置I2C的时钟和模式,以及实现数据的发送函数。同时,需要整合SSD1306的驱动代码,包括初始化命令、清屏、写字符串等函数(这里我们为了省事,直接使用江协科技)。

        用户提到使用标准库,所以需要避免使用HAL的函数,转而使用如stm32f10x_gpio.h、stm32f10x_adc.h、stm32f10x_i2c.h等头文件中的函数。比如,ADC的初始化需要配置ADC_InitTypeDef结构体,启动校准,然后进行转换。I2C部分需要手动处理起始、地址发送、数据发送和停止条件。

        另外,ADC的转换结果需要通过计算得到电压值,这里使用3.3V参考电压,12位分辨率,所以电压=adc_value * 3.3 / 4095。显示部分需要将数值转换为字符串,并格式化输出到OLED上。

        需要注意的问题包括:I2C的时序是否正确,是否添加了上拉电阻;ADC的采样时间是否足够,是否需要多次采样取平均以减少噪声;标准库中的函数调用是否正确,例如I2C的等待标志位是否处理妥当,避免死循环。

        最后,代码结构应包括初始化函数(GPIO、ADC、I2C)、OLED驱动函数、主循环中的ADC读取和显示更新。可能还需要实现简单的延时函数,因为标准库中没有HAL_Delay,可以使用SysTick或简单的循环延时。

#include "stm32f10x.h"                  // Device header
#include "Delay.h"
#include "OLED.h"
#include "stdlib.h"


int adc_value;
float voltage;
u8 buff[30];
/**
  * 坐标轴定义:
  * 左上角为(0, 0)点
  * 横向向右为X轴,取值范围:0~127
  * 纵向向下为Y轴,取值范围:0~63
  * 
  *       0             X轴           127 
  *      .------------------------------->
  *    0 |
  *      |
  *      |
  *      |
  *  Y轴 |
  *      |
  *      |
  *      |
  *   63 |
  *      v
  * 
  */

// 初始化水泵ADC
void ADC_Init_Config(void)
{
    ADC_InitTypeDef ADC;
    GPIO_InitTypeDef GPIO;

    // 使能ADC1和GPIOB时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1 | RCC_APB2Periph_GPIOB, ENABLE);

    // 配置PB0为模拟输入模式
    GPIO.GPIO_Pin = GPIO_Pin_0;
    GPIO.GPIO_Mode = GPIO_Mode_AIN;
    GPIO_Init(GPIOB, &GPIO);

    // 配置ADC1
    ADC.ADC_Mode = ADC_Mode_Independent;
    ADC.ADC_ScanConvMode = DISABLE;
    ADC.ADC_ContinuousConvMode = DISABLE;
    ADC.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;
    ADC.ADC_DataAlign = ADC_DataAlign_Right;
    ADC.ADC_NbrOfChannel = 1;
    ADC_Init(ADC1, &ADC);

    // 配置ADC1的通道8(PB0),采样时间为1.5周期
    ADC_RegularChannelConfig(ADC1, ADC_Channel_8, 1, ADC_SampleTime_1Cycles5);

    // 使能ADC1
    ADC_Cmd(ADC1, ENABLE);

    // 初始化ADC校准值
    ADC_ResetCalibration(ADC1);
    while (ADC_GetResetCalibrationStatus(ADC1));
    ADC_StartCalibration(ADC1);
    while (ADC_GetCalibrationStatus(ADC1));
}

int main(void)
{
	ADC_Init_Config();
	
	/*OLED初始化*/
	OLED_Init();
	
	/*在(0, 0)位置显示字符'A',字体大小为8*16点阵*/
	OLED_ShowChar(0, 0, 'A', OLED_8X16);
	
	/*在(16, 0)位置显示字符串"Hello World!",字体大小为8*16点阵*/
	OLED_ShowString(16, 0, "Hello World!", OLED_8X16);
	
	/*在(0, 18)位置显示字符'A',字体大小为6*8点阵*/
	OLED_ShowChar(0, 18, 'A', OLED_6X8);
	
	/*在(16, 18)位置显示字符串"Hello World!",字体大小为6*8点阵*/
	OLED_ShowString(16, 18, "Hello World!", OLED_6X8);
	
	/*在(0, 28)位置显示数字12345,长度为5,字体大小为6*8点阵*/
	OLED_ShowNum(0, 28, 12345, 5, OLED_6X8);
	
	/*在(40, 28)位置显示有符号数字-66,长度为2,字体大小为6*8点阵*/
	OLED_ShowSignedNum(40, 28, -66, 2, OLED_6X8);
	
	/*在(70, 28)位置显示十六进制数字0xA5A5,长度为4,字体大小为6*8点阵*/
	OLED_ShowHexNum(70, 28, 0xA5A5, 4, OLED_6X8);
	
	/*在(0, 38)位置显示二进制数字0xA5,长度为8,字体大小为6*8点阵*/
	OLED_ShowBinNum(0, 38, 0xA5, 8, OLED_6X8);
	
	/*在(60, 38)位置显示浮点数字123.45,整数部分长度为3,小数部分长度为2,字体大小为6*8点阵*/
	OLED_ShowFloatNum(60, 38, 123.45, 3, 2, OLED_6X8);
	
	/*在(0, 48)位置显示汉字串"你好,世界。",字体大小为固定的16*16点阵*/
	OLED_ShowChinese(0, 48, "你好,世界。");
	
	/*在(96, 48)位置显示图像,宽16像素,高16像素,图像数据为Diode数组*/
	OLED_ShowImage(96, 48, 16, 16, Diode);
	
	/*在(96, 18)位置打印格式化字符串,字体大小为6*8点阵,格式化字符串为"[%02d]"*/
	OLED_Printf(96, 18, OLED_6X8, "[%02d]", 6);
	
	/*调用OLED_Update函数,将OLED显存数组的内容更新到OLED硬件进行显示*/
	OLED_Update();
	
	/*延时3000ms,观察现象*/
	Delay_ms(3000);
	
	/*清空OLED显存数组*/
	OLED_Clear();

	
	while (1)
	{

		        // 启动ADC转换
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);

        // 等待转换完成
        while (!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));

        // 获取ADC转换结果
        adc_value = ADC_GetConversionValue(ADC1);

        // 计算电压值
        // STM32F103C8T6的ADC分辨率是12位,参考电压为3.3V
        voltage = (adc_value * 3.3) / 4096;
				sprintf((char*)buff,"%fV  ",voltage);
				OLED_ShowString(16, 18, buff, OLED_6X8);
				OLED_Update();

				
	}
}

优化建议:

        1.添加ADC软件平均滤波:

uint16_t ADC_ReadAvg(uint8_t times) {
    uint32_t sum = 0;
    for(uint8_t i=0; i<times; i++) {
        ADC_SoftwareStartConvCmd(ADC1, ENABLE);
        while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
        sum += ADC_GetConversionValue(ADC1);
    }
    return sum/times;
}

        2.显示刷新使用局部刷新代替全屏刷新提升性能

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

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

相关文章

CYT4BB Dual Bank - 安全启动

本节介绍TRAVEO™ T2G微控制器(MCU)的启动顺序。有关TRAVEO™ T2G微控制器的安全特性、不同的生命周期阶段以及“安全启动”序列的详细描述,请参阅 AN228680 -Secure system configuration in TRAVEO™ T2G family.   TRAVEO™ T2G微控制器(MCU)的启动序列(见图3)基于…

科技行业智能化升级经典案例—某芯片公司

案例标题 CSGHub赋能某芯片公司&#xff1a;国产AI芯片全链路管理平台的高效落地与生态共建 执行摘要 某芯片公司在开发内部模型管理平台时&#xff0c;选择AgenticOps体系中的CSGHub作为核心工具&#xff0c;通过其本地化部署能力、中文支持及RESTful API接口&#xff0c;解决…

Python编程从入门到实践 PDF 高清版

各位程序员朋友们&#xff0c;还在为找不到合适的Python学习资料而烦恼吗&#xff1f;还在为晦涩难懂的编程书籍而头疼吗&#xff1f;今天&#xff0c;就给大家带来一份重磅福利——237完整版PDF&#xff0c; 我用网盘分享了「Python编程&#xff1a;从入门到实践__超清版.pdf…

系统性能不达标,如何提升用户体验?

当系统性能不达标时&#xff0c;要想有效提升用户体验&#xff0c;必须从性能优化、前后端协同、用户感知改善、监控预警机制四个关键维度切入。其中&#xff0c;性能优化是最直接有效的策略&#xff0c;它通过代码优化、资源压缩、缓存机制、CDN加速等手段&#xff0c;显著提升…

智能守护校园“舌尖安全“:AI视频分析赋能名厨亮灶新时代

引言&#xff1a; 在校园食品安全备受关注的今天&#xff0c;一套融合视频监控管理平台与AI视频分析盒子的智能解决方案正在全国多地学校食堂悄然落地&#xff0c;为传统的"名厨亮灶"工程注入科技新动能。这套系统不仅实现了后厨操作的"透明化"&#xff0…

初步尝试AI应用开发平台——Dify的本地部署和应用开发

随着大语言模型LLM和相关应用的流行&#xff0c;在本地部署并构建知识库&#xff0c;结合企业的行业经验或个人的知识积累进行定制化开发&#xff0c;是LLM的一个重点发展方向&#xff0c;在此方向上也涌现出了众多软件框架和工具集&#xff0c;Dify就是其中广受关注的一款&…

卷积神经网络中的局部卷积:原理、对比与应用解析

【内容摘要】 本文聚焦卷积神经网络中的局部卷积&#xff0c;重点解析全连接、局部连接、全卷积与局部卷积四种连接方式的差异&#xff0c;结合人脸识别任务案例&#xff0c;阐述局部卷积的应用场景及优势&#xff0c;为理解卷积网络连接机制提供技术参考。 关键词&#xff1a…

重拾童年,用 CodeBuddy 做自己的快乐创作者

某个炎炎的夏日午后&#xff0c;阳光透过稀疏的树叶洒落在地上&#xff0c;一道道光影斑驳陆离。那时候的我们&#xff0c;还只是三五个小朋友&#xff0c;蹲坐在村头的一棵老槐树下&#xff0c;手里握着并不属于自己的游戏掌机&#xff0c;轮流按动着手柄的按键&#xff0c;在…

HarmonyOS实战:自定义时间选择器

前言 最近在日常鸿蒙开发过程中&#xff0c;经常会使用一些时间选择器&#xff0c;鸿蒙官方提供的时间选择器满足不了需求&#xff0c;所以自己动手自定义一些经常会使用到的时间选择器&#xff0c;希望能帮到你&#xff0c;建议点赞收藏&#xff01; 实现效果 需求分析 默认…

6:OpenCV—图像滤波

过滤图像和视频 图像滤波是一种邻域运算&#xff0c;其中输出图像中任何给定像素的值是通过对相应输入像素附近的像素值应用某种算法来确定的。该技术通常用于平滑、锐化和检测图像和视频的边缘。 让我们了解在讨论图像过滤技术、内核和卷积时使用的一些术语的含义。 内核 内…

pytorch语法学习

启动 python main.py --config llve.yml --path_y test -i output

5:OpenCV—图像亮度、对比度变换

1.更改图像和视频的亮度 更改亮度 更改图像的亮度是常用的点操作。在此操作中&#xff0c;图像中每个像素的值应增加/减少一个常数。要更改视频的亮度&#xff0c;应对视频中的每一帧执行相同的操作。 如果要增加图像的亮度&#xff0c;则必须为图像中的每个像素添加一些正常…

Oracle 的V$ACTIVE_SESSION_HISTORY 视图

Oracle 的V$ACTIVE_SESSION_HISTORY 视图 V$ACTIVE_SESSION_HISTORY显示数据库中的 Sampled Session 活动。 它包含每秒拍摄一次的活动数据库会话的快照。如果数据库会话位于 CPU 上或正在等待不属于等待类的事件&#xff0c;则认为该会话处于活动状态。请参阅 view 以了解有…

【Python 算法零基础 4.排序 ② 冒泡排序】

目录 一、引言 二、算法思想 三、时间复杂度和空间复杂度 1.时间复杂度 2.空间复杂度 四、冒泡排序的优缺点 1.算法的优点 2.算法的缺点 五、实战练习 88. 合并两个有序数组 算法与思路 ① 合并数组 ② 冒泡排序 2148. 元素计数 算法与思路 ① 排序 ② 初始化计数器 ③ 遍历数组…

Python:操作Excel设置行高和列宽

Python 操作 Excel:轻松设置行高与列宽 📊✨ 在处理 Excel 表格时,除了正确展示数据本身,合理设置行高与列宽也是提升可读性和专业度的关键因素。本文将带你了解如何使用 Python 的 openpyxl 库,优雅地控制 Excel 表格的排版布局,实现行高、列宽的灵活设置与自动适配! …

docker-volume-backup 备份 ragflow volumes

自定义项目名称 这里我自定义了 ragflow 项目的名称&#xff0c;修改 .env&#xff0c;添加环境配置 # 自定义项目名称 COMPOSE_PROJECT_NAMEragflow创建备份脚本配置文件 在 ragflow/docker 目录下创建文件 docker-compose-backup.yml version: 3services:backup:image: o…

Axure设计数字乡村可视化大屏:从布局到交互的实战经验分享

乡村治理正从传统模式向“数据驱动”转型。数字乡村可视化大屏作为数据展示的核心载体&#xff0c;不仅能直观呈现乡村发展全貌&#xff0c;还能为决策提供科学依据。本文以Axure为工具&#xff0c;结合实际案例&#xff0c;分享如何从零设计一个功能完备、交互流畅的数字乡村大…

算法第26天 | 贪心算法、455.分发饼干、376. 摆动序列、 53. 最大子序和

弹性算法理论基础 想清楚 局部最优 是什么&#xff0c;如果可以推导出全局最优&#xff0c;那就是正确的贪心算法 455. 分发饼干 题目 思路与解法 class Solution:def findContentChildren(self, g: List[int], s: List[int]) -> int:res 0i 0j 0g.sort()s.sort()whi…

PDF处理控件Aspose.PDF教程:以编程方式将 PDF 导出为 JPG

在本节中&#xff0c;我们将探讨如何使用 Aspose.PDF 库将 PDF 文档转换为 JPG 图像。Aspose.PDF 是一个功能强大且用途广泛的库&#xff0c;专为需要以编程方式处理 PDF 文件的开发人员而设计。它提供了丰富的功能&#xff0c;可用于跨多个平台创建、编辑和转换 PDF 文档。其主…

AI大模型应用之评测篇

在看到公司对于AI 工程师 的岗位要求 &#xff1a;“能够熟练使用各种自动化评测工具与方法&#xff0c;对AI 模型的输出进行有效评估” 时&#xff0c;其实比较疑惑&#xff0c;这个是对大模型能力例如像Deepseek ,GPT-4 ,千问&#xff0c;LLAMA这些模型的能力评测&#xff0c…