HAL库写驱动3个ads1115,并对所得的电压值进行滤波。通过串口发送。STM32F030R8T6

时间: 2024-03-09 19:49:20 浏览: 160
好的,下面是一个示例代码,可以用HAL库驱动三个ADS1115,并对所得的电压值进行滤波,最后通过串口发送。 ```c #include "stm32f0xx_hal.h" #include "stdio.h" #define ADS1115_ADDRESS 0x90 // ADS1115器件地址,A0,A1,A2接地 // ADS1115内部寄存器地址 #define ADS1115_REG_POINTER_CONVERT 0x00 // 转换寄存器 #define ADS1115_REG_POINTER_CONFIG 0x01 // 配置寄存器 // ADS1115配置寄存器参数 #define ADS1115_CONFIG_OS_SINGLE 0x8000 // 单次转换模式 #define ADS1115_CONFIG_MUX_DIFF_0_1 0x0000 // 差分输入0-1 #define ADS1115_CONFIG_MUX_DIFF_0_3 0x1000 // 差分输入0-3 #define ADS1115_CONFIG_MUX_DIFF_1_3 0x2000 // 差分输入1-3 #define ADS1115_CONFIG_MUX_DIFF_2_3 0x3000 // 差分输入2-3 #define ADS1115_CONFIG_PGA_6_144V 0x0000 // PGA增益为6.144V #define ADS1115_CONFIG_MODE_SINGLE 0x0100 // 单次转换模式 #define ADS1115_CONFIG_DR_860SPS 0x0080 // 数据输出速率为860SPS #define ADS1115_CONFIG_CMODE_TRAD 0x0000 // 传统比较器模式 #define ADS1115_CONFIG_CPOL_ACTVLOW 0x0000 // 比较器输出极性为低 #define ADS1115_CONFIG_CLAT_NONLAT 0x0000 // 非滞后模式 #define ADS1115_CONFIG_CQUE_1CONV 0x0000 // 至少一次转换后触发比较器 // 滤波参数 #define FILTER_SIZE 5 // 滤波器容量 float filter_buffer[FILTER_SIZE][3]; // 滤波器缓存 int filter_index = 0; // 滤波器索引 ADC_HandleTypeDef hadc; UART_HandleTypeDef huart; void SystemClock_Config(void); void MX_GPIO_Init(void); void MX_USART1_UART_Init(void); void MX_ADC_Init(void); void ADS1115_WriteRegister(uint8_t i2c_addr, uint8_t reg_addr, uint16_t reg_value) { uint8_t tx_buf[3]; tx_buf[0] = reg_addr; tx_buf[1] = reg_value >> 8; tx_buf[2] = reg_value & 0xFF; HAL_I2C_Master_Transmit(&hi2c1, i2c_addr, tx_buf, 3, 1000); } uint16_t ADS1115_ReadRegister(uint8_t i2c_addr, uint8_t reg_addr) { uint8_t tx_buf[1]; uint8_t rx_buf[2]; tx_buf[0] = reg_addr; HAL_I2C_Master_Transmit(&hi2c1, i2c_addr, tx_buf, 1, 1000); HAL_I2C_Master_Receive(&hi2c1, i2c_addr, rx_buf, 2, 1000); return (rx_buf[0] << 8) | rx_buf[1]; } float ADS1115_ReadVoltage(uint8_t i2c_addr, uint8_t mux_diff, uint8_t pga) { uint16_t config = ADS1115_CONFIG_OS_SINGLE | mux_diff | pga | ADS1115_CONFIG_MODE_SINGLE | ADS1115_CONFIG_DR_860SPS | ADS1115_CONFIG_CMODE_TRAD | ADS1115_CONFIG_CPOL_ACTVLOW | ADS1115_CONFIG_CLAT_NONLAT | ADS1115_CONFIG_CQUE_1CONV; ADS1115_WriteRegister(i2c_addr, ADS1115_REG_POINTER_CONFIG, config); HAL_Delay(1); uint16_t adc_value = ADS1115_ReadRegister(i2c_addr, ADS1115_REG_POINTER_CONVERT); float voltage = 0; switch (pga) { case ADS1115_CONFIG_PGA_6_144V: voltage = (float)adc_value * 6.144 / 32768; break; case ADS1115_CONFIG_PGA_4_096V: voltage = (float)adc_value * 4.096 / 32768; break; case ADS1115_CONFIG_PGA_2_048V: voltage = (float)adc_value * 2.048 / 32768; break; case ADS1115_CONFIG_PGA_1_024V: voltage = (float)adc_value * 1.024 / 32768; break; case ADS1115_CONFIG_PGA_0_512V: voltage = (float)adc_value * 0.512 / 32768; break; case ADS1115_CONFIG_PGA_0_256V: voltage = (float)adc_value * 0.256 / 32768; break; default: break; } return voltage; } float Filter(float value, int channel) { // 添加新数据到滤波器缓存 filter_buffer[filter_index][channel] = value; // 计算滤波结果 float result = 0; for (int i = 0; i < FILTER_SIZE; i++) { result += filter_buffer[i][channel]; } result /= FILTER_SIZE; // 更新滤波器索引 filter_index = (filter_index + 1) % FILTER_SIZE; return result; } void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) { // 读取电压值 float voltage1 = ADS1115_ReadVoltage(ADS1115_ADDRESS, ADS1115_CONFIG_MUX_DIFF_0_1, ADS1115_CONFIG_PGA_6_144V); float voltage2 = ADS1115_ReadVoltage(ADS1115_ADDRESS, ADS1115_CONFIG_MUX_DIFF_0_3, ADS1115_CONFIG_PGA_6_144V); float voltage3 = ADS1115_ReadVoltage(ADS1115_ADDRESS, ADS1115_CONFIG_MUX_DIFF_1_3, ADS1115_CONFIG_PGA_6_144V); // 进行滤波 float filtered_voltage1 = Filter(voltage1, 0); float filtered_voltage2 = Filter(voltage2, 1); float filtered_voltage3 = Filter(voltage3, 2); // 发送电压值 char buf[64]; sprintf(buf, "V1: %.2f, V2: %.2f, V3: %.2f\r\n", filtered_voltage1, filtered_voltage2, filtered_voltage3); HAL_UART_Transmit(&huart, (uint8_t *)buf, strlen(buf), 1000); } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); MX_ADC_Init(); HAL_ADC_Start_IT(&hadc); while (1) { } } void SystemClock_Config(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; /** Initializes the RCC Oscillators according to the specified parameters * in the RCC_OscInitTypeDef structure. */ RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) { Error_Handler(); } /** Initializes the CPU, AHB and APB buses clocks */ RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0) != HAL_OK) { Error_Handler(); } } void MX_ADC_Init(void) { ADC_ChannelConfTypeDef sConfig = {0}; /** Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion) */ hadc.Instance = ADC1; hadc.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4; hadc.Init.Resolution = ADC_RESOLUTION_12B; hadc.Init.DataAlign = ADC_DATAALIGN_RIGHT; hadc.Init.ScanConvMode = DISABLE; hadc.Init.EOCSelection = ADC_EOC_SINGLE_CONV; hadc.Init.LowPowerAutoWait = DISABLE; hadc.Init.ContinuousConvMode = DISABLE; hadc.Init.NbrOfConversion = 1; hadc.Init.DiscontinuousConvMode = DISABLE; hadc.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; hadc.Init.ExternalTrigConv = ADC_SOFTWARE_START; hadc.Init.DMAContinuousRequests = DISABLE; hadc.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN; if (HAL_ADC_Init(&hadc) != HAL_OK) { Error_Handler(); } /** Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time. */ sConfig.Channel = ADC_CHANNEL_0; sConfig.Rank = ADC_RANK_CHANNEL_NUMBER; sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5; if (HAL_ADC_ConfigChannel(&hadc, &sConfig) != HAL_OK) { Error_Handler(); } } void MX_USART1_UART_Init(void) { huart.Instance = USART1; huart.Init.BaudRate = 9600; huart.Init.WordLength = UART_WORDLENGTH_8B; huart.Init.StopBits = UART_STOPBITS_1; huart.Init.Parity = UART_PARITY_NONE; huart.Init.Mode = UART_MODE_TX_RX; huart.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart) != HAL_OK) { Error_Handler(); } } void MX_GPIO_Init(void) { __HAL_RCC_GPIOA_CLK_ENABLE(); __HAL_RCC_GPIOB_CLK_ENABLE(); } void Error_Handler(void) { } #ifdef USE_FULL_ASSERT void assert_failed(uint8_t *file, uint32_t line) { } #endif /* USE_FULL_ASSERT */ ``` 在代码中,我们使用了HAL库的I2C、UART和ADC库函数。我们首先定义了ADS1115器件地址和内部寄存器地址,并使用ADS1115_WriteRegister和ADS1115_ReadRegister函数操作ADS1115器件。我们还定义了滤波器缓存和滤波器索引,使用Filter函数进行滤波。在ADC转换完成后,我们读取三个差分输入的电压值,并进行滤波和串口发送。最后,在主函数中循环调用ADC转换函数,等待中断触发。 如果需要使用其他电压增益或数据输出速率,可以修改ADS1115配置寄存器参数。如果需要使用其他滤波算法,可以替换Filter函数。
阅读全文

