Easyelectronics.ru

Электроника для всех
Текущее время: 20 июн 2018, 12:30

Часовой пояс: UTC + 5 часов



    • JLCPCB - Платы прототипов всего за 2$ c бесплатной доставкой (при первом заказе)
    • 10 PCBs за $2 для 2 слоев, $15 для 4 слойной, $74 для 6 слойной платы.
    • Крупнейший китайский производитель прототипных плат. 290000+ клиентов & 8000+ заказов в день!
    • LCSC - Крупнейший китайский онлайн магазин радиодеталей.

Начать новую тему Ответить на тему  [ Сообщений: 46 ]  На страницу Пред.  1, 2
Автор Сообщение
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 25 фев 2018, 21:53 
Только пришел

Зарегистрирован: 07 окт 2016, 07:02
Сообщения: 17
_pv писал(а):
*data = SPDR это тоже самое что и data[0] = SPDR
а что же там лежит в data[1], data[2] и т.д.? учитывая что data[10] - локальная неинициализированная переменная

Это я понял. Сделал так:
Код:
 
ISR(SPI_STC_vect)
   {
       char str1[3];
      *str1 = SPDR;
       char str2[3] = "BB";
 
    if (strncmp (str1, str2,3)==0)
      {
   PORTC=0xFF;
      }
    else
   {
      PORTC=0x00;
         }
     
     return;
   }

Если просто отправляю один символ B то работает, но BB уже не работает.
Не могу понять как вытащить все символы из SPDR и объединить их в переменной str1.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 26 фев 2018, 15:42 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2908
вопрос тот же, *str1 = SPDR означает запись содержимого регистра SPDR в нулевой элемент массива str1[0] = SPDR,
что по вашему находится в чёрном ящике str1[1] и str1[2]?

подсказка: массив объявленный внутри прерывания не как статический каждый раз создаётся заново.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 26 фев 2018, 18:27 
Только пришел

Зарегистрирован: 07 окт 2016, 07:02
Сообщения: 17
_pv писал(а):
вопрос тот же, *str1 = SPDR означает запись содержимого регистра SPDR в нулевой элемент массива str1[0] = SPDR,
что по вашему находится в чёрном ящике str1[1] и str1[2]?

подсказка: массив объявленный внутри прерывания не как статический каждый раз создаётся заново.

Об этом я и говорю, что не могу понять как правильно это всё сделать. Пытался применить советы с этого сайта Описание функций языка Си и если я задаю
Код:
char str1[16]=”1234567890”;
   char str2[16]=”1234507890”;
всё работает.
НО ккак мне впихнуть и сравнить из SDPR? уже весь инет перерыл в поисках чего либо похожего. Нарыл только
Код:
ISR (SPI_STC_vect) //прерывание по приходу байта

