在main中调用的 Stm32_Clock_Init(336, 8, 2, 7); /* 设置时钟,168Mhz *///8*336/8/2=168
时钟源,PLL寄存器配置函数:
HAL_StatusTypeDef HAL_RCC_OscConfig(RCC_OscInitTypeDef *RCC_OscInitStruct)
系统时钟,总线寄存器配置,及HCLK时钟计算函数:
HAL_StatusTypeDef HAL_RCC_ClockConfig(RCC_ClkInitTypeDef *RCC_ClkInitStruct, uint32_t FLatency)
计算系统时钟函数:
串口波特率配置:
在main中调用的:usart_init(9600); /* 串口初始化为波特率 */
串口寄存器配置:
HCLK时钟是系统时钟不分频168 M,PCLK时钟2分频84M:
比特率寄存器配置部分: (小数部分的高4位和低4位组合?小数部分大于0.96会进位--在位4加1)
算法模拟(注释):
// UARTBRR.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
double sj(uint64_t a, uint64_t b);
//U1---USARTDIV是串口实际分频值--小数点后移两位(值扩大100倍)
//U2---再除100,其实还是取整---
//U3---U1(p, b) - (U2(p, b) * 100U)取扩大100倍的小数部分,
// * 16U左移4位--以整数的形式把小数放在低四位---加50除100,就是加0.5,取整实现四舍五入
#define U1(p, b) (p*25U)/(4U*b) //USARTDIV=Pck/(16*Baud)取到小数点后(移)两位--->USARTDIV*100=(Pck*100)/(16*Baud)= (p*25U)/(4U*b)
#define U2(p, b) (U1(p, b)/100U)
//#define U3(p, b) ((((U1(p, b) - (U2(p, b) * 100U)) * 16U) + 50U) / 100U)
#define U3(p, b) ((((U1(p, b) - (U2(p, b) * 100U)) * 16U) + 50U) / 100U)
int main()
{
uint64_t pc = 84000000, ba = 9600;
uint32_t u3;
uint32_t u1;
uint32_t u2;
uint32_t d;
d = sj(pc, ba);
u3 = U3(pc, ba);
u1 = U1(pc, ba);
u2 = U2(pc, ba);
std::cout << u1 << "\n" << u2 << "\n";
std::cout << d << "--" << u3 <<"\n";
return 0;
}
double sj(uint64_t a, uint64_t b)
{
return(U1(a, b) - (U2(a, b) * 100));
}
// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单
运行结果:
参考资料:
F4 16倍过采样和F1等同: