Другие языки программирования и технологии

Вопрос по языку СИ, конкретнее по передачи байта по UART

//Функция отправляющая байт в UART ( далее в тексте буду называть это НЁХ)

void send_to_uart(uint8_t data) {
while(!(USART1->SR & USART_SR_TC)); //Ждем пока бит TC в регистре SR станет 1
USART1->DR=data; //Отсылаем байт через UART
}

Возникло непонимание. Предположим для наглядности, что sr - 8 битовый регистр, в котором бит Tc - младший. Согласно даташиту, бит ТС становится равным 1, когда окончена передача байта, т. е. когда ТС у нас 0 - байт передаётся. К тому же согласно "НЁХ", запись в регистр DR не может производиться, пока не будет выполнено условие while. А тут поподробней. Согласно статьям в инете, while будет выполняться, когда условие будет истинно, т. е. отлично от нуля.

Разберем побитово эту строчку: (!(USART1->SR & USART_SR_TC))
Возьмем ситуацию, когда у нас байт в процессе передачи

00000000 - регистр SR
00000001 - битовая маска USART_SR_TC
В результате побитовая И даст: 00000000
Инверсия! даст: 11111111
Т. е. значение отличное от нуля, т. е. операнд while будет выполняться, т. е. в процессе передачи байта у нас будет перезаписываться регистр DR.
Где я не прав? :)
Muzambil Jumaev
Muzambil Jumaev
271
"Т. е. значение отличное от нуля, т. е. операнд while будет выполняться, т. е. в процессе передачи байта у нас будет перезаписываться регистр DR."
Ошибочное утверждение.

У Вас в конце строчки while() стоит точкасзапятой - ;
while(!(USART1->SR & USART_SR_TC));
Поэтому пока внутри скобок вайла истина, до USART1->DR=data; очередь не дойдет.

****
"В результате побитовая И даст: 00000000"
Правильно.
"Инверсия! даст: 11111111"
Ошибка. Хотя в данном случае разницы и нет.
Побитовая инверсия это - ~.
А восклицательный знак - это отрицание, то есть логическое "НЕ".
Отрицанием нуля будет любое число отличное от нуля, обычно 1, но, по-моему, в Си не обязательно.
Отрицание любого отличного от нуля числа будет ноль.
Рустам Миргунов
Рустам Миргунов
21 729
Лучший ответ
STM32 и микроконтроллеры?
------
00000000 - регистр SR
00000001 - битовая маска USART_SR_TC
В результате побитовая И даст: 00000000
Инверсия! даст: 11111111
---------------
Неужели?
00000000 И 00000001 = 11111110
!(11111110 ) = 00000001

Сюрпрайз.

Если вы уж язык программирования C взяли под вопросом, удосужьтесь изучить его.
+ битовые операции...

Но не тут-то было.

Дело в том, что восклицательный знак - логическая операция. Т. е в итоге, у вас тут получается некий бред. А мои знания в С уж нулевые - вероятно вам придется добавить USART1->SR != 1 или что-то в таком духе.

Надеюсь мой полуночный бред тебе поможет, ибо я всё забыл.

И не забуду добавить - пользуйся дебагом.
Kuttuubek Kalbaev
Kuttuubek Kalbaev
1 755
Muzambil Jumaev 00000000 И 00000001 = 11111110 - wtf???
таблица истинности для "И" 0 и 0 =0, 0 и 1 = 0, 1 и 0 =0, 1 и 1 = 1. Почему инверсия 2 раза?
Muzambil Jumaev "...вероятно вам придется добавить USART1->SR != 1 или что-то в таком духе. " Ничего там не надо добавлять, это готовый рабочий кусок кода. И про битовые операции читал и минимум си для Мк знаю) Гуглить умею
Muzambil Jumaev Дебагом можно, среда разработки на другом ноуте) я из-за этой хрени заснуть не могу.