Easyelectronics.ru

Электроника для всех
Текущее время: 23 янв 2021, 00:47

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



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 35 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 12:42 
Только пришел

Зарегистрирован: 05 фев 2020, 11:58
Сообщения: 11
Не могу передать строку по уарт, причем символы по отдельности передаются, а вместо строки Privet идет длинная передача разных символов.
Пишу в атмел студио 7
int main(void)
{
I2C_Init();
LCD_ini();
USART_Init(16);
USART_Transmit('L');
USART_Transmit('M');
USART_Transmit(0x0d);
USART_Transmit(0x0a);
USART_Transmit_str("Privet");
USART_Transmit(0x0d);
USART_Transmit(0x0a);
while (1)
{
}
}

void USART_Transmit( unsigned char data ) //Функция отправки символов
{
while ( !(UCSR0A & (1<<UDRE0)) ); //Ожидание опустошения буфера приема
UDR0 = data; //Начало передачи данных
}

void USART_Transmit_str( char *str ) //Функция отправки строки по usart
{

while(*str)
{
USART_Transmit(*str++);
}
}


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 13:24 
Старожил

Зарегистрирован: 19 мар 2011, 05:05
Сообщения: 3066
ну так выдает всю память, какая там есть..


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 17:33 
Только пришел

Зарегистрирован: 05 фев 2020, 11:58
Сообщения: 11
goreprogrammist писал(а):
ну так выдает всю память, какая там есть..

При отладке в Студио видно, что передает каждый символ из строки, а реально отдельные символы передаются а при передачи строки - белеберда.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 21:31 
Старожил
Аватара пользователя

Зарегистрирован: 01 дек 2013, 18:06
Сообщения: 232
Откуда: г. Волгоград.
У меня на МЕГЕ 8 такой код работает нормально:

Код:
void USART_Transmit( unsigned char data)
    {
      // ждать очистки флага передатчика
      while (!(UCSRA & DATA_REGISTER_EMPTY));
      // загрузить байт данных в буфер и начать передачу
      UDR = data;
    }

void UART_send_st (const unsigned char *st)
{
   while(*st)
      USART_Transmit(*st++);
}

UART_send_st("Hello, World!\n");
USART_Transmit(13);


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 21:35 
Старожил

Зарегистрирован: 19 мар 2011, 05:05
Сообщения: 3066
ну повезло значит. вы смотрите, куда смотрит этот st и что там в памяти находится. оно продолжает показывать дальше, пока условие цикла не исполняется - а когда оно исполняется?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 21:41 
Старожил
Аватара пользователя

Зарегистрирован: 01 дек 2013, 18:06
Сообщения: 232
Откуда: г. Волгоград.
Цитата:
ну повезло значит


может быть, может быть


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 22:42 
Только пришел

Зарегистрирован: 05 фев 2016, 21:31
Сообщения: 16
goreprogrammist писал(а):
ну повезло значит. вы смотрите, куда смотрит этот st и что там в памяти находится. оно продолжает показывать дальше, пока условие цикла не исполняется - а когда оно исполняется?

А что не так то? Цикл будет исполняться, пока не попадётся символ конца строки(*st != '\0'). '\0' при передаче строкового литерала добавляется автоматом. Поправьте, если ошибаюсь.

Что касается проблемы топикстартера, я бы начал с проверки настроек уарт. Сдаётся, что они могут отличаться, к примеру, числом стопбит. Также интересные эффекты получаются, если не совпадает частота тактирования, указанная в проекте, с реальной. Как раз сейчас занимаюсь уартом, долго не мог понять, почему посылаю 'g', а в терминал стабильно приходит 'Ы' :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 05 фев 2020, 23:02 
Старожил
Аватара пользователя

Зарегистрирован: 04 окт 2011, 10:19
Сообщения: 2140
Вопрос знатокам С

USART_Transmit_str("Privet");

где будет находится "Privet" ?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 05:29 
Только пришел

Зарегистрирован: 05 фев 2020, 11:58
Сообщения: 11
gromgor писал(а):
... я бы начал с проверки настроек уарт. Сдаётся, что они могут отличаться, к примеру, числом стопбит. Также интересные эффекты получаются, если не совпадает частота тактирования, указанная в проекте, с реальной. Как раз сейчас занимаюсь уартом, долго не мог понять, почему посылаю 'g', а в терминал стабильно приходит 'Ы' :)

Так в том и дело что уарт настроен правильно: при передачи по одной литере все ок
Код:
         USART_Transmit('L');
         USART_Transmit('M');
         USART_Transmit(0x0d);
         USART_Transmit(0x0a);

Это передает правильно

