| Микроконтролери и електроника http://mcu-bg.com/mcu_site/ |
|
| Проблем с бит UCSR0A.TXC0 на atmega168? http://mcu-bg.com/mcu_site/viewtopic.php?f=3&t=6255 |
Страница 1 от 1 |
| Автор: | Ники [ Пет Ное 07, 2008 12:21 pm ] |
| Заглавие: | Проблем с бит UCSR0A.TXC0 на atmega168? |
Наложи ми се да изчаквам край на предаването по УАРТа. Обичайно се изчаква бит UCSR0A.UDRE0 да се вдигне за да покаже че буфера е празен, но това не ме устройва и реших да ползвам флаг UCSR0A.TXC0, който се вдига след изпращане на стоп-бит на последния байт. И тук ударих на камък. Цикъла в който задържам в изчакване на вдигането на този бит не работи. Изчистването на този флаг, UCSR0A.TXC0, преди или след цикъла на изчакване за вдигането му, не помага. За момента съм решил проблема с Delay() функция която да задържа софта за време колкото е сендването на 1 байт при текущ бауд рейт, но това ми стои някак дървено при наличието на хардуер за подобна индикация. Функцията която ползвам е следната: #define _BV(x) (1<<x) inline void wait_uart_tx(void) { //if (UCSR0A & _BV(TXC0)) UCSR0A|=_BV(TXC0); //while ((UCSR0A & _BV(TXC0))); while (!(UCSR0A & _BV(TXC0))); //if (UCSR0A & _BV(TXC0)) UCSR0A|=_BV(TXC0); } редовете които са коментирани, водят единствено до спиране на работата на програмата, за което не положих усилия да разбера защо се получава, а редът 'while (!(UCSR0A & _BV(TXC0)));' за момента е безсмислен, защото не върши това което очаквам, но и не влошава видимо работата на програмата. Та питам, бъгчето в професора ли е, или в задклавиатурното устройство? |
|
| Автор: | Cvetanov [ Пет Ное 07, 2008 1:06 pm ] |
| Заглавие: | |
След като изчакаш вдигането на флага трябва да има ред с примерно такова съдържание sbi(UCSR0A,TXC0); Това нулира въпросния флаг. Иначе след първия изпратен байт, ще остане завинаги в 1. //едит така би трябвало да работи. inline void wait_uart_tx(void) { while (!(UCSR0A & _BV(TXC0))); UCSR0A|=_BV(TXC0); } |
|
| Автор: | Ники [ Пет Ное 07, 2008 2:01 pm ] | |||||||||
| Заглавие: | ||||||||||
Eдно въпосче към теб конкретно, ей така от любопитство, ползвал ли си този бит в софтуер който си писал, за посочения от мен процесор? |
||||||||||
| Автор: | Cvetanov [ Пет Ное 07, 2008 3:18 pm ] |
| Заглавие: | |
Едно отговорче - Ползвал съм го с мега88 (и не само), което е същото. Работи със сигурност. Ако искаш и филмче ще ти направя. |
|
| Автор: | Ники [ Пет Ное 07, 2008 4:18 pm ] |
| Заглавие: | |
явно (полу)нощния труд не помага за правилното мислене. Пак си проверих творенията, амбициран от отговора ти, че работи. Странно ми е, че пробвах доста от описаните в първия ми пост варианти, но е имало и други куци неща, които съм оправил но не съм опитал отново чистенето на бита. Така не работи: inline void wait_uart_tx(void) { while (!(UCSR0A & _BV(TXC0))); UCSR0A|=_BV(TXC0); } Така работи: inline void wait_uart_tx(void) { UCSR0A|=_BV(TXC0); while (!(UCSR0A & _BV(TXC0))); } Засега ще мина и без филмче |
|
| Автор: | Cvetanov [ Пет Ное 07, 2008 5:06 pm ] |
| Заглавие: | |
Аз използвам вариант 1. Предполагам че при теб не работи, защото преди да почнеш да въртиш цикъл с wait_uart_tx, някъде в началото на програмата имаш предаване без да се следи и съответно нулира флага ТХС. |
|
| Автор: | Ники [ Пет Ное 07, 2008 5:37 pm ] |
| Заглавие: | |
Ако беше отговорил в по-горния си пост че не си пробвал върху тази фамилия процесори, едва ли щях да се заиграя да търся къде е проблема. Дразни, но не ми се губеше врме за такава дреболия, пък и имаше лесен уоркъраунд. Софта от доста места принтва по порта, но само на едно място ме сърбеше обсъждания бит. Засега го оставям с работещия вариант, не е важен кой от двата е , а само да има нужния ефект. Благодаря все пак за отговорите! |
|
| Страница 1 от 1 | Часовете са според зоната UTC + 2 часа [ DST ] |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|