Код (Text): unsigned char currKey, prevKey; //-----------код А while (1){ currKey = PINA; if ( currKey != 0xFF){ UART1_Write(currKey); } } //-----------код Б while (1){ currKey = PINA; if ( currKey != 0xFF ){ if (currKey != prevKey){ UART1_Write(currKey); } } prevKey = currKey; } Контроллер Atmega16. На порту А сидят кнопки. PullUp включен. Если нажата кнопка, передать состояние порта (код) по UART на терминал. Два варианта кода. Вариант А. Нажимаю кнопку (замыкаю один из входов порта на землю) - в терминал начинают сыпаться коды состояния порта. Например, нажата кнопка на 0 бите - код 0хFE, на 7 бите - 0х7F. Все хорошо, кроме одного: пока нажата кнопка, контроллер бомбардирует терминал одним и тем же кодом. Мне не надо столько раз посылать этот код. Достаточно один раз передать в терминал код. Поэтому родился вариант Б. А в варианте Б происходит не то, что я ожидаю: в терминал как и предполагалось, приходит один код на одно нажатие кнопки. Вся проблема в том, что этот код всегда равен 0х00, какую бы кнопку я не нажал. Или я что-то не понял, или одно из двух... В чем тут засада?
может быть так правильнее?: Код (Text): prevKey = 0; while (1){ currKey = PINA; if ( currKey != 0xFF ){ if (currKey != prevKey){ UART1_Write(currKey); prevKey = currKey; } } }
это не меняет сути. В чем проблема я примерно нащупал: это регистр UDR. Зачем-то приходится его обнулять принудительно перед передачей байта. Тогда передача будет идти правильно. Надо ковыряться в UАRT либе.
cresta У меня основная масса чудес случается из-за оптимизации компилятором. А вот если в регистре состояния UART установлены биты ошибок, то отладчик регистр UDR отображается как 0 (может ли отладчик показать в нём что-то другое - не проверял). Попробуй прочитать перед передачей его и/или регистр состояния. Еще для кнопок хорошо бы сделать защиту от дребезга (механический износ кнопок и наводки никто не отменял). Можно читать кнопки с интервалом в 10-15мс и по нескольким совпадающим значениям принимать решение нажата/не нажата(считается, что для механических контактов дребезг заканчивается в течении 50мс): Код (Text): b[3&++cnt]=PINA; currKey|=(b[0]&b[1]&b[2]&b[3]); currKey&=(b[0]|b[1]|b[2]|b[3]);
Советую посмотреть доку на отмегу там есть примеры по передачи. Необходимо просматривать бит занятости передатчика перед отправкой. По поводу одной отправке то либо как сказали паузы либо можно завязать на внешнее прерывание и тогда по перепаду отправлять, правда проблему дребезга это не решит.
Проблему решил, уйдя от библиотечной функции. Сделал свою: Код (Text): void RS_Send_Char(char c){ while ( !(UCSRA & 0b00100000) ); //waiting for ready UDR = c; } void RS_Send_Text (char *text){ while ( *text ){ RS_Send_Char (*text); text ++; } }