x893 писал(а):
Вопрос знатокам С
USART_Transmit_str("Privet");
где будет находится "Privet" ?

В моем случае это находится в data IRAM


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 09:17 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 2629
А признак конца строки '\0' формируется, точно?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 11:06 
Заглядывает иногда
Аватара пользователя

Зарегистрирован: 23 ноя 2010, 20:11
Сообщения: 117
Откуда: Омск
Что-то мне кажется, что код передачи строки должен выглядеть так:
Код:
void UART_send_st (const unsigned char *st)
{
   while(*st) {
      USART_Transmit(*st); // Передаются данные из разыменованого указателя
      st++; // Указатель двигается дальше.
   }
}

А иначе будет:
string[] = "Hello!\0";
&string = 0x89; // например
UART_send_st (0x89); < Передали УКАЗАТЕЛЬ на память
while(*st) -> 0x89 == 'H'
USART_Transmit('H'++); < Отправляется 'H'
// string[] == "Iello!\0" < Происходит инкремент ПО УКАЗАТЕЛЮ.
// *st == 0x89 < А указатель остаётся прежним.
while(*st) -> 0x89 == 'I' (Не ноль - продолжаем...)
USART_Transmit('I'++); < Отправляется 'I'

И так далее вплоть до 0xFF (я)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 12:49 
Старожил

Зарегистрирован: 16 окт 2013, 01:27
Сообщения: 1688
Пробуйте:

void USART_Transmit( unsigned char data ) { //Функция отправки символов

while ( !(UCSR0A & (1<<UDRE0)) ); //Ожидание опустошения буфера приема
UDR0 = data; //Начало передачи данных
}

void USART_Transmit_str( char *str ) {//Функция отправки строки по usart

while(*str) {
USART_Transmit(*str); // <=
str++; // <=
}
}

P\S Не посмотрел выше уже написали


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 13:39 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 2629
Все верно - это косяк
Код:
USART_Transmit(*st++);


Не надо было разименовывать указатель.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 15:08 
Только пришел

Зарегистрирован: 05 фев 2020, 11:58
Сообщения: 11
sed_alex писал(а):
Пробуйте:

void USART_Transmit( unsigned char data ) { //Функция отправки символов

while ( !(UCSR0A & (1<<UDRE0)) ); //Ожидание опустошения буфера приема
UDR0 = data; //Начало передачи данных
}

void USART_Transmit_str( char *str ) {//Функция отправки строки по usart

while(*str) {
USART_Transmit(*str); // <=
str++; // <=
}
}

P\S Не посмотрел выше уже написали

Всем спасибо за участие уже руки опускаются.
Попробовал так, действительно белеберду перестал гнать. Но выводит 8 байт FF, дополнил еще одним тестом
Код:

uint64_t  kub  = 0x2861357C060000D7;
uint8_t *kodROM;

   kodROM = &kub;
   USART_Transmit('S');
   _delay_ms(300);
   USART_Transmit('T');
   _delay_ms(300);
   USART_Transmit('A');
   _delay_ms(300);
   USART_Transmit('R');
   _delay_ms(300);
   USART_Transmit('T');
   USART_Transmit(0x0d);
   USART_Transmit(0x0a);

      USART_Transmit_str("Privet");
      USART_Transmit(0x0d);
      USART_Transmit(0x0a);

         
   for(uint8_t i=0;i<8;i++)
   {
      unsigned char c;
      c=*kodROM;
      USART_Transmit(c);
      kodROM++;
   }


Теперь выводит START потом 8 байт FF вместо Privet и 8 байт FF вместо 28 61 35 7C 06 00 00 D7
Но ведь в пошаговой симуляции прекрасно видно как оно все правильно делается, а в железе нет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 18:09 
Старожил

Зарегистрирован: 15 ноя 2015, 12:11
Сообщения: 200
Если посимвольный вывод работает - для эксперимента вставьте в цикле while(*st) задержку после вызова USART_Transmit(*st++), чтобы убедиться, что с логикой перебора строки всё в порядке. Строковые литералы сам компилятор добивает \0-терминатором. У постфикс-инкремента приоритет выше, чем у разыменования, и возвращает он предыдущее значение переменной, которое и разыменовывается, чтобы получить unsigned char который требуется USART_Transmit-у.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 18:27 
Только пришел

Зарегистрирован: 05 фев 2020, 11:58
Сообщения: 11
siarzhuk писал(а):
Если посимвольный вывод работает - для эксперимента вставьте в цикле while(*st) задержку после вызова USART_Transmit(*st++), чтобы убедиться, что с логикой перебора строки всё в порядке. Строковые литералы сам компилятор добивает \0-терминатором. У постфикс-инкремента приоритет выше, чем у разыменования, и возвращает он предыдущее значение переменной, которое и разыменовывается, чтобы получить unsigned char который требуется USART_Transmit-у.

Попробовал с задержкой, все тоже самое. Попробовал в Протеусе - все ок, а в железе нет. Сменил плату контроллера, я использую Ардуино Мега2560 - не помогло.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 06 фев 2020, 22:48 
Старожил

Зарегистрирован: 19 мар 2011, 05:05
Сообщения: 3066
хихи.
мне такое вообще выдало
Segmentation fault: 11

только это же какая-то билиберда в самом коде?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 06:04 
Только пришел

Зарегистрирован: 05 фев 2020, 11:58
Сообщения: 11
goreprogrammist писал(а):
хихи.
мне такое вообще выдало
Segmentation fault: 11

только это же какая-то билиберда в самом коде?

Как правильно код написать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 07:10 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 2629
Почему ждем опустошение приемника, это при передачи то?
Может лучше ждать конца отправки байта?
Цитата:
while ( !(UCSR0A & (1<<UDRE0)) ); //Ожидание опустошения буфера приема


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 07:16 
Старожил
Аватара пользователя

Зарегистрирован: 26 окт 2013, 07:58
Сообщения: 2629
Я делаю прием/передачу по UART на прерываниях + кольцевой буфер.
Прерывания по поступлению байта и по отправке.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 12:58 
Заглядывает иногда

Зарегистрирован: 23 мар 2010, 20:28
Сообщения: 49
Fil1, покажите код инициализации, может там затык.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 17:38 
Только пришел

Зарегистрирован: 05 фев 2020, 11:58
Сообщения: 11
Dust112 писал(а):
Fil1, покажите код инициализации, может там затык.

Код:
void USART_Init( unsigned int ubrr)//Инициализация модуля USART
{
   
   UBRR0H = (unsigned char)(ubrr>>8);
   UBRR0L = (unsigned char)ubrr;
   
   UCSR0B |= ( 1<<TXEN0); //(1<<RXEN0)| Включаем  передачу по USART
   //UCSR0B |= (1<<RXCIE0); //Разрешаем прерывание при передаче
   UCSR0A |= (1<<U2X0); //
   UCSR0C |= (1<<UCSZ01)|(1<<UCSZ00);//
}

void USART_Transmit( unsigned char data ) //Функция отправки данных
{
   while ( !(UCSR0A & (1<<UDRE0)) ); //Ожидание опустошения буфера данных
   UDR0 = data; //Начало передачи данных
}

void USART_Transmit_str(const char *str ) //Функция отправки строки по usart
{
   
   while(*str)
   {
      
      USART_Transmit(*str);
      str++;
      _delay_ms(100);
   }
}


int main(void)
{
   USART_Init(34);//При 16МГц кварце 34-57600 16-115200
   

   USART_Transmit('S');
   _delay_ms(300);
   USART_Transmit('T');
   _delay_ms(300);
   USART_Transmit('A');
   _delay_ms(300);
   USART_Transmit('R');
   _delay_ms(300);
   USART_Transmit('T');
   USART_Transmit(0x0d);
   USART_Transmit(0x0a);
      USART_Transmit_str("Privet");
      USART_Transmit(0x0d);
      USART_Transmit(0x0a);

         
   while (1)
   {
   }
}

Литеры передает, строку-нет, переменные-нет.
Запустил этот же код на плате Ардуино нано - все работает как надо даже регистры править не надо было.
Загрузил бутлоадер в мегу2560, попробывал скетчи ардуиновские- Сериалпринт работает как надо
Что можно еще попробывать?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 20:24 
Старожил

Зарегистрирован: 19 мар 2011, 05:05
Сообщения: 3066
а объяви эту строчку и попробуй скормить функции
const char buf[] = "trulyalya\n";
и потом без const (такое ведь имеет право на жизнь?):
char buf[] = "oi\n";


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 21:50 
Старожил
Аватара пользователя

Зарегистрирован: 01 дек 2013, 18:06
Сообщения: 232
Откуда: г. Волгоград.
А у меня так
Код:
void UART_send_st (const unsigned char *st)
{
   while(*st) {
      USART_Transmit(*st); // Передаются данные из разыменованого указателя
      st++; // Указатель двигается дальше.
   }
}


отказалось работать, а предыдущий вариант работает отлично


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Не могу передать строку по uart
СообщениеДобавлено: 07 фев 2020, 23:55 
Старожил

Зарегистрирован: 04 окт 2012, 00:23
Сообщения: 2745
Откуда: Москва
Какой проц? Где смотрите белиберду?


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


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


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

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


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

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

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