笔者在做毕业设计的时候遇到一个问题:
要通过与USART2相连的串口屏设置单片机USART1的波特率,在串口屏载入该页面的时候,需要呈现当前USART1的波特率,那么如何获取到波特率呢?
很容易想到的办法就是:根据串口初始化的函数顺藤摸瓜,找到写波特率的寄存器,然后把寄存器读出来就好了
然鹅:
/*---------------------------- USART BRR Configuration -----------------------*/
/* Configure the USART Baud Rate -------------------------------------------*/
RCC_GetClocksFreq(&RCC_ClocksStatus);
if (usartxbase == USART1_BASE)
{
apbclock = RCC_ClocksStatus.PCLK2_Frequency;
}
else
{
apbclock = RCC_ClocksStatus.PCLK1_Frequency;
}
/* Determine the integer part */
if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
{
/* Integer part computing in case Oversampling mode is 8 Samples */
integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));
}
else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
{
/* Integer part computing in case Oversampling mode is 16 Samples */
integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));
}
tmpreg = (integerdivider / 100) << 4;
/* Determine the fractional part */
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
/* Implement the fractional part in the register */
if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
{
tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
}
else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
{
tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
}
/* Write to USART BRR */
USARTx->BRR = (uint16_t)tmpreg;
虽然这里貌似计算方法很复杂的样子,其实也是能看出一些端倪的,不过,我们还是看手册吧。
资料1:
25.6.3 波特比率寄存器(USART_BRR)
注意: 如果 TE 或 RE 被分别禁止,波特计数器停止计数
地址偏移:0x08
复位值:0x0000
[tr][/tr]
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
保留 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
DIV_Mantissa[11:0] | DIV_Fraction[3:0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位31:16 | 保留位,硬件强制为0 |
位15:4 | DIV_Mantissa[11:0]:USARTDIV的整数部分 位15:4
这12位定义了USART分频器除法因子(USARTDIV)的整数部分。 |
位3:0 | DIV_Fraction[3:0]:USARTDIV的小数部分 位3:0
这4位定义了USART分频器除法因子(USARTDIV)的小数部分。 |
资料2:
表176 设置波特率时的误差计算
波特率 | fPCLK=36MHz | fPCLK=72MHz |
|
|
|
|
|
序号 | Kbps | 实际 | 置于波特率
寄存器中的值 | 误差% | 实际 | 置于波特率
寄存器中的值 | 误差% |
1 | 2.4 | 2.4 | 937.5 | 0% | 2.4 | 1875 | 0% |
2 | 9.6 | 9.6 | 234.375 | 0% | 9.6 | 468.75 | 0% |
3 | 19.2 | 19.2 | 117.1875 | 0% | 19.2 | 234.375 | 0% |
4 | 57.6 | 57.6 | 39.0625 | 0% | 57.6 | 78.125 | 0% |
5 | 115.2 | 115.384 | 19.5 | 0.15% | 115.2 | 39.0625 | 0% |
6 | 230.4 | 230.769 | 9.75 | 0.16% | 230.769 | 19.5 | 0.16% |
7 | 460.8 | 461.538 | 4.875 | 0.16% | 461.538 | 9.75 | 0.16% |
8 | 921.6 | 923.076 | 2.4375 | 0.16% | 923.076 | 4.875 | 0.16% |
9 | 2250 | 2250 | 1 | 0% | 2250 | 2 | 0% |
10 | 4500 | -- | -- | -- | 4500 | 1 | 0% |
资料3:
25.3.4 分数波特率的产生(节选)
接收器和发送器的波特率在USARTDIV的整数和小数寄存器中的值应设置成相同。
这里的 f CK 是给外设的时钟 (PCLK1 用于 USART2 、 3 、 4 、 5 , PCLK2 用于 USART1)
USARTDIV是一个无符号的定点数。这12位的值设置在USART_BRR寄存器
好了资料码完了
下面是计算过程:
首先,根据资料1,得到USARTDIV的整数部分,
即 DIV_Mantissa = (int)((USART1->BRR&0x0000ffff)>>4)
由于我要获取的是USART1的波特率,根据资料3可知,
则,根据资料2中表格第三栏 fPCLK=72MHz 中的 置于波特率寄存器中的值 与算得的 DIV_Mantissa 作比较,即可获得对应的波特率。
比如,算得 DIV_Mantissa=468,查表可知波特率为9.6Kbps即9600。
以上。
笔者在做毕业设计的时候遇到一个问题:
要通过与USART2相连的串口屏设置单片机USART1的波特率,在串口屏载入该页面的时候,需要呈现当前USART1的波特率,那么如何获取到波特率呢?
很容易想到的办法就是:根据串口初始化的函数顺藤摸瓜,找到写波特率的寄存器,然后把寄存器读出来就好了
然鹅:
/*---------------------------- USART BRR Configuration -----------------------*/
/* Configure the USART Baud Rate -------------------------------------------*/
RCC_GetClocksFreq(&RCC_ClocksStatus);
if (usartxbase == USART1_BASE)
{
apbclock = RCC_ClocksStatus.PCLK2_Frequency;
}
else
{
apbclock = RCC_ClocksStatus.PCLK1_Frequency;
}
/* Determine the integer part */
if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
{
/* Integer part computing in case Oversampling mode is 8 Samples */
integerdivider = ((25 * apbclock) / (2 * (USART_InitStruct->USART_BaudRate)));
}
else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
{
/* Integer part computing in case Oversampling mode is 16 Samples */
integerdivider = ((25 * apbclock) / (4 * (USART_InitStruct->USART_BaudRate)));
}
tmpreg = (integerdivider / 100) << 4;
/* Determine the fractional part */
fractionaldivider = integerdivider - (100 * (tmpreg >> 4));
/* Implement the fractional part in the register */
if ((USARTx->CR1 & CR1_OVER8_Set) != 0)
{
tmpreg |= ((((fractionaldivider * 8) + 50) / 100)) & ((uint8_t)0x07);
}
else /* if ((USARTx->CR1 & CR1_OVER8_Set) == 0) */
{
tmpreg |= ((((fractionaldivider * 16) + 50) / 100)) & ((uint8_t)0x0F);
}
/* Write to USART BRR */
USARTx->BRR = (uint16_t)tmpreg;
虽然这里貌似计算方法很复杂的样子,其实也是能看出一些端倪的,不过,我们还是看手册吧。
资料1:
25.6.3 波特比率寄存器(USART_BRR)
注意: 如果 TE 或 RE 被分别禁止,波特计数器停止计数
地址偏移:0x08
复位值:0x0000
[tr][/tr]
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 |
保留 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
DIV_Mantissa[11:0] | DIV_Fraction[3:0] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
位31:16 | 保留位,硬件强制为0 |
位15:4 | DIV_Mantissa[11:0]:USARTDIV的整数部分 位15:4
这12位定义了USART分频器除法因子(USARTDIV)的整数部分。 |
位3:0 | DIV_Fraction[3:0]:USARTDIV的小数部分 位3:0
这4位定义了USART分频器除法因子(USARTDIV)的小数部分。 |
资料2:
表176 设置波特率时的误差计算
波特率 | fPCLK=36MHz | fPCLK=72MHz |
|
|
|
|
|
序号 | Kbps | 实际 | 置于波特率
寄存器中的值 | 误差% | 实际 | 置于波特率
寄存器中的值 | 误差% |
1 | 2.4 | 2.4 | 937.5 | 0% | 2.4 | 1875 | 0% |
2 | 9.6 | 9.6 | 234.375 | 0% | 9.6 | 468.75 | 0% |
3 | 19.2 | 19.2 | 117.1875 | 0% | 19.2 | 234.375 | 0% |
4 | 57.6 | 57.6 | 39.0625 | 0% | 57.6 | 78.125 | 0% |
5 | 115.2 | 115.384 | 19.5 | 0.15% | 115.2 | 39.0625 | 0% |
6 | 230.4 | 230.769 | 9.75 | 0.16% | 230.769 | 19.5 | 0.16% |
7 | 460.8 | 461.538 | 4.875 | 0.16% | 461.538 | 9.75 | 0.16% |
8 | 921.6 | 923.076 | 2.4375 | 0.16% | 923.076 | 4.875 | 0.16% |
9 | 2250 | 2250 | 1 | 0% | 2250 | 2 | 0% |
10 | 4500 | -- | -- | -- | 4500 | 1 | 0% |
资料3:
25.3.4 分数波特率的产生(节选)
接收器和发送器的波特率在USARTDIV的整数和小数寄存器中的值应设置成相同。
这里的 f CK 是给外设的时钟 (PCLK1 用于 USART2 、 3 、 4 、 5 , PCLK2 用于 USART1)
USARTDIV是一个无符号的定点数。这12位的值设置在USART_BRR寄存器
好了资料码完了
下面是计算过程:
首先,根据资料1,得到USARTDIV的整数部分,
即 DIV_Mantissa = (int)((USART1->BRR&0x0000ffff)>>4)
由于我要获取的是USART1的波特率,根据资料3可知,
则,根据资料2中表格第三栏 fPCLK=72MHz 中的 置于波特率寄存器中的值 与算得的 DIV_Mantissa 作比较,即可获得对应的波特率。
比如,算得 DIV_Mantissa=468,查表可知波特率为9.6Kbps即9600。
以上。
举报