Микроконтролери и електроника
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 ]
Заглавие: 

Cvetanov написа:
....

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/