Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.56/140: Рейтинг темы: голосов - 140, средняя оценка - 4.56
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155

Младший и старший байт и запись 16 битных чисел на ардуино

28.12.2017, 11:40. Показов 29477. Ответов 41
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Доброе утро коллеги!
Изучаю протокол один, и тут нужно :
1) Записать данные с помощью младшего и старшего байта.
2)Все данные в структуре должны быть в 16-ричной форме.

Отсюда вытекает вопрос, подскажите на примере , как превратить число определенное , например в диапозоне от 0 до 1000 в младший и старший байт. Так же ни когда не работал с 16-ричной системой (программирование учил по учебникам, поэтому я нуб), подскажите как правильно на ардуинке писать в структуру такие данные, так как протокол это требует.

Заранее спасибо!
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
28.12.2017, 11:40
Ответы с готовыми решениями:

Функция: изменить старший байт числа на заданное значение, не изменяя младший байт
функция изменяет старший байт числа на заданное значение не изменяя младший байт. как можно проще

Скетч для ардуино: разделить на младший и старший бит
Здравствуйте, помогите со скетчем, нужно разделить на младший и старший бит int microsec = 0; int stepp = 1; void setup() { ...

Как получить младший байт и его старший бит
Подскажите как получить младший байт и его старший бит. И как сделать замену старшего бита младшего байта на противоположный? Работа с...

41
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 11:46
Лучший ответ Сообщение было отмечено MaximusL как решение

Решение

Если не изменяет память, для этого там предусмотрены cпециальные макросы:
C++
1
2
HIGH(x);
LOW(x);
Или не там..
Но можно и самому наколхозить:
C++
1
2
3
4
5
6
7
short x;
char y;
y = x & 0xFF; // Можно просто y = x; если левый операнд типа char или y = (char) x; если более широкого типа. Это LOW
y = (x >> 8) & 0xFF; // Можно просто y = x >> 8; если левый операнд типа char или y = (char)(x >>8); если более широкого типа. Это HIGH
 
#define LOW(x) (x & 0xFF)
#define HIGH(x) ((x >> 8) & 0xFF)
1
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 11:53  [ТС]
Так, с эти разобрались.
Теперь еще вопрос:
Как подсчитать контрольную сумму? Формула: Parameter code to be written ×256 + 67+ parameter to be written + ADDR
Parameter code to be written = 00H
Parameter to be written - (из описания) Parameter to be written: are specified using 16 binary system.
ADDR = 1

Че то ничего не получается.
Например с даннми которые хочу записать=999
Младший байт=3,
Старший байт =231

Контрольную сумму считаю так:0*256+67+999+1 ?????
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 11:56
Сылочку можно на функцию? Что-то не вкурю из ваших описаний, чего они там хотят.
0
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 11:59  [ТС]
Пожалуйста : https://yadi.sk/i/ifrEqsR-3QzYD4
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 12:07
Ну, вроде так, только там приписочка, что чек-сумма при записи сначала пишется младший байт, потом старший.
Попробуйте вот ту сумму, что у вас получилась, сначала записать LOW(summ), потом HIGH(summ)
И вообще, перемененую summ объявить как short, т.е. 16-битной
0
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 12:13  [ТС]
Прошу прощения, я можно поконкретнее ?))
Правильно я понял : 0*256+67+low byte+high_byte+1 ???

Добавлено через 59 секунд
А структура у меня вот такая получилась:
C++
1
2
3
4
5
6
7
8
         struct packet_in_reaktor{
      short addr; //int16_t?
      char func_code;//43H(67) - запись
      char param_cod;//00H - SV
      char low_byte;
      char high_byte;
      short check_code;//Parameter code to be written  ×256 + 67+ parameter to be written + ADDR
    };
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 12:16
Лучший ответ Сообщение было отмечено MaximusL как решение

Решение

summ = 0*256+67+999+1 = 1067;
LOW(summ) = 43;
HIGH(summ) = 4;

Добавлено через 1 минуту
Есть специальные typedef-ы, из которых сразу видно размер:
C++
1
2
3
4
uint_8t
uint_16t
uint_32t
uint64_t
Добавлено через 1 минуту
C++
1
2
3
4
5
6
7
8
struct packet_in_reaktor{
      uint16_t addr; //int16_t?
      uint8_t func_code;//43H(67) - запись
      uint8_t param_cod;//00H - SV
      uint8_t low_byte;
      uint8_t high_byte;
      uint16_t check_code;//Parameter code to be written  Г—256 + 67+ parameter to be written + ADDR
    };
