为什么随着 APB1 频率的变化,USART 传输的数据不正确.(RCC <= 21MHz) [英] Why USART transmits incorrect data as the APB1 frequency changes. (RCC &lt;= 21MHz)

查看:36
本文介绍了为什么随着 APB1 频率的变化,USART 传输的数据不正确.(RCC <= 21MHz)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在我的项目中使用 USART 通信协议.提供了通信,但发送了错误数据(STM> PC).

I want to use the USART communication protocol in my project. Communication is provided but incorrect data is sent (STM> PC).

我会尝试:

  1. 边界带相同.

  1. Boundrade bands are the same.

测试了 PLL 源多路复用器 (HSI-HSE) 和系统时钟多路复用器 (HSI-HSE-PLLCLK) 的合适组合.可用:HSE 和 PLLCLK

Suitable combinations of PLL Source Mux (HSI-HSE) and System Clock Mux (HSI-HSE-PLLCLK) were tested. Available: HSE and PLLCLK

APB1 时钟频率在允许范围内改变.观察到在每次变化时获得的数据也发生了变化.有时 STM 发送的数据非常快.

APB1 Clock frequency was changed within the allowed range. It was observed that the data obtained at each change also changed. Sometimes STM sent very fast data.

STM 卡从不同的源馈电,并通过接地均衡测试.

The STM card was fed from a different source and tested by ground equalization.

注 1:代码不包括整个项目.在这种情况下,我提到的问题就出现了.

Note-1: Codes do not include the entire project. In this case, the problem that I mentioned occurs.

#include "main.h"
#include "spi.h"
#include "tim.h"
#include "usart.h"
#include "gpio.h"
#include "stm32f4xx_hal.h"
#include "defines.h"
#include "tm_stm32_disco.h"
#include "tm_stm32_delay.h"
#include "tm_stm32_lis302dl_lis3dsh.h"
#include "stm32f4xx.h"  
#include "arm_math.h"
#define PID_PARAM_KP        100 
#define PID_PARAM_KI        0.025
#define PID_PARAM_KD        0   

float pid_error;

extern UART_HandleTypeDef huart1;

char* bufftr="Hello\n\r";

void SystemClock_Config(void);
void Error_Handler(void);
static void MX_GPIO_Init(void);
static void MX_USART1_UART_Init(void);

int main(void)
{
    HAL_Init();
    SystemClock_Config();
    TM_LIS302DL_LIS3DSH_t Axes_Data;

    MX_GPIO_Init();
    MX_TIM1_Init();
    MX_SPI1_Init();
    MX_USART1_UART_Init();

    __HAL_UART_ENABLE_IT(&huart1, UART_IT_TC);
    HAL_TIM_PWM_Start(&htim1, TIM_CHANNEL_2);

    SystemInit();
    TM_DELAY_Init();
    TM_DISCO_LedInit();

    if (TM_LIS302DL_LIS3DSH_Detect() == TM_LIS302DL_LIS3DSH_Device_LIS302DL) {
        TM_DISCO_LedOn(LED_GREEN | LED_RED);
        TM_LIS302DL_LIS3DSH_Init(TM_LIS302DL_Sensitivity_2_3G, TM_LIS302DL_Filter_2Hz);
    } else if (TM_LIS302DL_LIS3DSH_Detect() == TM_LIS302DL_LIS3DSH_Device_LIS3DSH) {
        TM_DISCO_LedOn(LED_BLUE | LED_ORANGE);
        TM_LIS302DL_LIS3DSH_Init(TM_LIS3DSH_Sensitivity_2G, TM_LIS3DSH_Filter_800Hz);
    } else {
        TM_DISCO_LedOn(LED_GREEN | LED_RED | LED_BLUE | LED_ORANGE);
        while (1);
    }   

    Delayms(300);
    TM_DISCO_LedOff(LED_ORANGE);
    TM_DISCO_LedOff(LED_BLUE);

    arm_pid_instance_f32 PID;
    PID.Kp = PID_PARAM_KP;
    PID.Ki = PID_PARAM_KI;
    PID.Kd = PID_PARAM_KD;
    arm_pid_init_f32(&PID, 1);


    TM_GPIO_SetPinLow(GPIOD, GPIO_Pin_12);
    TM_GPIO_SetPinLow(GPIOD, GPIO_Pin_14);  

    while (1){
        HAL_UART_Transmit_IT(&huart1, (uint8_t *)bufftr, 8);
        HAL_Delay(500);
    }

    void SystemClock_Config(void){
    RCC_OscInitTypeDef RCC_OscInitStruct = {0};
    RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};

    __HAL_RCC_PWR_CLK_ENABLE();
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);

    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
    RCC_OscInitStruct.HSEState = RCC_HSE_ON;
    RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
    RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
    RCC_OscInitStruct.PLL.PLLM = 4;
    RCC_OscInitStruct.PLL.PLLN = 168;
    RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
    RCC_OscInitStruct.PLL.PLLQ = 4;

    if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != 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_DIV4;
    RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;

    if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK){
        Error_Handler();
    }
}
static void MX_USART1_UART_Init(void){
    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();
    }
}
static void MX_GPIO_Init(void){
    __HAL_RCC_GPIOH_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
}
void Error_Handler(void){

}
#ifdef  USE_FULL_ASSERT
void assert_failed(uint8_t *file, uint32_t line){ 

}
#endif

注意-2:在所有条件都相同的情况下,创建并运行仅包含 USART 的项目时不会出现此问题.

Note-2: The problem does not occur when I create and run a project containing only USART when all the conditions are the same.

注 3:我没有收到任何错误消息或警告消息.

Note-3: I do not receive any error messages or warning messages.

推荐答案

SystemInit() 只应在重置处理程序中调用

SystemInit() should be called in the reset handler only

该函数应该将系统时钟重置为默认状态,直接从 HSI 以 16 MHz 运行.

This function is supposed to reset the system clock to a default state, running directly from HSI at 16 MHz.

您在 main() 中间调用它,此时 USART1 已经配置为假设更高的时钟速度.不知道外设在动态更改时钟源时会做什么.

You are calling it in the middle of main(), when USART1 is already configured assuming a higher clock speed. There is no telling what the peripheral would do when its clock source is changed on the fly.

这篇关于为什么随着 APB1 频率的变化,USART 传输的数据不正确.(RCC <= 21MHz)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