Здравствуйте, столкнулся с проблемой. Скажу сразу, я не первый день над её разрешением думаю, всё перепробовал и только сейчас решил обратиться сюда - может кто-нибудь и сталкивался.
Дело в чём: хочу организовать обмен данными по COM-порту на STM32-VLDiscovery (в основе данной отладочной платы лежит STM32F100RB). Ну ок, прочитал необходимые разделы в Reference Manual, посмотрел примеры в интернете и решил делать. Сначала пошёл лёгким путём, решив отправлять один символ с микроконтроллера через небольшие промежутки времени (ну а потом организовал бы полноценный обмен). Использую keil uvision5. Написал программу с использованием библиотеки STDPeriph. Написал. Он присылает - но не те символы. Решил найти, в чём проблема, не нашёл. Решив, что во всём виновата библиотека

- полез в референс мануал с описанием регистров порта ввода/вывода и USART. Написал программу, без использования STDPeriph (её код ниже). Результат - тот же.
Ну и решил искать, в чём проблема. Первая мысль - то, что baudrate не тот. Измерил частоту SYSCLK - 24 МГц, потом решил строго установить делители частоты для шин AHB (крепится к SYSCLK) и APB2 (на ней висят GPIOA(PA9 у данного порта - передатчик USART) и USART1). Ставил на эту шину и 24 МГц, и 6 МГц - результат тот же. Решил измерить выходной бодрейт с помощью осциллографа

- тут тоже всё нормально. Потом подумал, что во всём виновата терминальная программа на компе, поставил другую - не то, не в этом проблема. Далее решил, что переходник RS232-USB виноват. Проверил его дрова - всё норм, винда сама не ставила те, которые захотела, на всякий случай соединил RX с TX у переходника - работает на славу, принимает и передаёт. Также я ковырялся в коде, меняя стоп-биты, флаги, по которым идёт проверка, что регистр данных пуст - никакого результата. Стабильно выдаёт одни символы вместо других. Причём строго - вместо "a" выдаёт "O", вместо "2" выдаёт "6", вместо "b" выдаёт кавычку (0x27). В чём проблема - никак не пойму. Были мысли, что шум и т.д., надо организовывать проверку чётности, например. Но тут бодрейт - 9600, какие на этом бодрейте могут быть ошибки? Ещё не уверен, но может быть играет роль то, что отладочная плата питается от USB? но что-то не верится. Тогда сам микроконтроллер криво бы работал, а помигать светодиодом он всегда соглашался без проблем.
Код приведён ниже.
Код
#include "stm32f10x.h" // Device header
void delay(long x);
void initial(void);
int main(void)
{
uint8_t data;
initial();
data = 0x62;
while(1)
{
if(USART1->SR & USART_SR_TC)
USART1->DR=data;
delay(5000000);
}
}
void initial(void)
{
//AHB, APB2 clock configuration
RCC->CFGR &=~RCC_CFGR_HPRE;
RCC->CFGR |=RCC_CFGR_HPRE_DIV1;
RCC->CFGR &=~RCC_CFGR_PPRE2;
RCC->CFGR |=RCC_CFGR_PPRE2_DIV1; //APB2 clock value = 24MHz
RCC->APB2ENR|=RCC_APB2ENR_IOPAEN; //GPIOA clock enable
GPIOA->CRH &=~GPIO_CRH_MODE9;
GPIOA->CRH |= GPIO_CRH_MODE9_1 | GPIO_CRH_MODE9_0; //Output mode, max speed 50 MHz
GPIOA->CRH &= ~GPIO_CRH_CNF9;
GPIOA->CRH |= GPIO_CRH_CNF9_1; //Alternate function output Push-pull
RCC->APB2ENR|=RCC_APB2ENR_USART1EN; //USART1 clock enable
USART1->CR1 |= USART_CR1_UE; //USART1 enable
USART1->CR1 &= ~USART_CR1_M; //1 start bit, 8 bits of data
USART1->CR2 &= ~USART_CR2_STOP; //1 stop bit
USART1->CR1 &= ~USART_CR1_PCE; //Parity control disabled
USART1->CR3 &= ~USART_CR3_RTSE; //RTS hardware flow control disabled
USART1->CR3 &= ~USART_CR3_CTSE; //CTS hardware flow control disabled
USART1->BRR=0x9C4; //0x9C4 - 9600 baudrate for 24 MHz of APB2
USART1->CR1 |= USART_CR1_TE; //Transmitter enable
}
void delay(long x)
{
long i;
for(i=0;i<x;i++);
}
Ещё момент - решил измерять побитно, что должно быть записано в микроконтроллер, что выдаёт осциллограф, подключённый к выводу передатчика USART и что получаем в программе терминала на компьютере.
Символ "а":
микроконтроллер: 01100001
осциллограф: 10000110
терминал: 01001111
Символ "2":
микроконтроллер: 00110010
осциллограф: 01100100
терминал: 00110110
Символ "b":
микроконтроллер: 01100010
осциллограф: 01000110
терминал: 00100111
Какой-то связи между вышеуказанными двоичными числами, я не вижу. И это меня вообще в тупик ставит.