1
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 12:19  [ТС]
Спасибо большое !!
И последний глупый вопрос, и буду кавырятся сам : как запихнуть в check_code (2 байта) корректно младший и старший?
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 12:20
Лучший ответ Сообщение было отмечено MaximusL как решение

Решение

Да, самое главное забыли! )))

Выравнивание надо убрать)
C++
1
2
3
4
5
6
7
8
9
10
#pragma pack(push,1)
struct packet_in_reaktor{
      uint16_t addr; //int16_t?
      uint8_t func_code;//43H(67) - запись
      uint8_t param_cod;//00H - SV
      uint8_t low_byte;
      uint8_t high_byte;
      uint16_t check_code;//Parameter code to be written  Г—256 + 67+ parameter to be written + ADDR
    }; 
#pragma pack(pop)
Цитата Сообщение от MaximusL Посмотреть сообщение
И последний глупый вопрос, и буду кавырятся сам : как запихнуть в check_code (2 байта) корректно младший и старший?
они и так сами запишутся. по умолчанию младший байт идет по младшему адресу. ничего специально городить не надо.
1
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 12:25  [ТС]
Это как и что это? )))))
Спасибо Вам большое за помощь, но попрошу по развернутее пожайлуста)))))

Добавлено через 2 минуты
Спасибо!!!!!
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 12:26
Про выравнивание структур погуглите сами - материала полно.
Советую также написать функцию, которая, заполняла бы правильно структуру, а вы бы в нее только передавали параметры для записи.

Структуры для чтения также стоит сделать упакованными. Иначе ваш протокол не будет работать
0
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 13:39  [ТС]
Пока не хочет работать ... вот код:
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
42
43
44
45
46
47
48
49
50
51
52
53
#define DIR 8 // переключатель прием\передача
 
#pragma pack(push,1)
struct packet_in_reaktor {
  uint16_t addr; //int16_t?
  uint8_t func_code;//43H(67) - запись
  uint8_t param_cod;//00H - SV
  uint8_t low_byte;
  uint8_t high_byte;
  uint16_t check_code;//Parameter code to be written  ×256 + 67+ parameter to be written + ADDR
  void pask(short tmp)
  {
    check_code = param_cod * 256 + 67 + tmp + addr;
  }
};
#pragma pack(pop)
 
struct answer {
  uint16_t pv;//PV ,int16_t??
  uint16_t sv;//SV
  uint8_t mv;//MV
  uint8_t alarm;//??
  uint16_t param;//параметр чтения или записи
  uint16_t check_code;//PV+SV+( Alarm status×256+MV)+ parameter read/written + ADDR
};
 
packet_in_reaktor pack = {1,67,0,0,0,0};
 
void setup() {
  Serial.begin(9600);
  Serial2.begin(9600);
  pinMode(DIR, OUTPUT);
}
 
void loop() {
  
  float a = 0;
  unsigned short Number = 140;
  unsigned char  High  = (Number >> 8) & 0xFF;
  unsigned char  Low   = Number & 0xFF;
  pack.low_byte = Low;
  pack.high_byte = High;
  pack.pask(Number);
  byte* ptr28 = (byte* )&pack;
  
  digitalWrite(DIR, HIGH); // включаем передачу
  Serial2.write(ptr28, sizeof(packet_in_reaktor));
  
  digitalWrite(DIR, LOW); // включаем прием
  a = Serial2.read();
  Serial.println(a);
  //Serial.println(pack.check_code);
}
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 17:05
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#define DIR 8 // переключатель прием\передача
#define READ 0x52
#define WRITE 0x43
#define SV 0x00
#define HIAL 0x01
#define LoAL 0x02
...
 
#pragma pack(push,1)
struct packet_in_reaktor {
  uint8_t addr_low;
  uint8_t addr_high;
  uint8_t func_code;//43H(67) - запись
  uint8_t param_code;//00H - SV
  uint16_t value;
  uint16_t check_code;//Parameter code to be written  Г—256 + 67+ parameter to be written + ADDR
};
#pragma pack(pop)
 
#pragma pack(push,1)
struct answer {
  uint16_t pv;//PV ,int16_t??
  uint16_t sv;//SV
  uint8_t mv;//MV
  uint8_t alarm;//??
  uint16_t param;//параметр чтения или записи
  uint16_t check_code;//PV+SV+( Alarm statusГ—256+MV)+ parameter read/written + ADDR
};
#pragma pack(pop)
 
void write_send_struct(packet_in_reaktor& pack, uint8_t addr, uint8_t op, uint8_t param, uint16_t value=0) {
  pack.addr_high = pack.addr_low = addr + 0x80;
  pack.func_code = op;
  pack.param_code = param;
  pack.value = value;
  pack.check_code = (param << 8) + op + value + addr;
}
 
