Форум программистов, компьютерный форум, киберфорум
Микроконтроллеры ATmega AVR
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/41: Рейтинг темы: голосов - 41, средняя оценка - 4.90
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
1

Формирование пакета данных для передачи по UART

14.06.2015, 09:43. Показов 7376. Ответов 18
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
...доброго времени суток, уважаемые форумчане! Возник вопрос: имеется ли в CodeVisionAVR 1.25 для ATmega8 тип данных эквмвалентный AnsiString в C++?
Если - да, то как он называется и какую библиотеку нужно подключить?
Если - нет, то как сформировать такой пакет для передачи (на языке Си):
<число[int]> + <' '[пробел - как разделитель]> + <число[int]> + <' '[пробел - как разделитель]> <число[int]>; тип данных - char или unsigned char. В частности, на C++ это решается очень просто:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Константа
   AnsiString data1 = "255";
// Данные для передачи после вычислений
   int data2 = 120;
   int data3 = 60;
   int data4 = 100;
// Преобразование
   AnsiString Adata2 = IntToStr(data2);
   AnsiString Adata3 = IntToStr(data3);
   AnsiString Adata4 = IntToStr(data4);
// Создать строку для передачи
   AData_Full = Adata1 + " " + Adata2 + " " + Adata3 + " " + Adata4 + " " + data1;
// Занести в программный передающий буфер
   strcpy(BufWr, AData_Full.c_str());
Заранее благодарен за ответ.
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.06.2015, 09:43
Ответы с готовыми решениями:

