STM32H750使用keil生成工程用来测量正弦波的频率和峰峰值,并输出到串口屏中
时间: 2023-12-06 08:42:40 浏览: 132
以下是基于Keil的STM32H750工程代码示例,实现测量正弦波的频率和峰峰值,并输出到串口屏中:
首先需要配置MCU的时钟,这里使用HSI时钟,时钟频率为64MHz:
```
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 64;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInitStruct.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
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_4) != HAL_OK)
{
Error_Handler();
}
```
然后需要配置串口,这里使用USART1,波特率为115200:
```
UART_HandleTypeDef huart1;
huart1.Instance = USART1;
huart1.Init.BaudRate = 115200;
huart1.Init.WordLength = UART_WORDLENGTH_8B;
huart1.Init.StopBits = UART_STOPBITS_1;
huart1.Init.Parity = UART_PARITY_NONE;
huart1.Init.Mode = UART_MODE_TX_RX;
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart1) != HAL_OK)
{
Error_Handler();
}
```
接下来是测量正弦波的部分,这里使用TIM2和ADC1:
```
#define ADC_BUFFER_SIZE 2048
#define PWM_FREQUENCY 1000
uint32_t adc_buffer[ADC_BUFFER_SIZE];
volatile uint32_t adc_buffer_index = 0;
volatile uint32_t adc_buffer_half_full = 0;
float frequency = 0;
float peak_to_peak = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2)
{
HAL_ADC_Start_IT(&hadc1);
}
}
void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc)
{
if (hadc->Instance == ADC1)
{
adc_buffer[adc_buffer_index++] = HAL_ADC_GetValue(hadc);
if (adc_buffer_index == ADC_BUFFER_SIZE)
{
adc_buffer_index = 0;
adc_buffer_half_full = 1;
}
}
}
void measure_frequency_and_peak_to_peak()
{
uint32_t i = 0;
float sum = 0;
float max = 0;
float min = 4096;
HAL_TIM_Base_Start_IT(&htim2);
HAL_ADC_Start_IT(&hadc1);
while (adc_buffer_half_full == 0);
HAL_TIM_Base_Stop_IT(&htim2);
for (i = 0; i < ADC_BUFFER_SIZE; i++)
{
sum += adc_buffer[i];
if (adc_buffer[i] > max)
{
max = adc_buffer[i];
}
if (adc_buffer[i] < min)
{
min = adc_buffer[i];
}
}
frequency = ((float)HAL_RCC_GetHCLKFreq() / (PWM_FREQUENCY * ADC_BUFFER_SIZE)) * 2;
peak_to_peak = ((float)(max - min) / 4096) * 3.3;
}
```
最后是输出到串口屏的部分,这里使用HAL库提供的UART发送函数,发送频率和峰峰值的值:
```
char message[64];
sprintf(message, "Frequency: %.2fHz\r\n", frequency);
HAL_UART_Transmit(&huart1, message, strlen(message), HAL_MAX_DELAY);
sprintf(message, "Peak-to-peak: %.2fV\r\n", peak_to_peak);
HAL_UART_Transmit(&huart1, message, strlen(message), HAL_MAX_DELAY);
```
完整的代码示例可以参考以下链接:https://github.com/Keenster/stm32h750-measure-sine-wave-frequency-and-peak-to-peak-value
阅读全文