Проблема с передачей данных через UART в STM32F103C8 ('Blue Pill')

Я новичок во встраиваемых системах. Я пытаюсь записать данные на UART2 STM32F103C8 (т. Е. синий Таблетка) и хотите видеть данные в одном из портов моего компьютера с помощью адаптера FTDI, который подключен к UART2 устройства плата STM32F103C8. Но на своей консоли я получаю какой-то случайный квадратный блок вместо символа, который хочу передать.

Вот мой код, написанный в IDE Keil.

#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
  • Поток управления = нет

Как я могу это исправить?


person Tushar Yadav    schedule 30.04.2020    source источник
comment
Случайный квадратный блок звучит как непечатный символ. Напечатайте шестнадцатеричное значение байта, а не байта, и я уверен, что оно меньше 0x20 или больше 126   -  person Code Gorilla    schedule 30.04.2020
comment
Неправильная установка BRR (Регистр скорости передачи). Этот регистр содержит 12-битный делитель и 4-битный дробный делитель. Другая ошибка: частота для периферийного устройства usart составляет 36 МГц, а не 8 МГц. Для правильных настроек получите копию руководства STM32F10X и найдите значения в таблице 192. Или просто используйте libopencm3, очень простую в использовании.   -  person Frankie_C    schedule 30.04.2020
comment
Привет, @Frankie_C, спасибо за помощь. Мой код работает на частоте 36MHz.   -  person Tushar Yadav    schedule 01.05.2020
comment
Пожалуйста. Имейте в виду, что эти устройства настолько же гибки, насколько сложны в программировании. Не предполагайте ничего и всегда внимательно читайте таблицы данных. Google для libopencm3, это может быть большим подспорьем, я предпочитаю его собственной разработке HAL для STM.   -  person Frankie_C    schedule 01.05.2020


Ответы (2)


При работе с этими устройствами вы должны внимательно прочитать таблицы данных / справочные руководства и, возможно, применимые AN (заметки по применению), широко доступные на сайте производителя.

В конкретном случае семейство STM32F10x работает обычно с системными часами 72 МГц, генерируемыми внутренним генератором ФАПЧ, который использует внешний кристалл с частотой 8 МГц на Blue Pill в качестве эталона для Схема ФАПЧ, которая им управляет. Кварцевый генератор 8 МГц называется HSE, что означает высокоскоростной внешний генератор.

Я сказал «в целом», потому что пользователь может выбрать разные системные тактовые частоты, запрограммировав определенные предварительные делители частоты и схему внутренних тактовых импульсов, что на первый взгляд может стать очень сложным (и даже на второй…).

Теперь, предполагая стандартную конфигурацию периферийных интерфейсов, где системные часы выбраны на 72 МГц, а предварительный делитель AHB на 1, две периферийные часы (PCLCKx) установлены на 36 МГц (PCLCK1: предварительный делитель = 2) и 72 МГц (PCLCK2). , соответственно.

На чипах STM32F10x только USART1 синхронизируется с PCLCK2, а все остальные синхронизируются с PCKLK1 (максимум 36 МГц).

Итак, ваше устройство предположительно работает на частоте 36 МГц. Чтобы иметь скорость 9600 бод, нам нужен общий делитель 36 МГц / (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, что упрощает использование.

person Frankie_C    schedule 01.05.2020
comment
хороший ответ! - Голосовать за. - Я позволил себе отполировать некоторые моменты вашего описания. Пожалуйста, проверьте, согласны ли вы с этой новой формулировкой. - person HelpingHand; 02.05.2020
comment
@HelpingHand Спасибо. Я одобрил правку. По сути, я написал ответ на каком-то английском ... - person Frankie_C; 02.05.2020

это будет работать человек, я проверил это

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);
}
person Eldho Abraham    schedule 25.04.2021