Сжатие данных для передачи по UART
Добрый день! Контроллер передаёт по UARTу данные (числа разделённые знаком табуляции в формате...

Софтварный uart на tiny 26. Частота передачи данных.
И снова здравствуйте! Появилась у меня тут необходимость передавать данные с устройства на...

Выбор сетевого адаптера для передачи UDP пакета
Доброго времени суток. Опишу в кратце задачу для понимания: имеется несколько устройств общающихся...

Отправка пакета URB для ИЗОХРОННОЙ передачи в коде драйвера
Приветствую всех кодокопателей! Ниже приведен код отправки URB для драйвера шины USBD.sys . Вся...

Перевод массива из 16 битной в 8 битную систему для передачи в UART в MPLAB
#define ITT 10 // 10 iterations int ResultRC; void InitApp(void) { Parameters(); ...

18
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
14.06.2015, 11:08 2
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
<число[int]> + <' '[пробел - как разделитель]> + <число[int]> + <' '[пробел - как разделитель]> <число[int]>; тип данных - char или unsigned char
функцию sprintf знаешь?
C
1
2
char buf[256];
sprintf(buf,"%d %d %d",i1,i2,i3);
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
частности, на C++ это решается очень просто:
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
AnsiString data1
ты плюсы то с бульдером не путай
1
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
14.06.2015, 18:01  [ТС] 3
ValeryS, большое спасибо! действительно забыл про эту функцию: вот, что значит "хронически" пользоваться Visual Studio и Borland C++ Builder Сделал так:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
void main(void)
{
   bit on = 0; 
// ****  Данные для передачи  ****
// Защитный байт
   int Protect_Byte = 255;
// Значение pH
   int Out_pH = 120;
// Знчение темперватуры   
   int Out_Temp = 65; 
// Значение тока   
   int Out_Curr = 100; 
// -------------------------------------
// Инициализация объектов 
// .............................
while (1)
      {
       if(PINC.0==0 && on==0)
        {
        // ****  Передача данных  ****
        // Защитный байт 
           printf("%d", Protect_Byte); 
        // Значение pH
           printf(" %d", Out_pH); 
        // Температура
           printf(" %d", Out_Temp); 
        // Значение тока       
           printf(" %d", Out_Curr); 
        // Защитный байт
           printf(" %d", Protect_Byte);  
           on = 1;  
        }
       
       if(PINC.0 != 0)
        {
       on = 0;
        }
     };
}
...теперь передает так, как нужно, но "тормозит" комп (при моделировании в Proteus-е)... Подозреваю, что проблема в бесконечном цикле, а на реальном "железе" думаю, такого не будет или я ошибаюсь?
И еще вопрос: а как решить обратную задачу, т. е. "разобрать" принятую строку (формат и структура данных такие же)? В билдере эта задача решается элементарно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 // Прочитать байты из порта в буфер программы
      ReadFile(COMport, BufRd, Btr, &Temp, NULL);
 // Вызываем функцию для вывода данных в переменные 
     Synchronize(Printing);
 // --- Что-то делаем
     AnsiString Str_pH, Str_Temp, Str_Curr;
  // Выводим принятую строку в Memo
     char *Pstr;
     Pstr = strtok(BufRd, " ");
    while (Pstr != NULL)
     {
        Form1 -> Memo1 -> Lines -> Add(Pstr);
        Pstr = strtok(NULL, " ");
     }
  // Очистить буфер, чтобы данные не накладывались друг на друга
     memset(BufRd, 0, BUFSIZE);
  // Записать принятые байты в переменные
     Str_pH = Form1 -> Memo1 -> Lines -> Strings[1];
     Str_Temp = Form1 -> Memo1 -> Lines -> Strings[2];
     Str_Curr = Form1 -> Memo1 -> Lines -> Strings[3];
  // На всякий случай обрезаем возможные пробелы
     Str_pH = Str_pH.Trim();
     Str_Temp = Str_Temp.Trim();
     Str_Curr = Str_Curr.Trim();
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
14.06.2015, 18:22 4
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
а как решить обратную задачу, т. е. "разобрать" принятую строку
а примерно так же
есть функция sscanf
http://lord-n.narod.ru/downloa... sscanf.htm

Добавлено через 2 минуты
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
но "тормозит" комп (при моделировании в Proteus-е)... Подозреваю, что проблема в бесконечном цикле,
проблема может быть в printf, как он реализован? через UART? скорость обмена какая?
1
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
14.06.2015, 18:32  [ТС] 5
...да, UART; скорость - 9600... вот инициализации:
C
1
2
3
4
5
6
7
8
9
10
11
/* USORT initialization
 * Communication Parameters: 8 Data, 1 Stop, No Parity
 * USORT Receiver: Off
 * USORT Transmitter: On
 * USORT Mode: Asynchronous
 * USORT Baud Rate: 9600 */
   UCSRA=0x00; 
   UCSRB=0x08;
   UCSRC=0x86;
   UBRRH=0x00;
   UBRRL=0x33;
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
14.06.2015, 18:49 6
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
.да, UART; скорость - 9600...
я сейчас гоняю на 256000 и то бывает подтормаживает, правда у меня реальная железка
ну нет stm32 в протеусе
1
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
14.06.2015, 18:52  [ТС] 7
... т. е. до реализации в "железе" считать подтормаживание нормальным явлекнием?
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
14.06.2015, 19:03 8
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
т. е. до реализации в "железе" считать подтормаживание нормальным явлекнием?
не могу сказать, может и протеус сам тормозить это же эмулятор , может и винда, это все таки многопоточная система
смотри не на реальный отклик а на циферки внизу, они более точное время показывают
1
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
14.06.2015, 19:16  [ТС] 9
... и еще вопрос: не смогли бы Вы привести фрагмент кода по "разборке" строки и записи выделенной части в виде числа int?.. уже ничего не соображаю...
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
14.06.2015, 19:21 10
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
не смогли бы Вы привести фрагмент кода по "разборке" строки и записи выделенной части в виде числа int?
фрагмент строки дай
0
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
14.06.2015, 19:47  [ТС] 11
.... принимается с UART; тип данных - unsigned char; строка такая <число от 0 до 255; преобразовано из int><пробел; служит разделитлем><число от 0 до 255; преобразовано из int><пробел; служит разделитлем><и т. д.>
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
14.06.2015, 19:55 12
ну попробуй так
C++
1
sscanf(buf,"%d %d %d",&i1,&i2,&i3);
сам уже не помню является пробел разделителем или нет
скорми эту строку компилятору для большого компа и проверь, я часто так делаю когда сомнения возникают
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
число от 0 до 255
а зачем тебе int чем unsigned char не угодил ?
учти что 8битки для сложения вычитания Интов привлекают свои библиотеки, очень часто это тормозит
1
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
14.06.2015, 20:15  [ТС] 13
...в контроллер передаются два числа: одно для выбора режима - то ли "if - else if - else", то ли "switch-case" (посмотрю), а второе - хочу в цикле сформировать пачку импульсов для этого девайса (цифровой резистор)
Миниатюры
Формирование пакета данных для передачи по UART  
0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
14.06.2015, 21:53 14
Цитата Сообщение от ValeryS Посмотреть сообщение
я сейчас гоняю на 256000 и то бывает подтормаживает, правда у меня реальная железка
ну нет stm32 в протеусе
на скорости 256к у вас 25к прерываний в секунду, для получения нового байта данных из буфера в УАРТ. Соответственно, может уже и подтормаживать. Советую использовать выполнение функций из памяти и реализовывать передачу в УАРТ через DMA. Это лучшее, что можно предпринять в таких случаях. Работает не то что быстро - а "летает". )

2) Использовать для формирования строки функцию printf не рекомендовал бы. Для этого есть более шустрые itoa и прочие. Они выполнены по-проще, и работают намного быстрее.

3) ТС, вы использовали printf в качестве основной функции, передающей данные "в стандартный интерфейс". Я просто не был уверен, что CV AVR "стандартным интерфейсом по умолчанию" будет иметь именно ваш USORT1. Так ли это? Или вы где-то задали эту опцию отдельно? Обычно для того, чтобы использовать printf переопределяют функцию "putchar", которая и вызывается из стандартной printf для передачи данных.

4) Для парсинга значений я делал так: есть функция чтения значения из буфера типа: uint16_t getValue(char **buf); которая забирает значение из строки вплоть до символа разделителя или нулевого символа - окончания строки. Функция возвращает забранное значение и изменяет указатель, перемещая его к первому символу следующей цифры. Это очень удобно, когда вы хотите получить из буфера сразу несколько параметров.
2
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
15.06.2015, 06:18 15
Цитата Сообщение от Voland_ Посмотреть сообщение
на скорости 256к у вас 25к прерываний в секунду,
прерываний нет ну с точки зрения камня, а у машины скорее всего есть
пардон,забыл сказать это используется для отладки, printf используется как отладочная печать, передает в машину данные которые приходят по USB в камень
а для формирования DMX конечно никаких sprintf
Цитата Сообщение от Voland_ Посмотреть сообщение
Использовать для формирования строки функцию printf не рекомендовал бы. Для этого есть более шустрые itoa и прочие. Они выполнены по-проще, и работают намного быстрее.
если работаешь чисто с числами, а если нужен "весь зоопарк", тут или скорость или удобство
Цитата Сообщение от Voland_ Посмотреть сообщение
Для парсинга значений я делал так: есть функция чтения значения из буфера типа: uint16_t getValue(char **buf); которая забирает значение из строки вплоть до символа разделителя или нулевого символа - окончания строки. Функция возвращает забранное значение и изменяет указатель, перемещая его к первому символу следующей цифры. Это очень удобно, когда вы хотите получить из буфера сразу несколько параметров.
вполне здраво, но, по моему мнению, нужно сначала обкатать на общих случаях а потом оптимизировать
а то можно нарваться где косячит в протоколе или в обработке
2
77 / 77 / 11
Регистрация: 02.12.2011
Сообщений: 296
15.06.2015, 07:10  [ТС] 16
Цитата Сообщение от Voland_ Посмотреть сообщение
Для парсинга значений я делал так: есть функция чтения значения из буфера типа: uint16_t getValue(char **buf);
А можно подробнее и пример как это реалтзовать?.. никогда этой функцией не пользовался....
0
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
15.06.2015, 19:44 17
Цитата Сообщение от ValeryS Посмотреть сообщение
прерываний нет ну с точки зрения камня, а у машины скорее всего есть
как это нет? Вот здесь по-подробнее, как вы это реализовали. Свой вариант я расписал чуть выше.
Цитата Сообщение от Simulkin Stas Посмотреть сообщение
А можно подробнее и пример как это реалтзовать?.. никогда этой функцией не пользовался...
Конечно не пользовались, это самописная функция ).
Она парсит посимвольно данные из представленной строки. Если символ подходит под необходимое описание, то парсинг продолжается, если не подходит, то функция пытается найти следующий "подходящий" аргумент и выходит из функции. В результате вы получаете разобранное число или вообще - данные, и ссылку на следующие данные.
0
Модератор
Эксперт по электронике
8908 / 6677 / 918
Регистрация: 14.02.2011
Сообщений: 23,521
15.06.2015, 20:27 18
Лучший ответ Сообщение было отмечено Simulkin Stas как решение