{

simbyl[j]=SPDR; //сохранение байта в массив

if(j=7)j=0;

else j++;

}
но так и не сообразил что и как (((


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 26 фев 2018, 18:47 
Старожил

Зарегистрирован: 10 июн 2011, 23:01
Сообщения: 2908
Код:
ISR (SPI_STC_vect){
  static char buff[8];
  static unsigned char pos = 0;
  buff[pos] = SPDR;
  if (buff[pos] == '\n') {  // '\0', по количеству принятых байт, или по положительному фронту CS, раз это spi slave, определять что пора обрабатывать принятое
    buff[pos] = 0;
    pos = 0;
    if (0 == strncmp(buff, "AAA", 3) ){...}
  } else pos += 1;
  pos &= 0x07;
}


но вообще данные обрабатывать в прерывании не надо.
то есть код должен выглядеть примерно как

Код:
ISR (SPI_STC_vect){
  rxFifo.push(SPDR);
}

void main(){
...
  while(1){
    ...
    if (rxFifo.size()){ //проверить что там пришло и обработать если надо
      ...
    }
  }
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 26 фев 2018, 22:56 
Заглядывает иногда

Зарегистрирован: 23 мар 2010, 20:28
Сообщения: 47
Рабочий код:

Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 27 фев 2018, 11:47 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 653
Цитата:
но так и не сообразил что и как (((

Вам уже сказали что не так и как надо сделать. Слишком много что не так. Но я попробую другими словами, может вам понятнее так будет. Обратите внимание, что тип переменной - char. Это не строка. Это СИМВОЛ. Один байт. По сути char тоже самое, что и 8 битный integer без знака, т.е. uint8_t. Регистр тоже 8 битный integer. Понятия строки в C напрямую не существует, как бывает в других языках. Строковая переменная или константа по сути представляет из себя массив символов. В конце он терминируется байтом со значением 0x00 (\0). В связи с этим, со строками нельзя обычно работать, как с обычными переменными. Вы вычиваете по символу с буфера, записываете его в элемент массива по очереди. Нельзя просто взять и присвоить значение. Нельзя просто так сравнить 2 строки - это массив. Вы либо первый символ только сравниваете, либо адреса в памяти на строку. Для работы со строками есть полно стандартных функций - strstr(), strcpy(), и другие. Почитайте обязательно про строки в C какой-нибудь учебник или хотя бы онлайн статьи.
И еще почитайте про указатели (pointer). Они активно используются для строк в C, но на МК лучше работать со статическим буфером.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 27 фев 2018, 19:36 
Только пришел

Зарегистрирован: 07 окт 2016, 07:02
Сообщения: 17
Спасибо за помощь. Пойду читать про строки, разбираться что такое статический буфер, и учить сначала работать с интерфейсом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 27 фев 2018, 20:30 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Dust112 писал(а):
И еще почитайте про указатели (pointer). Они активно используются для строк в C, но на МК лучше работать со статическим буфером.
Так написано, как будто указатели нужны только для динамического буфера(строки?) -- какая-то недосказанность тут есть... Что такое статический буфер(или строка?), а что - динамический и чем они отличаются?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 27 фев 2018, 20:35 
Старожил

Зарегистрирован: 19 мар 2013, 19:37
Сообщения: 2439
Откуда: Санкт-Петербург
h4lf, слово "только" лишнее. Для динамического буфера указатель _нужен_ - просто потому, что как без этого вы "дотянетесь" до этого буфера?
Но и для статических данных указатели прекрасно работают, и для данных в стеке.
Динамический - это просто выделенный через malloc или другим подобным методом.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 27 фев 2018, 20:56 
Старожил

Зарегистрирован: 08 авг 2013, 09:43
Сообщения: 653
Да, это я и имел в виду. Просто большинство литературы по C будет расчитано на написание кода для ПК, где куда рациональнее активно использовать malloc().


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 27 фев 2018, 21:07 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
aamonster, просто так написано "Они активно используются для строк в C, но на МК лучше работать со статическим буфером." как будто есть какое-то противопоставление: или строка в С не может быть статическим буфером или указатели для статического буфера не используются. Если бы вместо запятой там была точка и не было бы "но" то и вопроса у меня не возникло бы, а так -- путаница может возникнуть.
Указатели при работе со строками в С используются всегда, насколько я понимаю, но не всегда явно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 28 фев 2018, 18:50 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Dust112 писал(а):
Рабочий код
Посмотрел код, он годится только в качестве примера (для ТС подойдёт, хоть это не SPI а UART и регистр не SPDR а UDR0, но принцип тот же), в реальном проекте так лучше не делать - а именно не делать через прерывания именно таким образом. Ещё что бросается в глаза:
1) переменная flag_reply изменяется в прерывании и проверяется в основной программе но она не volatile.
2) в обработчике USART0_RX_vect сначала читается регистр данных UDR0, а потом читается регистр статуса UCSR0A. Надо наоборот -- сначала UCSR0A, потом UDR0.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 28 фев 2018, 21:00 
Заглядывает иногда

Зарегистрирован: 23 мар 2010, 20:28
Сообщения: 47
h4lf писал(а):
Dust112 писал(а):
Рабочий код
Посмотрел код, он годится только в качестве примера (для ТС подойдёт, хоть это не SPI а UART и регистр не SPDR а UDR0, но принцип тот же), в реальном проекте так лучше не делать - а именно не делать через прерывания именно таким образом. Ещё что бросается в глаза:
1) переменная flag_reply изменяется в прерывании и проверяется в основной программе но она не volatile.
2) в обработчике USART0_RX_vect сначала читается регистр данных UDR0, а потом читается регистр статуса UCSR0A. Надо наоборот -- сначала UCSR0A, потом UDR0.

Опс, поумничать не удалось ))). volatile для переменной использую в другом модуле программы. Обработка статуса не дописана, поэтому пока так.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 02 мар 2018, 22:28 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Dust112, так это что, код из "боевого" проекта?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 03 мар 2018, 15:54 
Заглядывает иногда

Зарегистрирован: 23 мар 2010, 20:28
Сообщения: 47
h4lf писал(а):
Dust112, так это что, код из "боевого" проекта?

Таки да и весьма хорошо и уже давно работающего.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 03 мар 2018, 20:18 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Dust112, даже не собирался ставить под сомнение его работоспособность, я только хочу обратить внимание на некоторые недостатки, особенно приёма в таком виде (возможно в самом проекте сделано по другому, но я вижу только приведённый Вами код). Если интересно (не все любят критику, потому и спрашиваю) -- я приведу аргументы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 08 мар 2018, 04:00 
Заглядывает иногда

Зарегистрирован: 23 мар 2010, 20:28
Сообщения: 47
h4lf писал(а):
Dust112, даже не собирался ставить под сомнение его работоспособность, я только хочу обратить внимание на некоторые недостатки, особенно приёма в таком виде (возможно в самом проекте сделано по другому, но я вижу только приведённый Вами код). Если интересно (не все любят критику, потому и спрашиваю) -- я приведу аргументы.

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 10 мар 2018, 23:20 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Сначала о приёме: такой вариант приёма с использованием прерывания - не имеет преимуществ по сравнению с простым поллингом флага RXC в регистре статуса, но при этом имеет недостатки от использования обработчика прерывания. Поэтому, если устраивает блокирующий приём(а в Вашем примере он именно такой), то лучше это сделать явно -- без использования обработчика прерывания.
Подробнее:
функция uart_wite_for
Show код функции uart_wite_for
блокирует выполнение до тех пор, пока принятая через UART строка не совпадёт с со строкой str. Блокируруется вот этим (не относящееся к блокиковке удалено):
Код:
while (result == 0)
{
    if(strstr_P(buffer_receive, str))
    {
        result = 1;
    }
}

Т.е. пока не придёт нужная строка в UART, всё выполнение "стоит" в этом месте(кроме обработчиков прерываний, если не используется вытесняющий диспетчер или как там его). Это само по себе не всегда приемлемо, но если приемлемо (и программист полностью осознаёт, что делает), то лучше вообще не использовать обработчик USART0_RX_vect, а так же - через while проверять флаг RXC в UCSR0A. В этом случае volatile флаг flag_reply становится совсем ненужным, а у buffer_index_r можно будет убрать volatile.
А вот с внутренним while (flag_reply == 1) {} всё очень странно: flag_reply устанавливается в 1 только в обработчике прерывания, когда завершится (так или иначе) приём строки, а сбрасывается в этой функции перед обоими while. Видимо тут ошибка -- условием внутреннего while должно быть не (flag_reply == 1) а (flag_reply == 0), чтобы проверка на совпадение строк происходила только после окончания приёма, а не постоянно. Самое плохое в этой ошибке то, что и так всё работает, но если, например, прерывание случится сразу после flag_reply = 0; но перед while (flag_reply == 1) {} и в нём завершится приём строки (т.е. flag_reply установится), то программа зависнит в while (flag_reply == 1) {} насовсем. Постоянное сравнение неготовой строки в буфере buffer_receive, тоже может дать "сюрпризов". Но большую часть времени -- это будет работать, в этом и есть коварность такого рода ошибок.
То, что ожидаемая строка может вообще не прийти (в том числе из-за ошибки передачи) -- отдельный вопрос.
О проверке флагов ошибок уже писал. Нужно сначала читать регистр с флагами (UCSR0A), а только потом регистр данных (UDR0), ибо в DS написано:
Цитата:
This bit is valid until the receive buffer (UDR0) is read.
Если проверка флагов ошибок пока не используется, то нужно либо написать правильно чтение и заглушку, либо вообще удалить этот код проверки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 11 мар 2018, 00:01 
Заглядывает иногда

Зарегистрирован: 23 мар 2010, 20:28
Сообщения: 47
h4lf, спасибо, познавательно. Обязательно проанализирую применительно к моему варианту кода. В моем случае принимается заведомо известная строка, где присутствует нужный ответ. Может поэтому у меня и работает.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 11 мар 2018, 06:13 
Старожил
Аватара пользователя

Зарегистрирован: 18 апр 2017, 03:01
Сообщения: 846
Dust112, если у Вас там такая же ошибка с неверным условием внутреннего while, то оно будет работать, просто не будет ожидания окончания приёма строки перед сравнением. Но есть очень небольшая вероятность зависания во внутреннем цикле с этим неверным условием. Эта вероятность очень мала потому, что время выполнения (количество тактов между которыми может возникнуть прерывание) функции strstr_P гораздо больше чем время между сбросом flag_reply и проверкой условия внутреннего цикла while (flag_reply == 1) {}. Эту вероятность даже можно приблизительно подсчитать если узнать эти времена.
Кроме этого, так как сравнивается ещё не до конца принятая строка, возможно ложноположительное срабатывание этой функции (uart_wite_for), т.е. флаг result может быть установлен не после прихода ожидаемой строки str, а во время прихода другой. При этом приёмный буфер будет очищен преждевременно функцией clear_rxbuffer, что тоже может создать проблемы. Вероятность этого уже зависит от того, что конкретно приходит по UART и что ожидается (str). Очень может быть, что в Вашем конкретном случае такое вообще не может произойти и потому работает без проблем.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: AtMega8 SPI отправить строку.
СообщениеДобавлено: 11 мар 2018, 07:23 
Старожил

Зарегистрирован: 06 фев 2011, 15:16
Сообщения: 612
Откуда: Челябинск
Azerhud писал(а):
но так и не сообразил что и как (((
Я тоже что-то никак не соображу, что это значит?
Код:
if(j=7)j=0;


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 46 ]  На страницу Пред.  1, 2

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB