Натолкнулся сегодня на странное поведение передатчика USART. исследуя работу в реалтайме.
Когда-то давно написал функции putchar() и обработчик прерывания для работы передатчика USART с софтовым с буфером, ( для приемника тоже, но пока так детально его не исследовал)
Реализация, собственно, традиционная: есть общий массив, функция putchar() в него по кольцу пишет, обработчик прерывания по кольцу в обратном направлении- читает. для количества выводимых бит используется переменная tx_counter/ в прерывании она декрементируется, в функции putchar()- инкрементируется. В принципе все работает без ошибок, но с временной точки зрения есть особенности.
В обработчике прерывания использует бит TXE для определения того, свободен регистр данных или нет ( так как прерывание общее, оно может вызываться и приходом данных) . в прерывании проверяется, TXE==1, и если это так и tx_counter>0 то делается вывод из массива буфера в регистр данных (DR). В противном случае, если выводить нечего, прерывание по TXE запрещается.
В функции putchar перед инкрементацией Tx_counter и записи очередного элемента буфера я запрещаю прерывание от TXE, после инкрементации-разрешаю.
( Код будет завтра !!

)
Найденные "глюки" .
1. в документации на рисунке 241 (стр 660) есть замечательная надпись на графике TXE что он, дескать, может быть set by hardware
cleared by software. - это - Ошибка! он никак не может быть стерт руками, только записью в DR ( Стирал, проверял тут же- не стирается. косвенно это подтверждает буква "r" в поле описания статус регистра).
Дальше еще интересная особенность. Вывожу в буфер putchar() 120 символов и решаю посмотреть, сколько времени операция займет при каждем putcar дергаю ножкой, меряю. Cмотрю- расстояние между импульсами иногда сильно гуляет. Дергаю другой ножкой в прерывании usarta - вот оно, родимое. Cтоит после записи в DR ( начать пользоваться функцией putchar() как после каждой (не всегда!) возникает прерывание по USART.
Возникает оно
если перезаписывать единицей бит разрешения прерывания по TXE. В результате параллельно цепочке импульсов, отмечающую вызовы Putchar() получаю массированную цепочку пустых прерываний, вывод буфера происходит корректно, ничего не теряется!
В документации такого нет...
Кто сталкивался?