Jump to content

    
Sign in to follow this  
Entomo

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

Recommended Posts

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

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

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________________//

 

Share this post


Link to post
Share on other sites
7 минут назад, Entomo сказал:

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

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

Share this post


Link to post
Share on other sites
6 минут назад, Baser сказал:

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

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

Share this post


Link to post
Share on other sites
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;
}

 

Share this post


Link to post
Share on other sites

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

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

 

 

Share this post


Link to post
Share on other sites
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 минуты назад, Михась сказал:

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

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

Share this post


Link to post
Share on other sites
34 минуты назад, Aleksandr Baranov сказал:

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

Да

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

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

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

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

 

Share this post


Link to post
Share on other sites
28 минут назад, Entomo сказал:

не работает

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

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

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

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
1 минуту назад, Aleksandr Baranov сказал:

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

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

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

Share this post


Link to post
Share on other sites
12 минут назад, Entomo сказал:

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

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

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

Share this post


Link to post
Share on other sites
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

Edited by Entomo

Share this post


Link to post
Share on other sites
10 минут назад, Entomo сказал:

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

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

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this