Перейти к содержанию
    

Чтение строки микроконтроллером

Доброго времени суток

В приведенном по ссылке примере читается только один байт. А как прочесть строку из нескольких символов ? Я что-то не могу найти примеров

https://circuitdigest.com/microcontroller-projects/uart-communication-using-pic16f877a

 

//**Function to get one byte of date from UART**//
char UART_get_char()   
{
    if(OERR) // check for Error 
    {
        CREN = 0; //If error -> Reset 
        CREN = 1; //If error -> Reset 
    }
    
    while(!RCIF);  // hold the program till RX buffer is free
    
    return RCREG; //receive the value and send it to main function
}
//_____________End of function________________//

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

7 минут назад, Entomo сказал:

А как прочесть строку из нескольких символов ? Я что-то не могу найти примеров

По вашей ссылке на один абзац ниже.
Но это:
- только для строк с кодом "0" в конце. Для пакета данных нужно добавить длину и считать байты.
- работа в блокирующем режиме, т.е. МК больше ничего делать не будет, только ожидать новый байт.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 минут назад, Baser сказал:

По вашей ссылке на один абзац ниже.
Но это:
- только для строк с кодом "0" в конце. Для пакета данных нужно добавить длину и считать байты.
- работа в блокирующем режиме, т.е. МК больше ничего делать не будет, только ожидать новый байт.

Как называется раздел форума в котором я задал вопрос ? Нельзя ли как "для начинающего" ? - возможно ли написать код на С чтобы прочесть строку ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

37 minutes ago, Entomo said:

А как прочесть строку из нескольких символов ?

Что значит - прочесть строку? До символа перевода строки? Или заранее известное количество символов?

Нужно ли параллельно с этим еще что-то делать?

Простейший вариант, если до перевода строки или возврата каретки и без других задач:
 

char buf[100]; // буфер, куда читать строку не более 100 символов
for(i=0;i<100;++i)
{
char ch=UART_get_char();
if((ch=='\r')// возврат каретки?
   ||(ch=='\n'))// перевд строки?
{
  	buf[i]=0;// метка конца строки
	break;   // закончили ввод строки
}
buf[i]=ch;
}

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так в эмбеддинге не работает. В интернете есть куча экземплов - надо их изучать, сличая с документацией как и почему манипулируют с настройкой периферии. Потом запускать эти примеры на свих коротких проектах и отлаживаться. Весь секрет - отлаживаться придется постоянно и надо учится делать это быстро и качественно. Не работает - найти причину.

И не надо писать  - не работает. Надо исчерпывающе описать проблему и тогда выкладывать вопрос. У меня очень часто вопрос отменяется на этапе формализации вопроса.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А один символ Вы можете успешно принять на Вашем контроллере, используя UART_get_char() ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, Entomo сказал:

Нельзя ли как "для начинающего" ?

Можно. Для стандартной нуль-терминированной строки.

char mystring[20]; // выбираете размер так, чтобы с самой большой гипотетической строкой не было переполнения, хотя такое и невозможно

int idx = 0;
memset(mystring, 0, sizeof(mystring));
while(idx < sizeof(mystring-1)) {
  char c = UART_get_char();
  if(c == '\0' || c == '\r' || c == '\n')
    break;
  mystring[idx++] = c;
}
// здесь у вас в mystring будет нуль-терминированная принятая строка

 

22 минуты назад, Михась сказал:

Надо исчерпывающе описать проблему и тогда выкладывать вопрос.

Вы слишком много требуете: если тема задана в разделе для начинающих, то полагается не заставлять думать задающего вопрос, а сразу дать решение. Желательно на все случаи жизни. Сейчас тренд такой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

34 минуты назад, Aleksandr Baranov сказал:

А один символ Вы можете успешно принять на Вашем контроллере, используя UART_get_char() ?

Да

25 минут назад, MrBearManul сказал:

Можно. Для стандартной нуль-терминированной строки.

Нет и с Вашим кодом не работает. А исходный код по ссылке ниже нормально выполняется. Но это чтение только одного байта

https://circuitdigest.com/microcontroller-projects/uart-communication-using-pic16f877a

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