相关推荐

大家在看

recommend-type

2_JFM7VX690T型SRAM型现场可编程门阵列技术手册.pdf

复旦微国产大规模FPGA JFM7VX690T datasheet 手册 资料
recommend-type

网络信息系统应急预案-网上银行业务持续性计划与应急预案

包含4份应急预案 网络信息系统应急预案.doc 信息系统应急预案.DOCX 信息系统(系统瘫痪)应急预案.doc 网上银行业务持续性计划与应急预案.doc
recommend-type

RK eMMC Support List

RK eMMC Support List
recommend-type

DAQ97-90002.pdf

SCPI指令集 详细介绍(安捷伦)
recommend-type

毕业设计&课设-MATLAB的光场工具箱.zip

matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答! matlab算法,工具源码,适合毕业设计、课程设计作业,所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随

最新推荐

recommend-type

CUBEMX-STM32F030学习笔记

STM32F030F4P6是一款32位微控制器,基于ARM Cortex-M0内核,具有16KB FLASH存储器、4KB RAM、1个USART串口、TSSOP20脚封装,工作电压为2.4-3.6V,具有15个可用IO口。 二、HAL 库和STM32CubeMX HAL库是 STM32 微...
recommend-type

[野火EmbedFire]《STM32 HAL库开发实战指南——F103系列》—20211026.pdf

这本书由野火电子在2021年10月26日发布,旨在帮助开发者深入理解和应用STM32的HAL(Hardware Abstraction Layer)库,该库为STM32的硬件操作提供了一种标准化、高抽象级别的接口,使得开发者能够更高效地进行软件...
recommend-type

STM32不完全手册_HAL库版本_V1.0.pdf

《STM32不完全手册_HAL库版本_V1.0》是一本专为STM32初学者和开发者编写的详实教程,旨在引导读者逐步掌握STM32微控制器的使用。手册分为三个部分,涵盖硬件、软件和实战应用,旨在提供一个全面的学习路径。 **硬件...
recommend-type

STM32F407 RTC 配置理解与总结

本文将对STM32F407的RTC配置进行详细的理解和总结,从基本概念到实际应用,帮助读者深入了解STM32F407的RTC配置。 RTC 概念 RTC(Real-Time Clock)是单片机中的一种时钟模块,负责记录和维护时间信息。STM32F...
recommend-type

【电磁】基于matlab GUI FDTD时域有限差分的变电站暂态电磁计算【含Matlab源码 11057期】.zip

Matlab领域上传的视频是由对应的完整代码运行得来的,完整代码皆可运行,亲测可用,适合小白; 1、从视频里可见完整代码的内容 主函数:main.m; 调用函数:其他m文件;无需运行 运行结果效果图; 2、代码运行版本 Matlab 2019b;若运行有误,根据提示修改;若不会,私信博主; 3、运行操作步骤 步骤一:将所有文件放到Matlab的当前文件夹中; 步骤二:双击打开main.m文件; 步骤三:点击运行,等程序运行完得到结果; 4、仿真咨询 如需其他服务,可私信博主; 4.1 博客或资源的完整代码提供 4.2 期刊或参考文献复现 4.3 Matlab程序定制 4.4 科研合作
recommend-type

免费下载可爱照片相框模板

标题和描述中提到的“可爱照片相框模板下载”涉及的知识点主要是关于图像处理和模板下载方面的信息。以下是对这个主题的详细解读: 一、图像处理 图像处理是指对图像进行一系列操作,以改善图像的视觉效果,或从中提取信息。常见的图像处理包括图像编辑、图像增强、图像恢复、图像分割等。在本场景中,我们关注的是如何使用“可爱照片相框模板”来增强照片效果。 1. 相框模板的概念 相框模板是一种预先设计好的框架样式,可以添加到个人照片的周围,以达到美化照片的目的。可爱风格的相框模板通常包含卡通元素、花边、色彩鲜明的图案等,适合用于家庭照片、儿童照片或是纪念日照片的装饰。 2. 相框模板的使用方式 用户可以通过下载可爱照片相框模板,并使用图像编辑软件(如Adobe Photoshop、GIMP、美图秀秀等)将个人照片放入模板中的指定位置。一些模板可能设计为智能对象或图层蒙版,以简化用户操作。 3. 相框模板的格式 可爱照片相框模板的常见格式包括PSD、PNG、JPG等。PSD格式通常为Adobe Photoshop专用格式,允许用户编辑图层和效果;PNG格式支持透明背景,便于将相框与不同背景的照片相结合;JPG格式是通用的图像格式,易于在网络上传输和查看。 二、模板下载 模板下载是指用户从互联网上获取设计好的图像模板文件的过程。下载可爱照片相框模板的步骤通常包括以下几个方面: 1. 确定需求 首先,用户需要根据自己的需求确定模板的风格、尺寸等要素。例如,选择“可爱”风格,确认适用的尺寸等。 2. 搜索资源 用户可以在专门的模板网站、设计师社区或是图片素材库中搜索适合的可爱照片相框模板。这些网站可能提供免费下载或是付费购买服务。 3. 下载文件 根据提供的信息,用户可以通过链接、FTP或其他下载工具进行模板文件的下载。在本例中,文件名称列表中的易采源码下载说明.txt和下载说明.htm文件可能包含有关下载可爱照片相框模板的具体说明。用户需仔细阅读这些文档以确保下载正确的文件。 4. 文件格式和兼容性 在下载时,用户应检查文件格式是否与自己的图像处理软件兼容。一些模板可能只适用于特定软件,例如PSD格式主要适用于Adobe Photoshop。 5. 安全性考虑 由于网络下载存在潜在风险,如病毒、恶意软件等,用户下载模板文件时应选择信誉良好的站点,并采取一定的安全防护措施,如使用防病毒软件扫描下载的文件。 三、总结 在了解了“可爱照片相框模板下载”的相关知识后,用户可以根据个人需要和喜好,下载适合的模板文件,并结合图像编辑软件,将自己的照片设计得更加吸引人。同时,注意在下载和使用过程中保护自己的计算机安全,避免不必要的麻烦。
recommend-type

【IE11停用倒计时】:无缝迁移到EDGE浏览器的终极指南(10大实用技巧)

# 摘要 随着互联网技术的迅速发展,旧有的IE11浏览器已不再适应现代网络环境的需求,而Microsoft EDGE浏览器的崛起标志着新一代网络浏览技术的到来。本文首先探讨了IE11停用的背景,分析了EDGE浏览器如何继承并超越了IE的特性,尤其是在用户体验、技术架构革新方面。接着,本文详细阐述了迁移前的准备工作,包括应用兼容性评估、用户培训策略以及环境配置和工具的选择。在迁移过程中,重点介
recommend-type

STC8H8K64U 精振12MHZ T0工作方式1 50ms中断 输出一秒方波

STC8H8K64U是一款单片机,12MHz的晶振频率下,T0定时器可以通过配置工作方式1来实现50ms的中断,并在每次中断时切换输出引脚的状态,从而输出一秒方波。 以下是具体的实现步骤: 1. **配置定时器T0**: - 设置T0为工作方式1(16位定时器)。 - 计算定时器初值,使其在50ms时溢出。 - 使能T0中断。 - 启动T0。 2. **编写中断服务程序**: - 在中断服务程序中,重新加载定时器初值。 - 切换输出引脚的状态。 3. **配置输出引脚**: - 设置一个输出引脚为推挽输出模式。 以下是示例代码: ```c
recommend-type

易语言中线程启动并传递数组的方法

根据提供的文件信息,我们可以推断出以下知识点: ### 标题解读 标题“线程_启动_传数组-易语言”涉及到了几个重要的编程概念,分别是“线程”、“启动”和“数组”,以及特定的编程语言——“易语言”。 #### 线程 线程是操作系统能够进行运算调度的最小单位,它被包含在进程之中,是进程中的实际运作单位。在多线程环境中,一个进程可以包含多个并发执行的线程,它们可以处理程序的不同部分,从而提升程序的效率和响应速度。易语言支持多线程编程,允许开发者创建多个线程以实现多任务处理。 #### 启动 启动通常指的是开始执行一个线程的过程。在编程中,启动一个线程通常需要创建一个线程实例,并为其指定一个入口函数或代码块,线程随后开始执行该函数或代码块中的指令。 #### 数组 数组是一种数据结构,它用于存储一系列相同类型的数据项,可以通过索引来访问每一个数据项。在编程中,数组可以用来存储和传递一组数据给函数或线程。 #### 易语言 易语言是一种中文编程语言,主要用于简化Windows应用程序的开发。它支持面向对象、事件驱动和模块化的编程方式,提供丰富的函数库,适合于初学者快速上手。易语言具有独特的中文语法,可以使用中文作为关键字进行编程,因此降低了编程的门槛,使得中文使用者能够更容易地进行软件开发。 ### 描述解读 描述中的“线程_启动_传数组-易语言”是对标题的进一步强调,表明该文件或模块涉及的是如何在易语言中启动线程并将数组作为参数传递给线程的过程。 ### 标签解读 标签“模块控件源码”表明该文件是一个模块化的代码组件,可能包含源代码,并且是为了实现某些特定的控件功能。 ### 文件名称列表解读 文件名称“线程_启动多参_文本型数组_Ex.e”给出了一个具体的例子,即如何在一个易语言的模块中实现启动线程并将文本型数组作为多参数传递的功能。 ### 综合知识点 在易语言中,创建和启动线程通常需要以下步骤: 1. 定义一个子程序或函数,该函数将成为线程的入口点。这个函数或子程序应该能够接收参数,以便能够处理传入的数据。 2. 使用易语言提供的线程创建函数(例如“创建线程”命令),指定上一步定义的函数或子程序作为线程的起始点,并传递初始参数。 3. 将需要传递给线程的数据组织成数组的形式。数组可以是文本型、数值型等,取决于线程需要处理的数据类型。 4. 启动线程。调用创建线程的命令,并将数组作为参数传递给线程的入口函数。 在易语言中,数组可以按照以下方式创建和使用: - 定义数组类型和大小,例如`数组 变量名(大小)` - 赋值操作,可以使用`数组赋值`命令为数组中的每个元素赋予具体的值。 - 作为参数传递给子程序或函数,可以使用`参数`命令将数组作为参数传递。 在多线程编程时,需要注意线程安全问题,例如避免多个线程同时操作同一个资源导致的数据竞争或死锁。易语言虽然简化了线程的创建和管理,但在进行多线程开发时,依然需要开发者具有一定的线程安全意识。 文件“线程_启动多参_文本型数组_Ex.e”可能包含了一个具体示例,展示了如何使用易语言创建一个线程,并将一个文本型数组作为参数传递给它。这个模块可能是易语言开发者学习和参考的一个实用例子,能够帮助理解易语言在处理线程和数组时的具体用法和技巧。
recommend-type

【PCB设计速成】:零基础到专家的电路板设计全面攻略

# 摘要 本文为从事PCB设计与制造领域的技术人员提供了一个全面的指导。第一章介绍PCB设计的基础知识,为后续章节的学习打下理论基础。第二章详细讲解了PCB设计软件工具的使用,包括软件的选择、安装配置、布局布线技巧以及设计验证的方法。第三章深入探讨了PCB制造过程,涵盖从工艺流程到打样、测试、装配和焊接的具体操作。第四章讲述了高级PCB设计技术,包括HDI技术、多层板设计以及热管理策略。第