Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: UART 0xFF проблема
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Все остальные микроконтроллеры
andron86
Привет всем, помогите пожалуйста с проблемой!

Никак не могу считать 0xff. Конкретнее:c СОМ порта пытаюсь считать телеграмму с конечным байтом 0xff - все, кроме этого, байты, принимаются без проблем. help.gif

Использую в C8051F124,Keil c51, UART0 38400/1stopbit и такой алгоритм:

Код
  for(Temp = 0; Temp<8; Temp++)
{
while(cmd = getchar())
        if(cmd != -1) break;
          if(cmd==0xff){ temp2[i]=cmd; break;}
temp1[count]=cmd;        
}


помогите студенту, плиз!!!
arttab
А я послать через ком не могу FF. для проварки этой засады проверьте через гипертерминал Alt+255. Если проходит, то Ваш девайс ОК, а проблемы с совтом на компе. Сам бьюсь.
andron86
Да нет, вроде проверенно! Посылаю не на терминал, а на камеру(VISCA Sony- там в телеграмме заключительный байт 0xff) - всё прёт, софт для компа сам писал!
andron86
Цитата(arttab @ Mar 1 2006, 07:46) *
А я послать через ком не могу FF. для проварки этой засады проверьте через гипертерминал Alt+255. Если проходит, то Ваш девайс ОК, а проблемы с совтом на компе. Сам бьюсь.


привет Артём - забыл добавить!

Если вы hyperterminal от гейса используете, то там, по моему, 0xff не высвечиваются(точно не знаю)! Попробуйте этот терминал
Shamil
Цитата(andron86 @ Mar 1 2006, 11:34) *
Никак не могу считать 0xff. Конкретнее:c СОМ порта пытаюсь считать телеграмму с конечным байтом 0xff - все, кроме этого, байты, принимаются без проблем.

Код
        while(cmd = getchar())
                if(cmd != -1)
                        break;

        if(cmd==0xff)
        {
                temp2[i]=cmd;
                break;
        }


Вы, к сожалению, не привели описание переменной cmd.
Если она описана как char, т.е. байт со знаком,
то значения 0xFF и -1 совпадают, и соответственно
эти значения пропускаются вашим же while.

P.S. Если Вы только учитесь, настоятельно рекомендую
следить за форматированием текста программ, не надо
экономить строки.
andron86
Извините забыл доавить!

cmd объявленна как unsigned char
Shamil
Цитата(andron86 @ Mar 1 2006, 12:23) *
Извините забыл доавить!
cmd объявленна как unsigned char

Это ничего не меняет, значение 0xFF в ней
будет соответствовать -1, при сравнении.

Для того чтобы твой код работал,
cmd надо объявить как short (т.е. двухбайтовую знаковую переменную)
andron86
Цитата(Shamil_Yusupov @ Mar 1 2006, 09:20) *
Это ничего не меняет, значение 0xFF в ней
будет соответствовать -1, при сравнении.

Для того чтобы твой код работал,
cmd надо объявить как short (т.е. двухбайтовую знаковую переменную)

Да нет Шамиль, мне кажется, что это одно и тоже! Ведь состояние сом порта в режиме ожидания 0xff т.е -1!! Даже если я объявлю cmd как short, то прерывание цикла будет при 0xffff -т.е. одно и тоже. Выход я нашел - меня спасло то, что 0xff находится не в начале телеграммы! То есть:
Код

unsigned char cmd;
for(xTemp = 0; xTemp<8; xTemp++)
{
while(cmd = getchar())
        if(cmd != -1 && xTemp == 0) break;

        if(cmd==0xff){ temp2[i]=cmd; break;}

temp1[count]=cmd;        
}
Alechin
Советую посмотреть листинг (в котором ассемблерный код - включить такую опцию в компиляторе) и посмотреть, что с чем сравнивается. На самом деле не очень понятно, что вообще Вы хотели сказать, разделив -1 и 0xff - это одно и тоже (для байтовой переменной). И как понять "состояние порта в режиме ожидания"? Разве getchar возвращает что-либо, если нет принятого символа? Вы что то не допоняли.
Shamil
Цитата(andron86 @ Mar 1 2006, 17:43) *
Цитата(Shamil_Yusupov @ Mar 1 2006, 09:20) *

Для того чтобы твой код работал,
cmd надо объявить как short (т.е. двухбайтовую знаковую переменную)

Да нет Шамиль, мне кажется, что это одно и тоже! Ведь состояние сом порта в режиме ожидания 0xff т.е -1!! Даже если я объявлю cmd как short, то прерывание цикла будет при 0xffff -т.е. одно и тоже.

Да, каюсь, не посмотрел описание функции getchar() в Keil.
Я решил, что эта функция описана как int,
и возвращает -1 при отсутствии принятых байтов,
поэтому в цикле while ты ожидаешь поступления байта.
Но судя по описанию эта функция сама дожидается
приема очередного байта.

Зачем же тогда у тебя стоит цикл while ???

Цитата(andron86 @ Mar 1 2006, 17:43) *
Выход я нашел - меня спасло то, что 0xff находится не в начале телеграммы! То есть:

