天堂隔壁 发表于 2017-9-9 14:49:01

关于STM32L476时钟设置使得串口波特率加倍问题

如题,第一次玩STM32L476,从网上下载了1个串口例程,波特率设置9600后,没问题,然后自己配置时钟(使用外部有源晶振),输出时钟都一样,比特率设置9600后,实际波特率竟然是19200.。。 实在找不到问题了,下面是代码。屏蔽的部分是9600波特率正常,没屏蔽的是实际是19200.
void SystemClock_Config12(void)
{
        RCC_OscInitTypeDef RCC_OscInitStruct;
RCC_ClkInitTypeDef RCC_ClkInitStruct;
RCC_PeriphCLKInitTypeDef PeriphClkInit;

    /**Initializes the CPU, AHB and APB busses clocks
    */
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 10;
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(__FILE__, __LINE__);
}

    /**Initializes the CPU, AHB and APB busses clocks
    */

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(__FILE__, __LINE__);
}

PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
{
    _Error_Handler(__FILE__, __LINE__);
}


//        RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_MSI;
//RCC_OscInitStruct.MSIState = RCC_MSI_ON;
//RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
//        RCC_OscInitStruct.MSICalibrationValue = 0;
//RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
//RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
//RCC_OscInitStruct.PLL.PLLM = 1;
//RCC_OscInitStruct.PLL.PLLN = 40;
//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(__FILE__, __LINE__);
//}
//       
//        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(__FILE__, __LINE__);
//}

//PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USART1;
//PeriphClkInit.Usart1ClockSelection = RCC_USART1CLKSOURCE_PCLK2;
//if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
//{
//    _Error_Handler(__FILE__, __LINE__);
//}
}

す疯Ⅱ恒す 发表于 2018-1-19 09:08:30

不应该是先配置好时钟再去配置串口的么?我记得串口配置波特率里有用到当前的系统时钟,如果你配置串口时系统时钟的值时旧的,肯定是按旧的时钟达到9600,但是你后面又改了时间,串口又不知道,天知道波特率会变成怎么样。

morphlings2014 发表于 2018-1-19 09:50:14

我在使用的时候好像没这个问题。
你波特率不对。应该是时钟频率不对,原来配置的PCLK2是80M的,你先把时钟频率改成80M试试,
(HAL_RCC_MCOConfig(RCC_MCO1, RCC_MCO1SOURCE_SYSCLK, RCC_MCODIV_1);可以在PA8脚输出系统时钟波形,你可以看下是否是80M。)

大碗刚 发表于 2018-1-19 09:51:38

下图是STM32L476的时钟树,我觉得你需要先确定外部晶振的频率是多少MHz,之后分别配置系统时钟和AHB、APB时钟。注释的代码里有使用MSI时钟为系统时钟,也有选择HSE时钟为系统时钟,可能是这个产生的原因,可以修改试一试。

wenyangzeng 发表于 2018-1-19 09:52:15



如果外部晶振频率为8MHZ时,系统时钟的配置如下:

RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLM = 1;
RCC_OscInitStruct.PLL.PLLN = 20;
RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV7;
RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2;
RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2;


红色部分与楼主的配置有所不同

yu0405jie 发表于 2018-1-19 09:52:17

我建议在确认一遍时钟的计算是否正确,同时确认一下 oversampling的设置是16还是8,最好写进程序之后读寄存器,看寄存器的配置

队长shiwo 发表于 2018-1-19 10:02:33

时钟没设置对,可以使用CUBEMX来配置系统时钟和串口的时钟源,我都没遇到过波特率倍增的

Inc_brza 发表于 2018-1-19 10:06:56

百分百代码问题,楼主可以首先通过HAL的GetSystemClock获取当前的各个总线时钟,检查是否正确,
然后再配置一下你的串口模块即可!

无薪税绵 发表于 2018-1-19 14:13:03

屏蔽部分时钟使用的是MSI,
你的代码时钟使用的是HSE,
肯定是系统时钟 、或者时钟分频系数没有设置正确。
请仔细检查对应头文件中的定义。

wolfgang2015 发表于 2018-1-19 14:23:22

按顺时钟初始化顺序来,先初始化PPL及系统时钟,然后再使能AHBx的RCC,
注意看RCC_OSCILLATORTYPE_MSI 还是 RCC_OSCILLATORTYPE_HSE 一定要选择好基础震荡频率
页: [1] 2
查看完整版本: 关于STM32L476时钟设置使得串口波特率加倍问题