ccccccc@

  • 2025-03-06
  • 发表了主题帖: 【microchip PolarFire SoC FPGA 套件】led呼吸灯实现

    一、测评环境 本次测评选用 PolarFire SoC Discovery Kit(MPFS-DISCO-KIT)开发板,其核心芯片为 MPFS095T-1FCSG325E FPGA。开发板上的 50MHz 振荡器通过 R18 引脚为设计中的 clk 提供时钟信号,而 LED1 连接到 T18 引脚,用于直观呈现呼吸灯效果。此外,开发板丰富的接口资源为后续功能扩展提供了基础条件。 二、测评步骤 (一)创建项目 打开 Libero SoC 软件,选择 “Project> New Project” 选项,开始新建项目。 在弹出的 “Project Details” 页面中,填写项目名称、选择合适的项目保存路径,并指定 “Preferred HDL Type” 为 Verilog。 进入 “Device Selection” 页面,依次选择 “Family” 为 PolarFireSoC,“Die” 为 MPFS095T,“Package” 为 FCSG325,“Speed” 为 - 1,“Range” 为 EXT。 在 “Device Settings” 页面,保持默认的关键设置不变,最后点击 “Finish” 完成项目创建。 (二)添加代码与设计文件 在项目中创建新的 Verilog 文件,命名为 “breathing_led.v”,并将给定的呼吸灯代码粘贴到该文件中保存。代码如下: verilog module breathing_led ( input wire clk, output reg led); parameter COUNT_MAX = 16667;parameter STEP = 100; reg [23:0] counter;reg [23:0] duty_cycle;reg up_down; always @(posedge clk) begin if (counter < COUNT_MAX - 1) begin counter <= counter + 1; end else begin counter <= 0; if (up_down == 0) begin if (duty_cycle < COUNT_MAX - STEP) begin duty_cycle <= duty_cycle + STEP; end else begin duty_cycle <= COUNT_MAX - STEP; up_down <= 1; end end else begin if (duty_cycle > STEP) begin duty_cycle <= duty_cycle - STEP; end else begin duty_cycle <= STEP; up_down <= 0; end end end if (counter < duty_cycle) begin led <= 0; end else begin led <= 1; endend endmodule 创建 SmartDesign 文件:选择 “File> New > SmartDesign”,输入合适的名称(如 “breathing_led_smart”)并点击 “OK”。 在 SmartDesign 中添加 HDL 文件:在 Libero SoC 的 IP catalog 中找到并拖入 “breathing_led.v” 对应的 HDL 文件到 SmartDesign 画布中。 设置引脚并连接到上层:在 SmartDesign 画布中,选中 “breathing_led” 模块的相关引脚(如 clk 和 led),右键选择 “Promote to Top Level”,将这些引脚连接到上层,以便后续进行引脚分配和设计验证。 仿真验证:利用 Libero SoC 的仿真工具,对设计进行仿真验证。设置合适的仿真激励,观察输出结果是否符合预期,检查代码功能是否正确实现。 (三)编译综合 在 “Design Flow” 窗口中,展开 “Implement Design”,右键点击 “Synthesize” 并选择 “Run”。编译综合过程完成后,仔细查看编译综合信息和资源使用报告,评估设计对 FPGA 资源的占用情况,判断是否满足项目需求。 (四)引脚分配 在 “Design Flow” 窗口中,展开 “Constraints”,右键点击 “Manage Constraints”,选择 “Open Manage Constraints View”。 在弹出的 “Constraint Manager” 窗口中,选择 “I/O Attributes” 选项卡,点击 “Edit with I/O Editor”。 在 “I/O Editor” 的 “Port View” 页面,依据开发板指南,将 “clk” 引脚连接到 R18 引脚,“led” 引脚连接到 T18 引脚,并设置正确的 I/O 标准。完成设置后,选择 “File > Commit and Check”,确保引脚分配无误。 (五)布局布线 引脚分配完成后,在 “Design Flow” 窗口中,右键点击 “Place and Route” 并选择 “Run”。布局布线完成后,查看布局布线报告中的时序和信号延迟信息,评估设计的时序性能是否满足要求。 (六)下载文件 布局布线完成后,在 “Design Flow” 窗口中,展开 “Program Design”,右键点击 “Run PROGRAM Action” 并选择 “Run”。通过 FlashPro Express 软件将生成的文件下载到开发板中,下载过程中确保开发板连接正常且供电稳定,切勿打断下载操作。 (七)功能测试 观察开发板上 LED1 的状态,正常情况下应呈现呼吸灯效果,留意亮度变化是否平滑。 三、测评结果分析 (一)功能实现 LED1 呈现出呼吸灯效果,但亮度变化不够平滑,这表明代码功能虽已实现,但频率设置可能需要进一步调整优化,以达到更理想的视觉效果。 (二)频率准确性 将测量得到的频率与 1500Hz 进行对比,若偏差在 ±10% 范围内,则可认为频率满足要求。若偏差较大,当实际频率高于 1500Hz 时,适当增大代码中的 COUNT_MAX 参数值;若实际频率低于 1500Hz,则适当减小 COUNT_MAX 参数值。调整参数后,需重新进行编译、下载和测试,直至频率达到满意的精度范围。 [localvideo]f3276c0c3389b7051b3cdb05f3318cba[/localvideo]  

  • 2025-02-27
  • 回复了主题帖: 【microchip PolarFire SoC FPGA 套件】②并不算一帆风顺的点灯之旅

    这个板子还是很强大的,不过阅读英语比较吃力的话,可以试试ai(不过ai也会有些问题存在,比如乱回复,回答没有重点)

  • 发表了主题帖: 【microchip PolarFire SoC FPGA 套件】led闪灭实现

    硬件连接:开发板提供了八个低电平有效 LED(LED1 - LED8),用于调试应用,这些 LED 连接到 PolarFire SoC FPGA。其中 LED1 连接到 FPGA 引脚 T18。 工程创建与设置 启动 Libero SoC 软件,创建新工程,在相应对话框中依次设置工程名称,首选 Verilog,并在后续页面选择器件系列等参数,最后点击 “Finish” 完成工程创建。 打开 SmartDesign 画布,输入合适名称创建新设计,展开 Libero SoC IP 目录中的 Macro Library,拖放相关逻辑元件到画布并按设计思路连接配置。 引脚分配与约束配置 查阅文档确定 LED 对应的 FPGA 引脚信息及 I/O 标准,如 LED1 的引脚为 T18,I/O 标准为 LVCMOS18。 在硬件手册上可以得知,两个按键的引脚名称。通过和led1进行连接,便可以进行亮灭控制。 在软件中进入 Design Flow 窗口,展开 Constraints,右键点击 “Manage Constraints” 并选择 “Open Manage Constraints View”;在 Constraint Manager 窗口选择 “I/O Attributes” 选项卡,点击 “Edit with I/O Editor”; 于 I/O Editor 页面的 “Port View” 选项卡设置 LED 引脚的 I/O Standard 和 Pin Number,可点击 “Unassigned” 查看可用引脚后手动输入或选择,完成后选择 “I/O Attribute Editor” 菜单的 “File > Commit and Check” 检查错误确保连接匹配。 烧录和测试 最后点击进行编程烧录,注意不要打断。 最后就可以进行按键控制亮灭了。使用现成的ip内核进行开发是非常方便又快捷的。 进度条跑完,出现一个小绿勾就是烧写完毕了。

  • 发表了主题帖: 【microchip PolarFire SoC FPGA 套件】PolarFire SoC FPGA 开发套件开箱测评

    一、开箱展示 PolarFire SoC FPGA 开发套件包装防护到位。打开包装,开发板置于海绵凹槽中,核心 MPFS095T - 1FCSG325E FPGA 芯片醒目,周边接口与元件布局有序。套件附带 USB 2.0 C 型公对公屏蔽线,线质好保障数据传输;Quickstart 卡标注基本连接与操作步骤,方便上手。 二、开发环境搭建 (一)软件安装配置 首先前往官网进行下载,可以直接进行搜索或者点击手册中的超链接; https://www.microchip.com/en-us/products/fpgas-and-plds/fpga-and-soc-design-tools/fpga/libero-software-later-versions 我前面就是绕了弯路,下载的其他版本,创建工程时候超不到开发板对应的参数; 然后按向导安装 Libero® SoC 套件,除了没有安装在C盘,其他的我都是默认选项,其自带编程驱动。安装时依系统版本和开发目标选路径与功能模块。同时安装 SoftConsole 用于调试,注意与 Libero® SoC 版本兼容。若用 DirectCores 和固件驱动,按文档指引分别下载安装; 然后在 Microchip Portal 注册获免费 Silver 许可证,如果没有账号的,用邮箱注册一个; https://www.microchip.com/en-us/products/fpgas-and-plds/fpga-and-soc-design-tools/fpga/licensing 然后选择Libero Silver 1 Yr DiskID NL License; 需要输入C盘的识别符号,我是在WINDOWS平台新进行开发的,在终端里输入“vol c:“就可以获得c盘的识别符了; lisces会在30分钟内发送到你的邮箱中,接着就可以点开软件,选择lisces所在路径,就能进行使用了; (二)硬件连接设定 开发板可通过 Type - C 端口或 5V DC 插孔供电,默认 J47 跳线 1、2 引脚闭合由 Type - C 供电,用 5V DC 插孔则打开。我是直接连接在电脑usb端进行供电的 三、工程创建流程 完成环境搭建后,用 Libero 软件编程。 点击 “New” 或 “Project > New Job Project” 创建项目,指定编程作业文件路径与保存位置。 选文件要适配目标设备与需求。点击 “finish”,确认编程器编号,完成初步设置。 准备好后点击 “RUN” 编程,成功显示 “RUN PASSED” 即可后续开发测试。

  • 2025-02-06
  • 回复了主题帖: 测评入围名单: PolarFire SoC FPGA Discovery 套件

    确认可完成测评计划

  • 2024-11-27
  • 回复了主题帖: 免费下载 | 安森美电动汽车充电白皮书,看碳化硅如何缓解“里程焦虑”!

    已经参加

  • 2024-11-11
  • 发表了主题帖: STM32H7S78-DK 开发套件三周目评测:简单声音采集保存之SD 卡录音保存和状态显示

    最后一个测试周目是基于 STM32H7 微控制器的音频采集与处理系统,能够采集音频信号,并将其以 WAV 格式保存至 SD 卡。采用 LED 闪烁来为用户提供各种状态反馈,包括录音状态、错误信息等。 二、项目模块结构 (一)错误处理与 LED 显示模块 功能:统一处理系统中的各类错误情况,并通过控制 LED 的不同闪烁模式向用户反馈相应信息。同时,也用于设置正常录音状态下的 LED 显示模式。 代码实现: // 定义不同的闪烁模式 #define LED_OFF 0 #define LED_ON 1 #define LED_BLINK_FAST 2 #define LED_BLINK_SLOW 3 #define LED_ALTERNATE_BLINK 4 // 定义错误码对应的闪烁模式 #define ERROR_MOUNT_SD_CARD LED_BLINK_FAST #define ERROR_OPEN_FILE LED_BLINK_FAST #define ERROR_ADC_DMA_INIT LED_BLINK_FAST #define RECORDING_ON LED_ON #define RECORDING_OFF LED_OFF #define ERROR_LONG_PRESS LED_BLINK_FAST // 错误处理函数,通过LED闪烁显示错误 void handleError(uint8_t errorMode) { switch (errorMode) { case ERROR_MOUNT_SD_CARD: case ERROR_OPEN_FILE: case ERROR_ADC_DMA_INIT: case ERROR_LONG_PRESS: // 设置LED闪烁模式来表示错误 setLEDMode(errorMode); break; default: break; } } // 设置LED的闪烁模式 void setLEDMode(uint8_t mode) { switch (mode) { case LED_OFF: HAL_GPIO_WritePin(GPIO_PIN_1, GPIO_PIN_RESET); // LD1(绿色)关闭 HAL_GPIO_WritePin(GPIO_PIN_5, GPIO_PIN_RESET); // LD2(橙色)关闭 HAL_GPIO_WritePin(GPIO_PIN_2, GPIO_PIN_SET); // LD3(红色)关闭 break; case LED_ON: if (mode == RECORDING_ON) { HAL_GPIO_WritePin(GPIO_PIN_1, GPIO_PIN_SET); // LD1(绿色)打开,表示录音中 HAL_GPIO_WritePin(GPIO_PIN_5, GPIO_PIN_RESET); // LD2(橙色)关闭 HAL_GPIO_WritePin(GPIO_PIN_2, GPIO_PIN_SET); // LD3(红色)关闭 } break; case LED_BLINK_FAST: // 实现快速闪烁逻辑(使用LD2橙色LED) for (int i = 0; i < 10; i++) { HAL_GPIO_TogglePin(GPIO_PIN_5, GPIO_PIN_SET); HAL_Delay(100); } break; case LED_BLINK_SLOW: // 实现慢速闪烁逻辑(使用LD2橙色LED) for (int i = 0; i < 5; i++) { HAL_GPIO_TogglePin(GPIO_PIN_5, GPIO_PIN_SET); HAL_Delay(500); } break; case LED_ALTERNATE_BLINK: // 实现交替闪烁逻辑 for (int i = 0; i < 5; i++) { HAL_GPIO_TogglePin(GPIO_PIN_1, GPIO_PIN_SET); HAL_GPIO_TogglePin(GPIO_PIN_5, GPIO_PIN_SET); HAL_Delay(300); } break; } }   在这个模块中,handleError函数接收错误模式参数,并调用setLEDMode函数来控制 LED 的闪烁模式。不同的错误或状态对应不同的闪烁模式,如ERROR_MOUNT_SD_CARD等错误码对应LED_ALTERNATE_BLINK模式,而录音开启状态RECORDING_ON对应LED_ON模式,通过LED1(红灯)和LED2(绿灯)的亮灭或LED3(用于特殊状态显示)的闪烁来向用户传达信息。 (二)音频采集模块 功能:利用 STM32 的 ADC(轮询方式)启动音频信号采集过程。 代码实现: // 初始化音频采集 void InitAudioCapture() { if (HAL_ADC_Start(&hadc1)!= HAL_OK) { handleError(ERROR_ADC_START); } }   InitAudioCapture函数用于初始化音频采集功能。它主要负责启动 STM32 芯片上的模数转换器(ADC)。如果 ADC 启动成功,那么后续就可以开始采集音频信号;如果启动失败,则通过调用handleError函数来处理错误,这里的错误处理方式是根据预定义的错误模式(ERROR_ADC_START)来控制 LED 闪烁,向用户提示 ADC 启动出现问题。 (三)WAV 文件生成模块 功能:生成符合 WAV 格式标准的文件头。 代码实现: // 生成WAV文件头 void generateWavHeader(FIL *file) { uint32_t dataSize = 0; uint32_t byteRate = SAMPLE_RATE * NUM_CHANNELS * (BITS_PER_SAMPLE / 8); uint32_t blockAlign = NUM_CHANNELS * (BITS_PER_SAMPLE / 8); // RIFF 块 const char riffHeader[] = {'R', 'I', 'F', 'F'}; f_write(file, riffHeader, sizeof(riffHeader), NULL); f_write(file, &dataSize, sizeof(dataSize), NULL); const char waveFormat[] = {'W', 'A', 'V', 'E'}; f_write(file, waveFormat, sizeof(waveFormat), NULL); // fmt 子块 const char fmtHeader[] = {'f', 'm', 't', ' '}; f_write(file, fmtHeader, sizeof(fmtHeader), NULL); const uint32_t fmtChunkSize = 16; f_write(file, &fmtChunkSize, sizeof(fmtChunkSize), NULL); const uint16_t audioFormat = 1; f_write(file, &audioFormat, sizeof(audioFormat), NULL); f_write(file, &NUM_CHANNELS, sizeof(NUM_CHANNELS), NULL); f_write(file, &SAMPLE_RATE, sizeof(SAMPLE_RATE), NULL); f_write(file, &byteRate, sizeof(byteRate), NULL); f_write(file, &blockAlign, sizeof(blockAlign), NULL); f_write(file, &BITS_PER_SAMPLE, sizeof(BITS_PER_SAMPLE), NULL); // data 子块 const char dataHeader[] = {'d', 'a', 't', 'a'}; f_write(file, dataHeader, sizeof(dataHeader), NULL); f_write(file, &dataSize, sizeof(dataSize), NULL); }   该模块根据定义好的音频参数(如采样率SAMPLE_RATE、声道数NUM_CHANNELS、每个样本的位数BITS_PER_SAMPLE)生成 WAV 文件头。此函数在录音保存到 SD 卡的过程中被调用。 (四)录音保存到 SD 卡模块 功能:将采集到的音频数据保存为 WAV 格式文件到 SD 卡,并以日期时间命名文件,同时处理文件操作过程中的错误情况。 代码实现:   此模块首先尝试挂载 SD 卡文件系统,在这一过程中若挂载失败(即f_mount函数返回值不为FR_OK),则通过handleError函数以ERROR_MOUNT_SD_CARD对应的 LED 闪烁模式向用户提示错误信息。挂载成功后,接着会根据当前日期和时间来创建文件名。之后尝试打开此文件,若文件打开操作失败(也就是f_open函数返回值不为FR_OK),同样会调用handleError函数,同时卸载文件系统。当文件成功打开后,会生成符合 WAV 格式的文件头。在录音过程中,使用轮询 ADC 转换是否完成,完成后获取其值并将音频数据逐个写入文件。待录音结束后,根据已写入文件的音频数据量来更新 WAV 文件头中的数据大小信息,最后关闭文件,并卸载 SD 卡文件系统。 (五)按键控制模块 功能:实现按键防抖功能,并通过按键控制录音的开始、停止、暂停等操作,同时在出现异常按键情况(如长按)时通过 LED 显示错误信息。 代码实现: // 更完善的按键防抖和长按检测 #define DEBOUNCE_COUNT 5 #define LONG_PRESS_TIME 1000 // 长按时间阈值(单位:毫秒) uint8_t buttonDebounceCounter = 0; uint32_t buttonPressStartTime = 0; // 假设这里的 BUTTON_Pin 就是控制 B2 按键的引脚(PC13) #define BUTTON_Pin GPIO_PIN_13 #define BUTTON_PORT GPIOC uint8_t debounceButton(uint16_t GPIO_Pin) { uint8_t currentState = HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_Pin); // 读取B2按键引脚状态 if (currentState == button.previousState) { if (currentState == GPIO_PIN_SET) { // 按下为高电平 buttonDebounceCounter++; if (buttonDebounceCounter >= DEBOUNCE_COUNT) { if (HAL_GetTick() - buttonPressStartTime > LONG_PRESS_TIME) { handleError(ERROR_LONG_PRESS); return GPIO_PIN_SET; // 返回高电平表示长按 } } } else { buttonDebounceCounter = 0; buttonPressStartTime = HAL_GetTick(); } } else { buttonDebounceCounter = 0; button.previousState = currentState; } return 0; } // 按键中断处理 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) { if (GPIO_Pin == BUTTON_Pin && debounceButton(GPIO_Pin) == GPIO_PIN_SET) { // 检测到B2按下 switch (buttonAction) { case BUTTON_PRESS_SHORT: recording =!recording; setLEDMode(recording? RECORDING_ON : RECORDING_OFF); if (recording) { SaveAudioToSDCard(); } break; default: break; } } }   在debounceButton函数中,实现了按键防抖和长按检测功能。当检测到按键按下且经过防抖处理后,如果按键按下时间超过LONG_PRESS_TIME阈值,判定为长按操作,调用handleError函数以ERROR_LONG_PRESS对应的 LED 闪烁模式提示用户。在HAL_GPIO_EXTI_Callback函数中,处理短按按键操作,根据按键状态切换录音状态,并通过setLEDMode函数设置相应的 LED 显示模式(录音开启时为RECORDING_ON模式,录音停止时为RECORDING_OFF模式),同时在录音开始时调用SaveAudioToSDCard函数开始保存音频。   实际操作时候,保存文件一直有问题,保存的文件打开音频有些失真,应该是采样率的问题,还需要修改调试一下。。。

  • 2024-11-07
  • 回复了主题帖: # STM32H7S78-DK 开发套件三周目评测:简单声音采集保存之使用 SD 卡读写的实现与分析

    cc1989summer 发表于 2024-11-2 13:03 哥们,你这帖子在那干讲,没开发板跑的实物图啊。 后面加,哈哈哈

  • 2024-11-01
  • 回复了主题帖: 《STM32H7S78-DK 开发套件二周目评测:简单声音采集之驱动MAX4466高精度声音传感器》

    cc1989summer 发表于 2024-10-30 21:46 哥们,翻到开发板背面,靠近USB1上面,有个芯片U1:MP23DB01,就是数字麦克风 o.o!!!我看手册是写有麦克风,但是又看示意图写的是一个麦克风接口。原来是这样!

  • 2024-10-31
  • 发表了主题帖: # STM32H7S78-DK 开发套件三周目评测:简单声音采集保存之使用 SD 卡读写的实现与分析

    该项目包括了保存录音、按键控制、串口控制、频率成分分析与分类等功能,逐步进行完成。 首先进行sd读写的开。在嵌入式开发中,尤其在无操作系统的裸机环境下,SD卡是实现大容量数据存储的重要组件。 ## 1. 硬件连接 在开始CubeMX配置前,需要先了解引脚的配置。 ### 1.1 数据引脚连接 - **D0 - D3**:将SD卡的数据引脚D0-D3分别连接到STM32的PC8、PC9、PC10、PC11。 - **CMD**:将SD卡的CMD引脚连接到STM32的PD2,用于命令传输。 - **CLK**:将SD卡的CLK引脚连接到STM32的PC12,提供时钟信号。 - **SD_Detect**:将SD卡的SD_Detect引脚连接至GPIO(PM14),用于检测SD卡插入状态。 具体连接示例代码: ```c // 配置引脚,在CubeMX中生成的初始化代码中可见 void MX_GPIO_Init(void) {     GPIO_InitTypeDef GPIO_InitStruct = {0};     // Enable clock for GPIOC and GPIOD     __HAL_RCC_GPIOC_CLK_ENABLE();     __HAL_RCC_GPIOD_CLK_ENABLE();     __HAL_RCC_GPIOM_CLK_ENABLE();  // 使能PM14引脚所在的GPIO时钟     // 配置SDMMC引脚:CMD (PD2), CLK (PC12), D0 (PC8), D1 (PC9), D2 (PC10), D3 (PC11)     GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_2;     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;     GPIO_InitStruct.Pull = GPIO_NOPULL;     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;     GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);         // 配置SD_Detect引脚 (PM14)     GPIO_InitStruct.Pin = GPIO_PIN_14;     GPIO_InitStruct.Mode = GPIO_MODE_INPUT;     GPIO_InitStruct.Pull = GPIO_PULLUP; // 内部上拉电阻     HAL_GPIO_Init(GPIOM, &GPIO_InitStruct); } ``` ## 2. CubeMX 配置与代码实现 CubeMX能够简化SD卡和文件系统的配置,我们将通过它来生成SD卡的初始化代码,并使用FATFS文件系统以实现文件操作。这里选择FATFS文件系统方式除了是可以直接配置简单快捷外,使用eprom还有一些缺点: 1.没有文件系统,sd卡在电脑等设备无法读取。 2.读写速度慢、读写区域小。 ### 2.1 CubeMX 配置步骤 #### 2.1.1 SDMMC 接口设置 1. 在CubeMX中打开**Peripherals -> SDMMC1**接口。 2. 将其模式设置为**4-bit**模式,以提升数据传输速率。 3. 在**Clock Configuration**中将SDMMC1的时钟频率调整为48MHz,以保证传输速率和稳定性。 #### 2.1.2 启用 FATFS 文件系统 1. 在**Middlewares**中启用FATFS支持,选择SDMMC1作为接口,以实现基于文件系统的操作。 2. 生成初始化代码,其中`fatfs.c`文件包含了文件系统初始化和读写的基本接口。 ### 2.2 基本代码示例 接下来使用FATFS文件系统在SD卡上进行文件创建、写入和读取: ```c #include "fatfs.h" #include "sdmmc.h" #include void SD_Test() {     FATFS fs;     FIL file;     FRESULT res;     UINT bw;     // 挂载文件系统     res = f_mount(&fs, "0:", 1);     if (res == FR_OK) {         // 创建并写入文件         res = f_open(&file, "0:/test.txt", FA_CREATE_ALWAYS | FA_WRITE);         if (res == FR_OK) {             char writeData[] = "Hello, SD Card!";             f_write(&file, writeData, sizeof(writeData), &bw);             f_close(&file);         }         // 读取文件         res = f_open(&file, "0:/test.txt", FA_READ);         if (res == FR_OK) {             char readData[32];             f_read(&file, readData, sizeof(readData), &bw);             printf("Read data: %s\n", readData);             f_close(&file);         }         // 卸载文件系统         f_mount(NULL, "0:", 1);     } } ``` ## 3. 不同 SD 卡读写方式与代码分析 当然在不同场景和需求下,对sd卡的读写操作应该有适当改变,才能提高效率、节省资源。 ### 3.1 基于文件系统的标准读写 - **优点**:CubeMX自动生成FATFS代码,简化了文件操作流程,适用于低频存储。比如传感器的数据记录等。 - **缺点**:由于文件系统需要索引和管理结构,写入速度会受影响。 ```c void SD_WriteRead_FileSystem() {     FATFS fs;     FIL file;     UINT bw, br;     char writeData[] = "File System Write Test";     char readData[32];     // 挂载文件系统     f_mount(&fs, "0:", 1);     // 写入文件     f_open(&file, "0:/filesystem.txt", FA_CREATE_ALWAYS | FA_WRITE);     f_write(&file, writeData, sizeof(writeData), &bw);     f_close(&file);     // 读取文件     f_open(&file, "0:/filesystem.txt", FA_READ);     f_read(&file, readData, sizeof(readData), &br);     f_close(&file);     printf("Read Data: %s\n", readData);     f_mount(NULL, "0:", 1); } ``` ### 3.2 扇区级块读写 - **优点**:直接操作扇区避免了文件系统开销,适合高频数据写入。比如音视频、网络文件等。 - **缺点**:需要手动管理数据位置和扇区分配,编程难度大。 ```c void SD_WriteBlock(uint32_t sector, uint8_t *data, uint32_t count) {     if (HAL_SD_WriteBlocks(&hsd1, data, sector, count, HAL_MAX_DELAY) == HAL_OK) {         printf("Block write success!\n");     } } void SD_ReadBlock(uint32_t sector, uint8_t *data, uint32_t count) {     if (HAL_SD_ReadBlocks(&hsd1, data, sector, count, HAL_MAX_DELAY) == HAL_OK) {         printf("Block read success!\n");     } } ``` ### 3.3 缓存 + 文件系统混合模式 - **优点**:使用缓存减少频繁写入,提升写入效率,适合音频等连续数据存储。 - **缺点**:占用较多RAM资源,需考虑系统内存限制。 ```c #define BUFFER_SIZE 512 uint8_t cacheBuffer[BUFFER_SIZE]; void SD_WriteCache(const char *data) {     static uint32_t offset = 0;     while (*data) {         cacheBuffer[offset++] = *data++;         if (offset >= BUFFER_SIZE) {             SD_WriteBlock(0, cacheBuffer, BUFFER_SIZE / 512); // 以块为单位写入             offset = 0;         }     } } ``` ## 4. 音频数据存储的优化方案 考虑到录音是一个时效性很强的操作,所以对存储效率要求很高,下面是两个优化的方案。 ### 4.1 双缓冲技术 设置两个缓冲区,交替写入SD卡以减小写入延时。 ```c uint8_t bufferA[BUFFER_SIZE]; uint8_t bufferB[BUFFER_SIZE]; volatile uint8_t *currentBuffer = bufferA; void Audio_WriteToSD() {     if (currentBuffer == bufferA) {         SD_WriteBlock(0, bufferA, BUFFER_SIZE / 512);         currentBuffer = bufferB;     } else {         SD_WriteBlock(0, bufferB, BUFFER_SIZE / 512);         currentBuffer = bufferA;     } } ``` ### 4.2 文件分段存储 音频数据按时间或大小分段存储,避免大文件操作带来的开销。 ```c void SaveAudioSegment(uint8_t *data, size_t size, uint8_t segmentNum) {     char filename[20];     sprintf(filename, " audio_segment_%d.wav", segmentNum);     f_open(&file, filename, FA_CREATE_ALWAYS | FA_WRITE);     f_write(&file, data, size, &bw);     f_close(&file); } ```

  • 2024-10-30
  • 回复了主题帖: 《STM32H7S78-DK 开发套件二周目评测:简单声音采集之驱动MAX4466高精度声音传感器》

    cc1989summer 发表于 2024-10-29 00:31 楼主,STM32H7S78-DK本身就带数字麦克风,理论上可以通过该麦克风实现音量检测…… 我开始也是看他有数字麦克风,才想测评弄这个,但是我只找到一个麦克风接口,有点疑惑。所以就干脆直接买了一个麦克风

  • 2024-10-21
  • 回复了主题帖: 《STM32H7S78-DK 开发套件二周目评测:简单声音采集之频率检测与显示》

    Jacktang 发表于 2024-10-20 08:50 这个对检测的音频信号有没有要求呢,比如最低的频率大小   按照目前的采样率的话,理论上的最低频率大约为1hz,最高大约是500hz的样子

  • 2024-10-18
  • 发表了日志: 《STM32H7S78-DK 开发套件二周目评测:简单声音采集之频率检测与显示》

  • 发表了主题帖: 《STM32H7S78-DK 开发套件二周目评测:简单声音采集之频率检测与显示》

    在实现adc基础上,实现对音频信号频率的检测。读取模拟信号并通过 FFT(快速傅里叶变换)分析频率成分。同时,在串口输出检测到的频率,并通过 LED 显示结果。 一、硬件连接 引脚连接: 将 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(); } } }

  • 发表了日志: 《STM32H7S78-DK 开发套件二周目评测:简单声音采集之驱动MAX4466高精度声音传感器》

  • 发表了主题帖: 《STM32H7S78-DK 开发套件二周目评测:简单声音采集之驱动MAX4466高精度声音传感器》

    本帖最后由 ccccccc@ 于 2024-10-18 11:52 编辑 MAX4466是一款高精度声音传感器,能够将声音信号转化为相应的模拟电压输出。STM32H7系列微控制器具备高性能的ADC(模数转换器)功能,可以精确地采集模拟信号并进行数字化处理。     使用STM32H7S78-DK开发板,通过ADC(模数转换器)采集MAX4466高精度声音传感器的模拟信号,最终实现一个简单的音量检测功能。 有下面个步骤: - 从MAX4466传感器采集音频信号。 - 对采集的数据进行处理,获得稳定的音量信息。   硬件连接: 引脚连接: 如上图所示,可以将MAX4466传感器的输出引脚连接到STM32的ADC输入引脚(即PC0,ADC12_IN10),设置该GPIO的ADC功能属性。   使用CubeMX进行配置: 在CubeMX中,进行如下设置: 选择ADC模块:选择ADC1,设置为12位分辨率,适合音频信号处理。 设置采样时间:设置为3.5个ADC时钟周期,确保稳定采样。 设置转换模式:选择单次转换模式(Single Conversion),适合简单应用。 时钟设置: 确保ADC时钟频率与采样时间相匹配,避免采样延迟。 引脚设置:配置PC0为ADC输入模式。 生成代码并导入Keil:  在CubeMX中生成代码,并导入Keil进行后续的代码开发。 在Keil中,检查  初始化ADC并读取值的代码 #include "stm32h7xx_hal.h" ADC_HandleTypeDef hadc1; void ADC_Init(void) { // 使能ADC时钟 __HAL_RCC_ADC12_CLK_ENABLE(); // ADC配置 hadc1.Instance = ADC1; hadc1.Init.Resolution = ADC_RESOLUTION_12B; // 12位分辨率 hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE; // 禁用扫描模式 hadc1.Init.ContinuousConvMode = DISABLE; // 禁用连续转换 hadc1.Init.ExternalTrigConv = ADC_SOFTWARE_START; // 软件触发 hadc1.Init.DataAlign = ADC_DATAALIGN_RIGHT; // 数据右对齐 hadc1.Init.NbrOfConversion = 1; // 单次转换 HAL_ADC_Init(&hadc1); // 初始化ADC } uint32_t Read_ADC_Value(void) { HAL_ADC_Start(&hadc1); // 启动ADC转换 HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); // 等待转换完成 return HAL_ADC_GetValue(&hadc1); // 返回ADC值 } 数据处理:在main代码中进行添加下面的代码进行采集信息的数据处理 滤波处理: 使用简单的移动平均滤波器平滑采样值,减少波动。 float moving_average(float new_value) { static float avg = 0; static int count = 0; count++; avg += (new_value - avg) / count; // 计算平均值 return avg; } 偏移量校正:在初始化时获取基准值,以确保测量的准确性。 static int32_t offset = 0; void Calculate_Offset(void) { for (int i = 0; i < 100; i++) { HAL_ADC_Start(&hadc1); HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY); offset += HAL_ADC_GetValue(&hadc1); // 累加ADC值 } offset /= 100; // 计算平均偏移量 } uint32_t Get_Corrected_ADC_Value(void) { uint32_t adc_value = Read_ADC_Value(); // 读取ADC值 return adc_value - offset; // 返回校正后的值 }   UART配置: 通过UART输出采样结果,方便观察和调试。当然也可以使用LED进行对应的显示。在CUBEMAX进行对应的配置;       UART_HandleTypeDef huart1; void UART_Init(void) { // 使能USART1时钟 __HAL_RCC_USART1_CLK_ENABLE(); // USART配置 huart1.Instance = USART1; huart1.Init.BaudRate = 115200; // 波特率 huart1.Init.WordLength = USART_WORDLENGTH_8B; // 字长 huart1.Init.StopBits = USART_STOPBITS_1; // 停止位 huart1.Init.Parity = USART_PARITY_NONE; // 无奇偶校验 huart1.Init.Mode = USART_MODE_TX_RX; // 发送接收模式 HAL_UART_Init(&huart1); // 初始化UART } void UART_Send_Data(uint32_t data) { char buffer[20]; sprintf(buffer, "ADC Value: %lu\n", data); // 格式化输出 HAL_UART_Transmit(&huart1, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY); // 发送数据 } 7.主程序: 在主循环中读取ADC值,并通过UART输出。 int main(void) { HAL_Init(); // 初始化HAL库 ADC_Init(); // 初始化ADC UART_Init(); // 初始化UART Calculate_Offset(); // 计算偏移量 while (1) { uint32_t corrected_value = Get_Corrected_ADC_Value(); // 获取校正后的ADC值 float smoothed_value = moving_average(corrected_value); // 平滑处理 UART_Send_Data(corrected_value); // 发送ADC值 } }   8.关于噪声处理: 滤波策略:可以通过选择适当的滤波窗口,达到避免数据波动的效果。并且考虑使用中位数滤波或加权平均滤波,以处理异常值和噪声。   9.当然还可以进一步进行性能优化: 使用DMA: 对于快速连续采样的需求,可以考虑使用DMA(直接存储器访问)进行数据采集,减轻CPU负担。 DMA_HandleTypeDef hdma_adc1; void DMA_Init(void) { __HAL_RCC_DMA2_CLK_ENABLE(); // 使能DMA时钟 hdma_adc1.Instance = DMA2_Stream0; hdma_adc1.Init.Channel = DMA_CHANNEL_0; // 选择通道 hdma_adc1.Init.Direction = DMA_PERIPH_TO_MEMORY; // 从外设到内存 hdma_adc1.Init.PeriphInc = DMA_PINC_DISABLE; // 禁用外设地址递增 hdma_adc1.Init.MemInc = DMA_MINC_ENABLE; // 启用内存地址递增 hdma_adc1.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD; // 外设数据对齐 hdma_adc1.Init.MemDataAlignment = DMA_MDATAALIGN_WORD; // 内存数据对齐 hdma_adc1.Init.Mode = DMA_CIRCULAR; // 循环模式 hdma_adc1.Init.Priority = DMA_PRIORITY_HIGH; // 高优先级 HAL_DMA_Init(&hdma_adc1); // 初始化DMA __HAL_LINKDMA(&hadc1, DMA_Handle, hdma_adc1); // 连接DMA与ADC }      

  • 2024-10-10
  • 回复了主题帖: 《STM32H7S78-DK 开发套件一周目评测:初试点灯,问题重重》

    Jacktang 发表于 2024-10-10 07:26 右键设置appli为活动项,进行编译,但是使用mdk直接进行烧录时候,开发板没有反应,这个是不是编译环境那里 ... 编译出来的文件直接烧录又没有问题,可以正常运行。而且mdk点击烧录时候,他又显示烧录成功。

  • 发表了主题帖: 《STM32H7S78-DK 开发套件一周目评测:初试点灯,问题重重》

    距离上一次开箱又过了很久,终于抽出时间继续埋头码字。   看其他的帖子,开机后都能进行触屏历程,我的上电后却没有反应。查看活动告知,可能是上一个使用者把历程给刷掉了,问题不大。   我来到官方支持下载了两个例程文件,分别是:   上面一个是hex文件,下面一个是工程文件,这里需要求助一下,hex文件进行烧录时候会显示烧录失败   下面的工程使用MDK-arm进行编译时候会报错缺一堆库 我查看路径时候,发现有些文件,在路径中找不到:   感觉处处碰壁,索性开始尝试点灯   使用cubemax直接对对应的四个引脚进行初始化:     然后对工程进行配置,我使用mdk进行开发:     生成代码后,点开mdk文件:   里面有两个文件分别是boot和appli,对boot进行编译时候也有报错,但是我们目前只需要烧录appli   右键设置appli为活动项,进行编译,但是使用mdk直接进行烧录时候,开发板没有反应,我都在想是不是遇到一个坏掉的,再使用programe进行烧录,就成功了;       目前几个问题都还不知道原因,只是验证了开发环境和步骤没有什么问题,接下来开始进行adc的开发。。。    

  • 2024-09-19
  • 发表了主题帖: 《STM32H7S78-DK 开发套件一周目评测:初识与准备》

        一、引言   本次评测重点聚焦于 STM32H7S78-DK 开发套件的数字麦克风功能。在一周目的评测中,我们将深入熟悉该开发套件的硬件结构与相关文档,精心准备测试设备和工具,并搭建测试环境,从而为后续的深入评测筑牢坚实基础。   二、开箱初体验   当双手触及 STM32H7S78-DK 开发套件的包装时,立刻能感受到其包装的扎实与专业风范。怀着满心的期待,小心翼翼地打开包装,首先映入眼帘的是采用防静电袋精心包装好的开发板、STMod + 扩展板、WiFi 模组以及一张内存卡。     开发板的外观设计简洁大方,电路板上的元件布局合理,尽显工艺之精良。一眼望去,STM32H7S78 微控制器以及丰富的通信接口清晰可见。开发板的边缘处理得极为光滑,毫无任何毛刺,充分彰显了高品质的制造工艺。   三、STM32H7S78-DK 开发套件硬件介绍   STM32H7S78-DK 开发套件为开发者倾力打造了强大的硬件平台,并赋予了丰富多样的功能。该探索套件涵盖了一整套硬件功能,能够助力用户对众多外设进行评估,诸如 USB Type-C、Octo-SPI 闪存与 Hexadeca-SPI PSRAM 器件、音频编解码器、数字麦克风、ADC、灵活扩展连接器以及用户按钮等。四个灵活的扩展连接器为特定应用(例如无线连接、模拟应用和传感器)提供了轻松且无限制的扩展功能。   其中,STM32H7S7L8H6H 微控制器具备三个 I²C 总线、六个 SPI 端口、三个 USART 端口、两个 SDMMC 端口、两个 CAN 端口、一个以太网端口、两个 SAI 端口、两个 12 位 ADC、一个嵌入式降压转换器、两个 Octo-SPI 存储器接口、一个 Hexadeca-SPI 接口、带供电功能的 USB OTG HS 端口、LCD-TFT 控制器、灵活存储控制器(FMC)、8 至 14 位 DCMI 接口、JTAG 和 SWD 调试支持。STM32H7S78-DK 探索套件还集成了用于 STM32 MCU 的 STLINK-V3EC 嵌入式在线调试器和编程器,并且带有 USB 虚拟 COM 端口桥接器,同时配备了全面的 MCU 软件包。   四、文档介绍   STM32H7S78-DK 开发套件提供了极为详细的文档,其中包括用户手册、参考手册、数据手册等。这些文档对于深入了解开发套件的硬件结构、功能特性以及开发方法有着极大的帮助。可以前往以下网址进行对应资料的下载:   数据摘要以及硬件电路图:https://www.st.com.cn/zh/evaluation-tools/stm32h7s78-dk.html#cad-resources; keil 开发库:https://www.keil.arm.com/packs/stm32h7rsxx_dfp-keil/devices/; 官方 demo:https://www.st.com/resource/en/demos_resources/stm32h7s78-dk-touchgfx-demo-1-1-2.zip; 更多参考资料:https://www.st.com.cn/zh/microcontrollers-microprocessors/stm32h7s7l8.html#documentation。   五、开发环境的准备   安装开发工具 我个人比较习惯使用 keil 进行开发,不过 STM32CubeIDE 的快速上手特性也着实令人着迷。由于本次测试时间周期较短,再加上工作较为繁忙,因此比较倾向于使用 Cube 来完成本次测试。 STM32CubeIDE:这是一款基于 Eclipse 的集成开发环境,全力支持 STM32 系列微控制器的开发。可以从 ST 官网下载安装:https://www.st.com.cn/zh/development-tools/stm32cubeide.html。 Keil MDK:另一种常用的开发工具,同样支持 STM32 系列微控制器的开发。可从 Keil 官网下载:https://www.keil.com/download/product/。 安装驱动程序 开发套件可能需要安装特定的驱动程序,以确保与计算机能够正常通信。本开发板支持 STLINK-V3EC 嵌入式在线调试器和编程器。可以在 ST 官网或开发套件的文档中找到相应的驱动程序下载链接:https://www.st.com.cn/zh/development-tools/stsw-link007.html。  

  • 2024-09-12
  • 回复了主题帖: 读书活动颁奖:《Rust实战》

    下次换个不用互动的活动参加,退回邮费自理感觉有点被伤到。。。

最近访客

< 1/2 >

统计信息

已有62人来访过

  • 芯积分:160
  • 好友:1
  • 主题:21
  • 回复:29

留言

你需要登录后才可以留言 登录 | 注册


现在还没有留言