28 минут назад, Entomo сказал:

не работает

Я сейчас рискую вызвать ваш праведный гнев... но... что значит "не работает"? Сделайте хоть минимальную диагностику и предоставьте сюда результаты. Чем дольше вы будете молчать и не делать шаги навстречу, тем дольше будем гадать.

Если не понимаете, то вот вам для затравки:

1. Какую строку в терминал вводите? До каждого символа. Например: 123456789[ENTER]. []-только для иллюстрации, на самом деле эти скобки не вводятся. Т.е. строка 123456789, затем перевод каретки.

2. Что содержится в массиве mystring?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А как Вы судите о том, что символ успешно принят? Вы его куда -то посылаете? Или у Вас есть какой-то отладчик вроде ST-LINK?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, Aleksandr Baranov сказал:

А как Вы судите о том, что символ успешно принят? Вы его куда -то посылаете? Или у Вас есть какой-то отладчик вроде ST-LINK?

Я неспроста дал исходную ссылку дважды. Там полностью то что мне удалось воспроизвести. В коде прописано что при сравнении  принятого символа с заданным загорается или выключается светодиод. Привожу ссылку в третий раз:

https://circuitdigest.com/microcontroller-projects/uart-communication-using-pic16f877a

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

12 минут назад, Entomo сказал:

Привожу ссылку в третий раз:

Вы думаете, кто-то это будет подробно изучать? :dirol:
Хочу у вас спросить, для прояснения ситуации и оживления дискуссии:
У вас уже есть реальная железка с PIC16F877A, или это снова чистая виртуальная реальность с моделированием в Протеусе и Гипертерминалом через виртуальные порты внутри ПК ?

Если это так, то плохо. Вы, как истинный ученый привыкли исследовать природные явления в виде "черных ящиков", пиная их и изучая отклик. Это хорошо, но в данной теме все рукотворное и можно влезть внутрь при помощи отладчиков и осциллографов. И не гадать, что там внутри происходит, а просто посмотреть.... :pardon:
Нужно менять подход.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 минуты назад, MrBearManul сказал:

1. Какую строку в терминал вводите? До каждого символа. Например: 123456789[ENTER]. []-только для иллюстрации, на самом деле эти скобки не вводятся. Т.е. строка 123456789, затем перевод каретки.

2. Что содержится в массиве mystring?

Я пробовал вводить и 0 и 1. При этом после ввода я для проверки тут же вывожу массив mystring (туда же - в терминал). Действительно - введенные символы в массиве содержатся. Вы можете это увидеть на скриншоте: в строке ввода 0 и 1 и в поле вывода то же. Но светодиод погасить/зажечь не удается. Вот фрагмент кода:

 

 while(1) //Infinite loop
    {
    
        //  get_value = UART_get_char(); 
        
         char mystring[20]; // выбираете размер так, чтобы с самой большой гипотетической строкой не было переполнения, хотя такое и невозможно

int idx = 0;
memset(mystring, 0, sizeof(mystring));
while(idx < sizeof(mystring-1)) {
  char c = UART_get_char();
  if(c == '\0' || c == '\r' || c == '\n')
    break;
  mystring[idx++] = c;
}
       
UART_send_string(mystring);
        
        if (mystring == '1') //If the user sends "1"
        {
            RB3=1; //Turn on LED
            UART_send_string("RED LED -> ON"); //Send notification to the computer 
            UART_send_char(10);//ASCII value 10 is used for carriage return (to print in new line)
        }
        
        if (mystring == '0') //If the user sends "0"
        {
           RB3=0; //Turn off LED
           UART_send_string("RED -> OFF"); //Send notification to the computer      
           UART_send_char(10);//ASCII value 10 is used for carriage return (to print in new line)
        }
       
    }

 

1.png

Изменено пользователем Entomo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

10 минут назад, Entomo сказал:

if (mystring == '1') //If the user sends "1"

Идём учить Си. Совершенно неправильно так делать. Вы сравниваете значение указателя с аски-кодом цифры 1. Думаю, что в 99,999% на любой системе это сравнение всегда будет ложным в независимости от содержимого самой строки.

Для наводки: функции strcmp/strstr.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...