STM32H750通过stm32cubemx使用keil生成工程用来测量正弦波的频率和峰峰值,并输出到串口屏中
时间: 2023-12-06 18:42:35 浏览: 41
好的,下面我给你提供一个大致的步骤:
1. 打开STM32CubeMX,选择你的芯片型号STM32H750,然后创建一个新工程。
2. 在Pinout & Configuration选项卡中,配置你的IO口。比如,如果你需要测量正弦波的频率和峰峰值,你需要将正弦波信号连接到定时器的输入捕获通道上,将串口屏连接到UART口上。
3. 在Clock Configuration选项卡中,配置你的时钟源,包括CPU时钟、APB总线时钟和定时器时钟等。
4. 在Project Manager选项卡中,生成代码并选择Keil MDK-ARM作为IDE。
5. 打开Keil MDK-ARM,使用File->Open Project打开生成的工程文件。
6. 在工程文件中,打开main.c文件。在该文件中,你需要使用定时器的输入捕获功能来测量正弦波的频率和峰峰值,并使用串口输出到屏幕上。
7. 使用HAL库函数编写代码,实现输入捕获功能和串口输出功能。在输入捕获中,你需要启动定时器,然后在定时器到达一定时间后捕获信号,计算频率和峰峰值。在串口输出中,你需要使用HAL库函数将数据发送到串口屏上。
8. 编译代码并下载到STM32H750芯片中,然后连接正弦波信号和串口屏,启动程序即可。
希望这些步骤能够帮助到你,祝你好运!
相关问题
STM32H750通过stm32cubemx使用keil生成工程用来测量正弦波的频率和峰峰值,并输出到串口屏中,给出代码
以下是使用STM32CubeMX和Keil编写的代码,可以测量正弦波的频率和峰峰值,并输出到串口屏幕中。
首先,我们需要在STM32CubeMX中配置外设和时钟。假设我们使用的是PA0引脚来输入正弦波信号,PA9和PA10引脚来作为串口1的TX和RX引脚。
1. 在Pinout & Configuration选项卡中,将PA0设置为GPIO输入模式。
2. 在Configuration选项卡中,启用USART1,并将其配置为115200波特率,8位数据位,无校验位和1个停止位。
3. 在Clock Configuration选项卡中,将系统时钟设置为480MHz。
接下来,在Keil中创建一个新的STM32CubeMX工程,并将生成的代码导入到工程中。然后,我们可以开始编写代码了。
首先,我们需要定义一些全局变量来存储正弦波的状态和测量结果:
```c
#define SAMPLE_SIZE 2048 // 采样点数
uint32_t adc_buf[SAMPLE_SIZE]; // 用于存储ADC采样结果
float adc_voltage[SAMPLE_SIZE]; // 用于存储ADC采样电压值
// 正弦波状态
struct sin_wave {
uint8_t index;
float freq;
float peak;
} sin;
// 测量结果
struct result {
float freq;
float peak;
} res;
```
然后,我们需要编写一些函数来初始化ADC和串口,并启动ADC转换:
```c
void init_adc() {
// 启用ADC时钟和GPIO时钟
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_ADC3_CLK_ENABLE();
// 配置PA0为模拟输入
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_0;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置ADC
ADC_HandleTypeDef hadc3 = {0};
hadc3.Instance = ADC3;
hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV4;
hadc3.Init.Resolution = ADC_RESOLUTION_12B;
hadc3.Init.ScanConvMode = DISABLE;
hadc3.Init.ContinuousConvMode = ENABLE;
hadc3.Init.DiscontinuousConvMode = DISABLE;
hadc3.Init.NbrOfDiscConversion = 0;
hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
hadc3.Init.ExternalTrigConv = ADC_EXTERNALTRIGCONV_T1_CC1;
hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
hadc3.Init.NbrOfConversion = 1;
hadc3.Init.DMAContinuousRequests = DISABLE;
hadc3.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
HAL_ADC_Init(&hadc3);
// 配置ADC通道
ADC_ChannelConfTypeDef sConfig = {0};
sConfig.Channel = ADC_CHANNEL_0;
sConfig.Rank = ADC_REGULAR_RANK_1;
sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;
sConfig.SingleDiff = ADC_SINGLE_ENDED;
sConfig.OffsetNumber = ADC_OFFSET_NONE;
sConfig.Offset = 0;
HAL_ADC_ConfigChannel(&hadc3, &sConfig);
// 启动ADC转换
HAL_ADC_Start(&hadc3);
}
void init_uart() {
// 启用USART和GPIO时钟
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
// 配置PA9和PA10为USART1的TX和RX引脚
GPIO_InitTypeDef GPIO_InitStruct = {0};
GPIO_InitStruct.Pin = GPIO_PIN_9 | GPIO_PIN_10;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART1;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
// 配置USART
USART_HandleTypeDef huart1 = {0};
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;
HAL_UART_Init(&huart1);
}
void start_conversion() {
HAL_ADC_Start_DMA(&hadc3, (uint32_t *)adc_buf, SAMPLE_SIZE);
}
```
接下来,我们需要编写一个函数来计算正弦波的频率和峰峰值:
```c
void calc_sin_wave() {
// 计算峰峰值
float max = -INFINITY;
float min = INFINITY;
for (int i = 0; i < SAMPLE_SIZE; i++) {
float voltage = adc_voltage[i];
if (voltage > max) {
max = voltage;
}
if (voltage < min) {
min = voltage;
}
}
sin.peak = max - min;
// 计算频率
float delta = 0;
int index = 0;
for (int i = 0; i < SAMPLE_SIZE; i++) {
float voltage = adc_voltage[i];
if (voltage > 0 && adc_voltage[i-1] < 0) {
delta = i - index;
index = i;
break;
}
}
sin.freq = 1.0 / (delta * (1.0 / 480000));
}
```
最后,我们需要编写一个主函数来循环读取ADC转换结果,并周期性地输出测量结果到串口屏幕:
```c
int main(void) {
HAL_Init();
init_adc();
init_uart();
start_conversion();
// 初始化正弦波状态
sin.index = 0;
sin.freq = 50;
sin.peak = 0;
// 主循环
while (1) {
// 计算ADC采样电压
for (int i = 0; i < SAMPLE_SIZE; i++) {
adc_voltage[i] = adc_buf[i] * 3.3 / 4096;
}
// 计算正弦波状态
calc_sin_wave();
// 输出测量结果到串口屏幕
if (sin.index == 0) {
res.freq = sin.freq;
res.peak = sin.peak;
char buffer[64];
sprintf(buffer, "Freq: %.2f Hz, Peak: %.2f V\n", res.freq, res.peak);
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, strlen(buffer), 1000);
}
// 更新正弦波状态
sin.index++;
if (sin.index >= SAMPLE_SIZE) {
sin.index = 0;
}
// 延时一段时间,以降低CPU负载
HAL_Delay(10);
}
}
```
这样,我们就完成了使用STM32H750测量正弦波的频率和峰峰值,并输出到串口屏幕的代码。
STM32H750使用keil生成工程用来测量正弦波的频率和峰峰值,并输出到串口屏中
以下是基于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