基于stm32的迷你示波器
难度系数:4分事情量:4分创新点:3分1 简介在一些大略的电子电路设计中,无需利用到高性能且体积弘大的台式示波器。因此,本项目为体积小巧的USB虚拟示波器。在设计过程中,在考虑了本钱问题的根本上,只管即便实现标准示波器的各项功能,充分发挥芯片性能。参数和特点如下:
4 设计事理4.1 硬件部分
总体解释硬件紧张包括将丈量旗子暗记转换至单片机AD可以采集的仿照旗子暗记转换部分、单片机电路USB串口数字电路部分和±3.3V电源部分。
旗子暗记转换电路
旗子暗记首先经由680KΩ和220KΩ电阻电容构成的衰减电路,使得±10V的旗子暗记转化至运放可以处理的±2.5V范围,后一级电压跟随器使得示波器的输入阻抗为900KΩ/90pF。
由单刀双掷开关掌握是否经由RC高通滤波器,以实现交直流耦合切换。此处利用继电器是一个更好的方案,但仿照开关CD4053的价格显然更为得当。
两个同比较例放大器构成类似于级联的形式,由仿照开关掌握是否进行放大。第一级放大倍数为5倍,第二级放大倍数靠近于20倍。从而可以实现放大倍数为1倍、5倍、20倍、100倍的不同增益。比较较由一个运放构成的改变反馈电阻的程控放大电路,该电路对付频率较高的小旗子暗记有更好的放大能力。
后续经由电压抬升电路,将正负电压旗子暗记转换成单片机AD可以采集的旗子暗记,终极的旗子暗记将叠加在1.5V直流量上。比较器的正比较端也接入1.5V直流旗子暗记,比较器输出端即为同频率的脉冲旗子暗记。加入比较器的紧张浸染是获取波形的频率值,以更快的实现一键自动功能。
此外,图中所用的LM358通用运放在实际调试中改成了性能更好的NCS20072运放。可能由于LM358的压摆率太低,导致在频率超过10KHz时就会涌现奇怪的失落真波形。紧张事理图
4.2 软件部分软件包括STM32单片机部分和LabVIEW上位机部分。单片机紧张实现串口吸收指令、AD采集、波形数据转换和串口发送波形数据的功能。采取STM32Cube预先配置各项参数,在Keil中进一步编程。
单片机参数配置
配置ADC触发办法为定时器触发,这样可以更精准的掌握采样间隔。由DMA掌握器将波形数据保存至数组,并设置DMA为非循环模式。
配置串口波特率为256000(没有采取常用的115200,由于只有在该波特率下才能够实现20FPS的刷新率)。开启吸收中断。由DMA掌握串口发送数据,这样在发送串口数据时,不会影响主程序的运行,从而可以提高刷新速率。
在频率丈量中,配置定时器为输入捕获模式,将定时器从模式设置为复位,触发源为TI1FP1。由DMA掌握器将每次脉冲旗子暗记来临时,将定时器的计数值保存至数组。其余,比较器的输出端含有高频脉冲噪声,须要配置定时器输入通道滤波器。
单片机波形采集程序
串口波形数据格式为< Time00640+Fre00100+Amp0+DC+波形数据点>的形式。个中AD触发定时器的计数值Time,最大65535;输入捕获定时器的计数值Fre,最大65535;程控放大器的放大倍数Amp,最大值3;耦合办法用DC和AC表示。
波形采集过程如下。
上位机程序
上位机的紧张事情是解析来自串口的字符串,处理波形、打算干系参数并显示。在单片机中不进行浮点运算,所有的波形数据均为AD采集的原始数据,为整数形式。而在上位机中,须要将这些整数转换成电压值。很显然,单片机AD值和输入电压值之间理论上成完备的线性关系,在上位机中须要跟据此线性关系求得实际电压值。在本作品中,有着4种程控增益,也就对应着4个函数关系。
5 部分核心代码#include "main.h"#include "adc.h"#include "dma.h"#include "tim.h"#include "usart.h"#include "gpio.h"/ Private includes ----------------------------------------------------------// USER CODE BEGIN Includes /#include "wave.h"#include "msg.h"/ USER CODE END Includes // Private typedef -----------------------------------------------------------// USER CODE BEGIN PTD // USER CODE END PTD // Private define ------------------------------------------------------------// USER CODE BEGIN PD // USER CODE END PD // Private macro -------------------------------------------------------------// USER CODE BEGIN PM // USER CODE END PM // Private variables ---------------------------------------------------------// USER CODE BEGIN PV // USER CODE END PV // Private function prototypes -----------------------------------------------/void SystemClock_Config(void);/ USER CODE BEGIN PFP // USER CODE END PFP // Private user code ---------------------------------------------------------// USER CODE BEGIN 0 // USER CODE END 0 // @brief The application entry point. @retval int /int main(void){ / USER CODE BEGIN 1 / / USER CODE END 1 / / MCU Configuration--------------------------------------------------------/ / Reset of all peripherals, Initializes the Flash interface and the Systick. / HAL_Init(); / USER CODE BEGIN Init / / USER CODE END Init / / Configure the system clock / SystemClock_Config(); / USER CODE BEGIN SysInit / / USER CODE END SysInit / / Initialize all configured peripherals / MX_GPIO_Init(); MX_DMA_Init(); MX_ADC1_Init(); MX_TIM1_Init(); MX_TIM3_Init(); MX_USART1_UART_Init(); / USER CODE BEGIN 2 /my_UartInit(&UsartData);my_WaveInit(&WaveData); / USER CODE END 2 / / Infinite loop / / USER CODE BEGIN WHILE / while (1) { / USER CODE END WHILE / / USER CODE BEGIN 3 /my_Wave(&WaveData); } / USER CODE END 3 /}/ @brief System Clock Configuration @retval None /void SystemClock_Config(void){ RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; / Configure the main internal regulator output voltage / HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); / 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.HSIDiv = RCC_HSI_DIV1; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV1; RCC_OscInitStruct.PLL.PLLN = 8; RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; 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_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK) { Error_Handler(); } / Initializes the peripherals clocks / PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1|RCC_PERIPHCLK_ADC; PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK1; PeriphClkInit.AdcClockSelection = RCC_ADCCLKSOURCE_SYSCLK; if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK) { Error_Handler(); }}/ USER CODE BEGIN 4 // USER CODE END 4 / / @brief Period elapsed callback in non blocking mode @note This function is called when TIM14 interrupt took place, inside HAL_TIM_IRQHandler(). It makes a direct call to HAL_IncTick() to increment a global variable "uwTick" used as application time base. @param htim : TIM handle @retval None /void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef htim){ / USER CODE BEGIN Callback 0 / / USER CODE END Callback 0 / if (htim->Instance == TIM14) { HAL_IncTick(); } / USER CODE BEGIN Callback 1 / / USER CODE END Callback 1 /}/ @brief This function is executed in case of error occurrence. @retval None /void Error_Handler(void){ / USER CODE BEGIN Error_Handler_Debug / / User can add his own implementation to report the HAL error return state / __disable_irq(); while (1) { } / USER CODE END Error_Handler_Debug /}#ifdef USE_FULL_ASSERT/ @brief Reports the name of the source file and the source line number where the assert_param error has occurred. @param file: pointer to the source file name @param line: assert_param error line source number @retval None /void assert_failed(uint8_t file, uint32_t line){ / USER CODE BEGIN 6 / / User can add his own implementation to report the file name and line number, ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) / / USER CODE END 6 /}#endif / USE_FULL_ASSERT // (C) COPYRIGHT STMicroelectronics END OF FILE /
完全代码可进群免费领取。
嵌入式物联网的学习之路非常漫长,不少人由于学习路线不对或者学习内容不足专业而错失落高薪offer。不过别担心,我为大家整理了一份150多G的学习资源,基本上涵盖了嵌入式物联网学习的所有内容。点击下方链接,0元领取学习资源,让你的学习之路更加顺畅!
记得点赞、关注、收藏、转发哦!
点击这里找小助理0元领取:扫码进群领资料