Cимволы при передаче по USART с платы STM32F3Discovery

Кто любит RISC в жизни, заходим, не стесняемся.
Ответить
DDenisov
Родился
Сообщения: 13
Зарегистрирован: Вс июл 03, 2016 17:16:23

Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение DDenisov »

Пытаюсь освоить передачу данных с контроллера при помощи USART. Код посимвольно посылает слово "Hello!".

Код: Выделить всё

#include "stm32f3xx.h"		// Device header.
#include "stdio.h"				// Библиотека стандартного ввода-вывода (ANSI C).
#include "string.h"				// Строки (ANSI C).

void UART3_init()
{
	// Настройка UART.
	RCC->APB1ENR |= RCC_APB1ENR_USART3EN;				// Запуск тактового генератора USART3.
	USART3->BRR = 0x9c4;												// Установка требуемой скорости.
	USART3->CR1 |= USART_CR1_UE;								// Включить передатчик USART.
	USART3->CR1 |= USART_CR1_TE;								// Включение передатчика.
	RCC->AHBENR |= RCC_AHBENR_GPIOBEN;					// Включить тактовый генератор порта.
	// Настройка выводов порта (альтернативная функция).
	GPIOB->MODER |= GPIO_MODER_MODER10_1;
	// Установка альтернативной функции USART3_TX.
	GPIOB->AFR[1] |= 0x00000700;
}

// Передача байта данных.
void UART3_TX_byte(char byte)
{
	// Ждем готовность регистра TDR к приему (Transmission Complete).
	while(!(USART3->ISR & USART_ISR_TC)) {};
	USART3->TDR = byte; 												// Передача байта.
}



int main(void)
{
		unsigned long int i;
	  UART3_init(); // Инициализация UART3
    UART3_TX_byte('H');
    UART3_TX_byte('E');
	  UART3_TX_byte('L');
    UART3_TX_byte('L');
	  UART3_TX_byte('O');
    UART3_TX_byte('!');
		//for(i = 0; i < 0xFFFFF; i++) {} // Пауза.
}
При срабатывании кода на виртуальный COM-порт приходят такие данные:

Изображение

Я ожидал, что будут отображаться символы слова "HELLO!". Этого не происходит. При включении кнопки ASCII на экране данных пусто. Кроме того, например, буква H имеет код 48. В принятых данных не то и отсутствуют повторяющиеся буквы L.

Пробовал ставить пауза между инициализацией и отправкой каждого символа. Заметил, что 1C 00 FC приходят разом, три байта.

Почему приходит по два-три байта, если я отправляю char? Можно ли сделать так, чтобы программа Terminal отображала символы?

Проект Keil uVision
MyUART.zip
Проект Keil uVision
(321.11 КБ) 252 скачивания
Добавлено after 3 hours 35 minutes 57 seconds:
Исправил код в части установки скорости. Подбирал методом тыка. Теперь почти работает. Иногда почему-то одну букву пишет неправильно.

Код: Выделить всё

#include "stm32f3xx.h"		// Device header.
#include "stdio.h"				// Библиотека стандартного ввода-вывода (ANSI C).
#include "string.h"				// Строки (ANSI C).

void UART3_init()
{
	// Настройка UART.
	RCC->APB1ENR |= RCC_APB1ENR_USART3EN;				// Запуск тактового генератора USART3.
	USART3->BRR = 8000000L/9600;												// Установка требуемой скорости.
	USART3->CR1 |= USART_CR1_UE;								// Включить передатчик USART.
	USART3->CR1 |= USART_CR1_TE;								// Включение передатчика.
	RCC->AHBENR |= RCC_AHBENR_GPIOBEN;					// Включить тактовый генератор порта.
	// Настройка выводов порта (альтернативная функция).
	GPIOB->MODER |= GPIO_MODER_MODER10_1;
	// Установка альтернативной функции USART3_TX.
	GPIOB->AFR[1] |= 0x00000700;
}

// Передача байта данных.
void UART3_TX_byte(char byte)
{
	// Ждем готовность регистра TDR к приему (Transmission Complete).
	while(!(USART3->ISR & USART_ISR_TC)) {};
	USART3->TDR = byte; 												// Передача байта.
}



int main(void)
{
		unsigned long int i;
	  UART3_init(); // Инициализация UART3
		for(i = 0; i < 0xFFFFF; i++) {} // Пауза.
    UART3_TX_byte('H');
		for(i = 0; i < 0xFFFFF; i++) {} // Пауза.
    UART3_TX_byte('E');
		for(i = 0; i < 0xFFFFF; i++) {} // Пауза.
	  UART3_TX_byte('L');
		for(i = 0; i < 0xFFFFF; i++) {} // Пауза.
    UART3_TX_byte('L');
		for(i = 0; i < 0xFFFFF; i++) {} // Пауза.
	  UART3_TX_byte('O');
		for(i = 0; i < 0xFFFFF; i++) {} // Пауза.
    UART3_TX_byte('!');
		
}
Изображение

Появился ещё вопрос. Верно ли я понимаю, что частота передачи данных соответствует частоте работы порта?

Добавлено after 27 minutes 13 seconds:
Заменил самодельный кабель на короткие китайские перемычки для Ардуино. Работает. Буквы не теряются. Видимо, длинный кабель нельзя. Я для удобства сделал 700 мм примерно в длину. И он заглючил. Приложил код, может кому пригодится.
Вложения
MyUART.zip
(321.17 КБ) 273 скачивания
Реклама
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение AlanDrakes »

Мама дорогая...
Вы что курили, что начали ЗАДЕРЖКАМИ делать паузы между символами?
Обычно ожидание готовности переферии выполняется проверкой регистра-статуса (USART3->SR). Это если решать проблему в лоб.
Иначе - это ожидание выносится в функцию передачи.
Далее. Может, отправлять сразу строку?
void USART_Send(char *s) {
while(*s) {
USART3_SendChar(*s);
s++;
};
};
Всё. Вся функция.
Отправляем, естественно, так:
USART_Send("Hello World!");
Ну и USART3_SendChar:
void USART3_SendChar(char c) {
USART3->DR = c;
while (!(USART3->SR & USART_SR_TC)) {};
};
};
Реклама
DDenisov
Родился
Сообщения: 13
Зарегистрирован: Вс июл 03, 2016 17:16:23

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение DDenisov »

А паузы-то я просто не убрал. Добавил их, когда не знал, что проблема в скорости передачи. В терминал тогда шел набор кракозябров и чтобы их отличать по времени появления и сравнить, я сделал паузы. Выяснилось что приходило по два байта или по три. То что готовность периферии проверяется специально предназначенными регистрами это понятно.

Про строку ясно тоже. Я так и сделаю. Хотел код попроще, пока он не работал.

Вопрос вот какой остался. Какую частоту в мануалах искать, чтобы не наугад скорость ставить?
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение dosikus »

[uquote="DDenisov",url="/forum/viewtopic.php?p=3161361#p3161361"]Приложил код, может кому пригодится.[/uquote]
С такими ляпами вряд-ли.
Расчет BRR можно сделать дефайном в хэдере , или вы думаете что все используют тактовую 8MHz?
Настройка пина на AF полагаясь на дефолтное состояние регистра всегда чревата.
Выбор AF -магические цифры.
При передаче проверяют не TC а TXE.
Строка должна выводиться зараз и строки нультерминэйтед.
Задержки в виде пустых циклов прерогатива ардуинщиков.

Добавлено after 5 minutes 57 seconds:
[uquote="AlanDrakes",url="/forum/viewtopic.php?p=3161631#p3161631"]Ну и USART3_SendChar:
void USART3_SendChar(char c) {
USART3->DR = c;
while (!(USART3->SR & USART_SR_TC)) {};
};
};[/uquote]

Бред не несите.
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение Z_h_e »

Лучше всего - это DMA использовать, сказал камню откуда и сколько и дальше забота камня.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Реклама
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение AlanDrakes »

[uquote="dosikus",url="/forum/viewtopic.php?p=3161732#p3161732"]Бред не несите.[/uquote]

Тем не менее, данная конструкция так же работает.
Это был самый простой набросок, пока не разобрался нормально с работой DMA.
Теперь данные быстро пишутся в кольцевой буфер, обновляется позиция записи, и, возможно, запускается DMA (если не запущен; если уже работает - по прерыванию конца передачи происходит проверка - совпадают ли позиции записи и последнего чтения, и, если нет - DMA запускается снова).
Так что теперь код больше похож на "Положил патрон и забыл. Либо насыпал пол цинка патронов, а DMA сам разрулит потом".
Переполнения случаются, не без них.
Реклама
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение dosikus »

[uquote="AlanDrakes",url="/forum/viewtopic.php?p=3163232#p3163232"]Тем не менее, данная конструкция так же работает.[/uquote]

TC для потоковых транзакций, изучите RM на досуге...
Аватара пользователя
Z_h_e
Собутыльник Кота
Сообщения: 2708
Зарегистрирован: Сб май 14, 2011 21:16:04
Откуда: г. Чайковский

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение Z_h_e »

AlanDrakes писал(а):Переполнения случаются, не без них.
Ну неее, значит где-то что-то не додумано. Хотя в каких-то задачах, в принципе, это может быть допустимым.
Изображение
Добро всегда побеждает зло. Поэтому кто победил - тот и добрый.
Аватара пользователя
AlanDrakes
Прорезались зубы
Сообщения: 236
Зарегистрирован: Пн июл 04, 2016 16:51:22
Откуда: Россия, Омск

Re: Cимволы при передаче по USART с платы STM32F3Discovery

Сообщение AlanDrakes »

Не то, чтобы непродумано, просто не имеет смысла заморачиваться с выводом некоторых сообщений. Да и переполнение просто не контролируется на уровне программы. Во всяком случае, не контролировалось чуть ранее.
Необходимости не было в выводе лога загрузки и событий в _таких_ объёмах. А если не слишком активно писать отладочную информацию - то и в "боевом" режиме до переполнения не доходит.
Ответить

Вернуться в «ARM»