Решение

Цитата Сообщение от Voland_ Посмотреть сообщение
как это нет? Вот здесь по-подробнее, как вы это реализовали.
чуть по позже распишу подробно, когда с делами разгребусь
а так на вскидку переписал
getc чтобы получать символ и putc чтобы отдавать

все остальное взял на себя Keil

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
int COM1_putchar( const char ch)
{
        while (USORT_GetFlagStatus(USORT1, USORT_FLAG_TC) == RESET);
        {}
        USORT_SendData(USORT1, (uint8_t) ch);
return 0;
}
 
#ifdef __cplusplus
 int std::putc(int ch,FILE *stream)
#else
int putc(int ch,FILE *stream)
#endif
 {
 
        volatile unsigned int i;
       if(ch=='\n')
          ch='\r';
       while (COM1_putchar (ch) != 0) {
          for (i=0; i<1000; i++) {
                /*** DO NOTHING ***/
            }
        }
        return (ch);
}
 
uint8_t Usart1_Get_symbol ()
 {
   while((USORT1->SR & USORT_SR_RXNE)==0) {}//ожидание приема
        return USORT1->DR;       //прочитать принятый байт
}
 
 
#ifdef __cplusplus
 int std::getc(FILE *stream)
 #else
int getc(FILE *stream)
 #endif
{
 return Usart1_Get_symbol ();
}
переписал это громко сказано, спер откуда то уже год где то пользуюсь
для отладки нормально, в реальном коде выбрасываю

Добавлено через 2 минуты
да забыл добавить УСБишка сидит вся на переываниях, так что циклы УСБ не мешают
а если бы я и работу с УСАРТ вел на прерываниях, пришлось бы как то регулировать прерывания
1
1976 / 1275 / 130
Регистрация: 04.01.2010
Сообщений: 4,607
15.06.2015, 21:07 19
ValeryS, я вас понял. Но это далеко не лучший вариант. Хотя, и совершенно не сложный.
0
15.06.2015, 21:07
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
15.06.2015, 21:07
Помогаю со студенческими работами здесь

Перевод массива из 16 битной в 8 битную систему для передачи в UART в MPLAB
#define ITT 10 // 10 iterations int ResultRC; void InitApp(void) { Parameters(); OSC();...

В массив записать разнородные данные для передачи этого пакета по сети
Доброго времени суток. Стоит задача следующего плана.. Есть некий массив, который будет передан по...

Просмотр передачи пакета
Здравствуйте! Подскажите пожалуйста есть ли программа, которая будет просматривать через какие...

UART настройка скорости передачи.
Здравствуйте форумчане, снова нужна ваша помощь, суть проблемы такая: имеется msp430 и LCD дисплей...

Метод передачи пакета в порт
Здрасте. Опят я в ступоре. Написал функцию или метод, как в C# это называется не важно, а он не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
19
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru