3

我是嵌入式系统的初学者。我正在尝试在 STM32F103C8(即Blue Pill板)的 UART2 上写入数据,并希望使用连接到STM32F103C8 板的UART2的FTDI适配器在我的计算机的一个端口中查看数据。但是在我的控制台上,我收到了一些随机的方块,而不是我想要传输的字符。

这是我用Keil IDE编写的代码。

#include "stm32f10x.h"                  // Device header

void usart2_init(void);
void USART_write(int data);
void delayMs(int delay);

int main(void)
{
    usart2_init();
    while(1)
    {
       USART_write('A');
       delayMs(5000);
    }
}

void usart2_init(void)
{
       // Enable clock source for USART2
       RCC->APB1ENR |= 0x20000;           // 0b 0000 0000 0000 0010 0000 0000 0000 0000
       RCC->APB2ENR |= 0x4;
       GPIOA->CRL |= 0x900;               // Set PA2 as TX pin (AF)
       USART2->BRR  = 0x341;              // Setting Baudrate to 9600 @8 MHz.
       USART2->CR1 |= 0x00008;            // Enable TX only
       USART2->CR1 |= 0x02000;            // Enable USART module by setting bit 13 to 1 i
       USART->CR1 register
}

void USART_write(int data)
{
    // We need to wait until Tx buffer is empty for sending data.
    while(!(USART2->SR & 0x0080));        // 0x0080
    USART2->DR = (data & 0xFF);
}

void delayMs(int delay)
{
    int i;
    for( ; delay>0 ; delay--)
    {
        for(i=0; i<3195; i++)
        {
        }
    }
}

下面我在调试时附上了截图。

点击这里查看截图

您可以看到不需要的方块而不是字符而不是我要传输的字符。在图像中,您还可以看到 UART 寄存器及其值。我正在使用ST-LINK2上传固件。

在处理 FTDI 和Tera Term时,我是否遗漏了一些信息或犯了一些错误?这是我的 Tera Term 配置:

  • 波特率 = 9600
  • 数据 = 8 位
  • 奇偶校验 = 无
  • 停止位 = 1
  • 控制流 = 无

我怎样才能解决这个问题?

4

2 回答 2

1

使用这些设备时,您应该仔细阅读数据表/参考手册以及生产商网站上广泛提供的可能适用的 AN(应用说明)。

在特定情况下,STM32F10x 系列通常使用由内部 PLL 振荡器生成的 72 MHz 系统时钟工作,该振荡器使用外部晶体,在 Blue Pill 上的频率为 8 MHz,作为 PLL(锁相环)的参考控制它的电路。8 MHz 晶振称为 HSE,代表高速外部振荡器。

我说“一般”是因为用户可以通过对特定的预分频器和内部时钟电路进行编程来选择不同的系统时钟频率,乍一看(甚至第二眼……)这可能会变得非常复杂。

现在假设外设接口采用标准配置,其中系统时钟选择为 72 MHz,AHB 预分频器为 1,两个外设时钟 (PCLCKx) 设置为 36 MHz (PCLCK1:预分频器 = 2) 和 72 MHz (PCLCK2) , 分别。

在 STM32F10x 芯片上,只有 USART1 的时钟来自 PCLCK2,所有其他的时钟来自 PCKLK1(最大 36 MHz)。

因此,您的设备可能主频为 36 MHz。要获得 9600 波特率,我们需要36 MHz / (9600 * 16) = 234.375的整体除数。

波特率发生器可以通过分别考虑整数和小数部分来处理小数除法。我们得到:

DIV_Fraction = 16 * 0.375 = 6 = 0x06
DIV_Mantissa = 234 = 0xEA
USART_BRR = (DIV_Mantissa << 4) | DIV_Fraction = 0xEA6

该符号0dxx取自 ST 文档,代表十进制表示。

结论

要在这些设备上进行操作,请在开始编程之前仔细阅读文档,如果可能,请使用帮助库。我个人更喜欢libopencm3而不是标准的 HAL 库,这简化了使用。

于 2020-05-01T10:54:14.437 回答
0

这行得通,我测试过

void init_Usart(void)
{
  // Enable clock source for USART2
  RCC->APB1ENR |= 0x20000;           // 0b 0000 0000 0000 0010 0000 0000 0000 0000
  RCC->APB2ENR |= 0x4;
  GPIOA->CRL |= 0x900;               // Set PA2 as TX pin (AF)
  USART2->BRR  = 0xEA6;              // Setting Baudrate to 9600 @8 MHz.
  USART2->CR1 |= 0x00008;            // Enable TX only
  USART2->CR1 |= 0x02000;            // Enable USART module 
   
}

void USART_write(int data)
{
  // We need to wait until Tx buffer is empty for sending data.
  while(!(USART2->SR & 0x0080));        // 0x0080
  USART2->DR = (data & 0xFF);
}
于 2021-04-25T13:51:23.663 回答