Да это не выход, а затычка.
andron86
Цитата(Alechin @ Mar 1 2006, 13:57) *
Советую посмотреть листинг (в котором ассемблерный код - включить такую опцию в компиляторе) и посмотреть, что с чем сравнивается. На самом деле не очень понятно, что вообще Вы хотели сказать, разделив -1 и 0xff - это одно и тоже (для байтовой переменной).

Я и не разделял -1 и 0xff, естественно это одно и тоже!
Цитата
И как понять "состояние порта в режиме ожидания"? Разве getchar возвращает что-либо, если нет принятого символа? Вы что то не допоняли.

Состояние порта - я ожидаю прихода фреймом и подсчитываю их колличесво по 0xff(конечный байт фрейма), а состояние порта high т.е. у меня fffff... Естественно можно также на прямую с SBUF регистра считывать, не используя getchar(), но как есть так есть!
Цитата
Вы что то не допоняли.

Может и верно, чего то не допонимаю!
Цитата
Да это не выход, а затычка.

согласен Шамиль на 100%, но тестовал в течении часа - вроде идёт! glare.gif
Alechin
Цитата
Состояние порта - я ожидаю прихода фреймом и подсчитываю их колличесво по 0xff(конечный байт фрейма), а состояние порта high т.е. у меня fffff... Естественно можно также на прямую с SBUF регистра считывать, не используя getchar(), но как есть так есть!

Я все равно не понял что такое состояние порта high = ffff - это что, состояние линии приема когда нет передачи? Тогда к флагу завершения пакета 0xff это не имеет отношения. Когда линия приема в "1" getchar будет ждать приема - появления стартового бита, 8 битов данных, стопового бита и т.п.
Или когда нет приема по порту все время передается байт-заполнитель 0xff?

Если же вы ждете пакета, оканчивающего на 0xff - то надо сделать так:
while((*pBuf++ = getchar()) != 0xff) ;
Все - при выходе из цикла буфер содержит принятый пакет.
Но учтите - если порта нет (устройство на другой стороне не отвечает) - цикл будет бесконечны.
Правильнее делать все обработчиком прерывания - принимать байты, сохранять в буфере, по приему признака конца пакета выставлять основной программе флаг готовности.
andron86
to Алёхин!

спасибо Вам что не оставляете в беде cheers.gif

Но я сам не пойму, почему у меня такие глюки - толи getchar()(uVison2) глючит, толи контроллер??? по идее достаточно:
Код
unsigned char cmd;
for(xTemp = 0; xTemp<8; xTemp++)
{
cmd = getchar();
if(cmd==0xff){ temp2[i]=cmd; break;}
temp1[count]=cmd;        
}

но у меня????? getchar постоянно возвращает 0xff, т.е. постоянно в режиме high??????? Flag read UART постоянно 1 - т.е. принят байт(убираю программно - но опять, при заходе в цикл, включает 1. p.s. на buse тишина??? )!!!!!! Я думаю. может кирдык ему(контроллеру) пришёл, но проблема, что их два(борта) и у обоих эта заноза!
Сегодня, опять же бился с другой проблемой - 16 битным Timer'ом! Ну никак правильно тикать не хочет - дурдом(p.s. использовал алгортитм с silabs - example)!!
Не знаю, может у меня опыта с 8051 от silaba нету? Хотя, вроде бы с ихней paging разобрался, в принципе как и все 8051'е!
SSerge
Цитата(andron86 @ Mar 3 2006, 01:11) *
Но я сам не пойму, почему у меня такие глюки - толи getchar()(uVison2) глючит, толи контроллер??? по идее достаточно:
Код
unsigned char cmd;
for(xTemp = 0; xTemp<8; xTemp++)
{
cmd = getchar();
if(cmd==0xff){ temp2[i]=cmd; break;}
temp1[count]=cmd;        
}

Вы в stdio.h давно не заглядывали?
Там можно найти строчки, которые заставят задуматься:

#ifndef EOF
#define EOF (-1)
#endif
...........
int getchar(void);

Это значит, что функция getchar() возвращает значение типа int, ну так опишите свою переменную как int и используйте символическое имя EOF чтобы не морочить себе голову тонкостями преобразования типов и способов представления отрицательных чисел.
Ещё полезно почитать какой-нибудь учебник по языку С, да вот хотя-бы K&R, в первой-же главе (цитата):

Основная проблема заключается в том, чтобы зафиксировать конец файла ввода. Обычно, когда функция getchar наталкивается на конец файла ввода, она возвращает значение, не являющееся действительным символом; таким образом, программа может установить, что файл ввода исчерпан. Единственное осложнение, являющееся значительным неудобством, заключается в существовании двух общеупотребительных соглашений о том, какое значение фактически является признаком конца файла. Мы отсрочим решение этого вопроса, использовав символическое имя EOF для этого значения, каким бы оно ни было.
...................

Использование символической константы EOF для представления значения, возвращаемого функцией getchar при выходе на конец файла, гарантирует, что только одна величина в программе зависит от конкретного численного значения.

Мы также описали переменную 'c' как int, а не char, с тем чтобы она могла хранить значение, возвращаемое getchar . Как мы увидим в главе 2, эта величина действительно int, так как она должна быть в состоянии в дополнение ко всем возможным символам представлять и EOF .
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.