void setup() {
  Serial.begin(9600);
  Serial2.begin(9600);
  pinMode(DIR, OUTPUT);
}
 
void loop() {
  packet_in_reaktor pack;  
  float a = 0;
 
  write_send_struct(pack, 1, WRITE, SV, 140);
    
  digitalWrite(DIR, HIGH); // включаем передачу
  Serial2.write((byte* )&pack, sizeof(pack));
  Serial2.flush(); // принудительно очищаем буфер. Правильное название функции тоже посмотрите
 
  delay_ms(100); // ждем, пока эта хрень передастся. Правильное название функции нагуглите сами
  
  digitalWrite(DIR, LOW); // и только после этого выключаем прием
  a = Serial2.read();
  Serial.println(a);
  //Serial.println(pack.check_code);
   delay_ms(2000);
}
Добавлено через 1 минуту
Осциллограф-то есть ткнуться?

по поводу
C++
1
a = Serial2.read();
не уверен.
1
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 17:05  [ТС]
Осциллографа нет((.
Да, данные вообще не приходят, молчит коробка.
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 17:12
Отправьте с одного порта ардуины на другой и посмотрите, что пришло
Или на комп отправьте
Отредактировал там еще раз код

Добавлено через 5 минут
Хотя, если serial принудительно флашить, то задержку не надо делать - только мешать будет.
0
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 17:16  [ТС]
Если отправлять просто на Com порт обычным Serial то приходит так как и задумано. Ладно, я поставлю еще один преобразователь Rs485, замкну передачу на него и посмотрю. Если контроллер молчит, то я правильно понимаю что он ответит только когда прилетит к нему вменяемый пакет?
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 17:43
Все от реализации зависит. Либо молчать будет, либо ругнется, что была ошибка. Надо доку курить

Добавлено через 2 минуты
Попробуйте на другой скорости. там еще 4800 есть и 19200. Мож скорость ему не нравится

Добавлено через 3 минуты
Посмотрите главу 5. Попробуйте настроить uart на 2 стоп бита и отправить последовательность
CHR$(129)+CHR$(129)+CHR$(67
)+CHR$(0)+CHR$(232)+CHR$(3)+CHR$(44)+CHR $(4)
Попробуйте с компа отправить

Добавлено через 1 минуту
Какая там вообще дефолтная скорость по доке?
1
2 / 2 / 0
Регистрация: 12.05.2015
Сообщений: 155
28.12.2017, 17:43  [ТС]
по скорости в настройках самого контроллера стоит 9600. Ладно буду ковырятся на праздниках, забрать домой его придется на праздники....отпишусь
0
73 / 86 / 40
Регистрация: 02.11.2017
Сообщений: 379
28.12.2017, 17:46
А адрес у него где выставляется? перемычками какими? Может, адрес не правильно выставлен?
Цитата Сообщение от MaximusL Посмотреть сообщение
Ладно буду ковырятся на праздниках, забрать домой его придется на праздники....отпишусь
А вот это зря.. Нехорошо работу домой забирать.. ))
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
28.12.2017, 17:46
Помогаю со студенческими работами здесь

Как в четырехбайтовом числе поменять местами старший и младший байт?
Помогите пожалуйста! Как в четырехбайтовом числе поменять местами старший и младший байт

Как получить младший (старший) байт целого числа (2-байтового)?
Как получить младший (старший) байт целого числа (2-байтового) Есть код в delphi var PG_1, PG_2 : Word; PG: Byte; Block:...

Вывести старший и младший байт заданного целого положительного числа в шестнадцатиричном и двоичном виде
Дано целое положительное число , тип int. Вывести старший и младший байт в 16ом и в 2ом виде.

Для целого числа А выделить старший байт и поставить его на место младшего байта. старший байт при этом обнулить.
Помогите пожалуйста, вообще не могу понять как делать следующее...Еще и в программе CODE BLOCKS препод почему именно эту программу...

Асемблер AVR Stydio. Найти сумму чисел 9701 и 32. Младший байт результата умножить на 4.
7. Найти сумму чисел 9701 и 32. Младший байт результата умножить на 4. Поместить старший байт в порт PORTC. Сбросить младшую тетраду байта...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
SDL3 для Web (WebAssembly): Идентификация объектов на Box2D v3 - использование userData и событий коллизий
8Observer8 02.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-collision-events-sdl3-c. zip Сканируйте QR-код на мобильном и вы увидите, что появится джойстик для управления главным героем. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru