614|2

44

帖子

1

TA的资源

一粒金砂(中级)

楼主
 

《STM32H7S78-DK 开发套件二周目评测:简单声音采集之频率检测与显示》 [复制链接]

在实现adc基础上,实现对音频信号频率的检测。读取模拟信号并通过 FFT(快速傅里叶变换)分析频率成分。同时,在串口输出检测到的频率,并通过 LED 显示结果。

一、硬件连接

  1. 引脚连接
    • 将 MAX4466 传感器的输出引脚连接到 STM32 的 ADC 输入引脚(PC0,即 ADC1_IN10)。
    • LED选取PO5。在高电平时候点亮。

       

二、使用 CubeMX 进行配置

在 CubeMX 中进行如下设置:

2.1 ADC 模块配置

  • 时钟设置:配置 ADC 时钟为 84MHz,选择 ADC 的时钟分频器为 1,以达到较高的采样精度。
  • 采样时间:设置 ADC 的采样时间为 15.5 个 ADC 时钟周期,以提高采样精度。
  • 通道设置:将 ADC 通道设置为 ADC1_IN10(PC0),确保能够读取传感器输出。

2.2 TIM 模块配置

  • 定时器配置:配置 TIM2 为定时器,用于生成定时中断。
    • 设置预分频器为 7999,自动重装载值为 999,以设定频率采样率(例如 1kHz)。

2.3 GPIO 设置

将 PO5 配置为推挽输出模式,用于控制 LED。

生成代码并导入 Keil,在 CubeMX 中生成代码,并导入 Keil 进行后续的代码开发。

四、代码实现

4.1 初始化模块

在 Keil 中,初始化 ADC、定时器和 LED 控制的代码如下:
#include "arm_math.h"
#include "stm32h7xx_hal.h"
#define FFT_SIZE 1024 // FFT 输入数组的大小
float32_t input[FFT_SIZE];
float32_t output[FFT_SIZE];
arm_cfft_instance_f32 fft_instance;
TIM_HandleTypeDef htim2;
ADC_HandleTypeDef hadc1;
void ADC_Init(void) {
  ADC_ChannelConfTypeDef sConfig = {0};
  __HAL_RCC_ADC12_CLK_ENABLE(); // 使能 ADC 时钟
  hadc1.Instance = ADC1;
  hadc1.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV2;
  hadc1.Init.Resolution = ADC_RESOLUTION_12B;
  hadc1.Init.ScanConvMode = DISABLE;
  hadc1.Init.ContinuousConvMode = ENABLE;
  hadc1.Init.DiscontinuousConvMode = DISABLE;
  hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  HAL_ADC_Init(&hadc1);
  sConfig.Channel = ADC_CHANNEL_10; // 选择通道 10
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_15CYCLES; // 设置采样时间
  HAL_ADC_ConfigChannel(&hadc1, &sConfig);
}
uint32_t Read_ADC_Value(void) {
  uint32_t adc_value = 0;
  HAL_ADC_Start(&hadc1);                            // 启动 ADC
  HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); // 等待转换完成
  adc_value = HAL_ADC_GetValue(&hadc1);             // 获取 ADC 值
  HAL_ADC_Stop(&hadc1);                             // 停止 ADC
  return adc_value;
}
void TIM_Init(void) {
  __HAL_RCC_TIM2_CLK_ENABLE(); // 使能 TIM2 时钟
  htim2.Instance = TIM2;
  htim2.Init.Prescaler = 7999;                 // 对应 1kHz
  htim2.Init.Period = 999;                     // 对应 1ms
  htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // 向上计数
  HAL_TIM_Base_Init(&htim2);                   // 初始化定时器
  HAL_TIM_Base_Start_IT(&htim2);               // 启动定时器中断
}
void FFT_Init(void) {
  arm_cfft_init_f32(&fft_instance, FFT_SIZE); // 初始化 FFT 实例
}

 

4.2 FFT 处理

使用 CMSIS DSP 库实现 FFT 分析信号频率:
void Perform_FFT(void) {
 arm_cfft_f32(&fft_instance, input, 0, 1); // 执行 FFT
 arm_cmplx_mag_f32(input, output, FFT_SIZE); // 计算幅度
}

 

4.3 频率检测与 LED 显示

计算频率并控制 LED 的开关状态的代码如下:
void Display_Frequency(void) {
 float max_value = output[0];
 uint32_t max_index = 0;
 for (uint32_t i = 1; i < FFT_SIZE / 2; i++) {
 if (output[i] > max_value) {
 max_value = output[i];
 max_index = i;
 }
}

 

// 控制 LED 的开关状态
if (max_index > 10) { 
 HAL_GPIO_WritePin(GPIOO, GPIO_PIN_5, GPIO_PIN_SET); // 点亮 LED
 } else {
 HAL_GPIO_WritePin(GPIOO, GPIO_PIN_5, GPIO_PIN_RESET); // 熄灭 LED
 }
}

 

4.4 主程序

在主循环中进行 ADC 采集、FFT 处理和 LED 控制的代码如下:
int main(void) {
 HAL_Init(); 
 SystemClock_Config();
 ADC_Init(); 
 TIM_Init(); 
 FFT_Init(); 
 while (1) {
UART_Send_Data(corrected_value);
 }
}
// 定时器溢出回调
void HAL_TIM_PERIOD_ELAPSED_CALLBACK(TIM_HandleTypeDef *htim) {
 if (htim->Instance == TIM2) {
// 每次定时器溢出时读取 ADC 值
 uint32_t adc_value = Read_ADC_Value(); // 获取 ADC 值

 static uint32_t sample_index = 0; 
 input[sample_index] = (float32_t)adc_value; // 存储到 FFT 输入数组
 sample_index++;
// 如果达到 FFT_SIZE 大小,则进行 FFT 计算
 if (sample_index >= FFT_SIZE) {
  sample_index = 0; // 重置索引

  Perform_FFT();
  Display_Frequency();
  }
 }
}
此帖出自stm32/stm8论坛

最新回复

这个对检测的音频信号有没有要求呢,比如最低的频率大小     详情 回复 发表于 2024-10-20 08:50
点赞 关注
 

回复
举报

6587

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

这个对检测的音频信号有没有要求呢,比如最低的频率大小

 

此帖出自stm32/stm8论坛

点评

按照目前的采样率的话,理论上的最低频率大约为1hz,最高大约是500hz的样子  详情 回复 发表于 2024-10-21 13:30
 
 

回复

44

帖子

1

TA的资源

一粒金砂(中级)

板凳
 
Jacktang 发表于 2024-10-20 08:50 这个对检测的音频信号有没有要求呢,比如最低的频率大小  

按照目前的采样率的话,理论上的最低频率大约为1hz,最高大约是500hz的样子

此帖出自stm32/stm8论坛
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表