Форум программистов, компьютерный форум, киберфорум
C (Си)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.82/11: Рейтинг темы: голосов - 11, средняя оценка - 4.82
0 / 0 / 0
Регистрация: 06.07.2018
Сообщений: 124

Передать Struct в функцию

30.03.2020, 20:00. Показов 2435. Ответов 6
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Пишу код для stm32
Есть задача - читать и писать структуры в backUp регистры

Хочу написать функцию для этих целей, но вот беда. Я не знаю как передать Любую структуру в функцию
Пытаюсь вот так, но компилятор ругается на попытку присвоить data что либо

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#define BIT_EEPROM 16
uint8_t reg[] = {RTC_BKP_DR1,RTC_BKP_DR2,RTC_BKP_DR3,RTC_BKP_DR4,RTC_BKP_DR5,RTC_BKP_DR6,RTC_BKP_DR7,RTC_BKP_DR8,RTC_BKP_DR9,RTC_BKP_DR10};
void Write_Struct(void *data, uint8_t adr)
{
    for(uint8_t i = adr; i > sizeof(data)/BIT_EEPROM; i++)
    {
        uint16_t _data = data >> (i*BIT_EEPROM)? 0 : BIT_EEPROM; //Ошибка тут
        HAL_RTCEx_BKUPWrite(&hrtc, reg[i],_data);
    }
}
void Read_Struct(void *data, uint8_t adr)
{
    for(uint8_t i = adr; i > sizeof(data)/BIT_EEPROM; i++)
    {
        (uint16_t *)data = data << (uint16_t *)HAL_RTCEx_BKUPRead(&hrtc, reg[i]); //Ошибка тут
    }
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
30.03.2020, 20:00
Ответы с готовыми решениями:

Как передать в функцию структуру в типе void и вернуть в struct
Ну есть структура: struct STransmitCmdStruct { SOCKET Client; Popen po; }TransmitCmdStruct; И функция unsigned...

как передать struct в list
Доброго времени суток. Такой вопрос: есть определенная структура, в которой есть несколько полей typedef struct _person{ long...

Не получается передать enum в struct
Помогите с заданием не могу передать enum в struct Описать перечисление ArticleType определяющее типы товаров, и добавить...

6
 Аватар для _SayHello
874 / 535 / 175
Регистрация: 30.07.2015
Сообщений: 1,739
31.03.2020, 17:44
Лучший ответ Сообщение было отмечено Dima-chan как решение

Решение

Dima-chan,
такая штука у вас не прокатит, так как sizeof(data) это размер типа указателя на void a не структуры.
C
1
2
3
4
5
6
7
8
9
10
typedef struct
{
    uint16_t a;
    float b;
    uint32_t c;
}CustomStruct_t;
 
CustomStruct_t myStruct;
 
memcpy((void*)regs, (void*)&myStruct, sizeof(CustomStruct_t));
1
 Аватар для Voland_
1983 / 1276 / 131
Регистрация: 04.01.2010
Сообщений: 4,607
31.03.2020, 18:22
вот-вот. но обычно в вызов функции добавляют еще один аргумент: "size", чтобы указать количество элементов данных.
1
Почетный модератор
 Аватар для Humanoid
11553 / 4348 / 452
Регистрация: 12.06.2008
Сообщений: 12,453
01.04.2020, 01:59
Лучший ответ Сообщение было отмечено Dima-chan как решение

Решение

Цитата Сообщение от Dima-chan Посмотреть сообщение
uint16_t _data = data >> (i*BIT_EEPROM)? 0 : BIT_EEPROM; //Ошибка тут
У вас data - это указатель, а вы пытаетесь с ним работать как с числом. Если вы хотите представить этот указатель, как указатель на 16-битные значения, тогда:
C
1
uint16_t datau16 * = (uint16_t *)data;
Что бы получить число из этого указателя:
C
1
(datau16[i] >> (i * BIT_EEPROM)) ? 0 : BIT_EEPROM;
Это при условии, что я правильно понял, что вы пытаетесь сделать. Но мне кажется, что тут общий принцип неправильный... странно, что записывается либо 0, либо BIT_EEPROM (а не сами данные). Я с этими Backup-регистрами никогда не работал, но подозреваю, что должно быть так:
C
1
2
3
4
5
6
7
8
9
10
11
12
void Write_Struct(void *data, int len, uint8_t adr)
{
  uint16_t *data16 = (uint16_t *)data;
  for (int i = adr; i < len / 2; i++)
    HAL_RTCEx_BKUPWrite(&hrtc, reg[i], data16[i]);
 
  // если размер нечётный, то дописываем последний байт.
  // Можно этого не делать, если в цикле проверять "i < (len + 1) / 2" (т.е. округлять деление в большую сторону),
  // но в этом случае вместе с последним байтом будет записан байт из за пределов переданной структуры
  if (len & 1)
    HAL_RTCEx_BKUPWrite(&hrtc, reg[len / 2 + adr], data16[len / 2 + adr] & 0xff);  // "& 0xff" нужен, что бы обнулить байт, который находится за пределами данных
}
А использовать функцию по такому же принципу, как написал _SayHello:
Write_Struct(&mystruct, sizeof(mystruct), 0);
1
0 / 0 / 0
Регистрация: 06.07.2018
Сообщений: 124
01.04.2020, 06:01  [ТС]
Не знал об такой функции, думал сделать через битовые операции, но как оказалось, нельзя проводить битовые операции над структурами
а вот на счет memcpy, проблема в том что структура больше 16 бит, ведь регистры бекапа 16 битные,
Как мне выделить определенную область памяти (скажем первые 16 бит структуры)

Добавлено через 4 минуты
HumanoidM, я конечно потом понял про эти указатели и свои ошибки,
Свою ошибку я описал с низу
Мне вот интересно, как вы представили структуру в виде uint16?
Даже если получится (сегодня попробую проверить), а как мне эти из кусков uint16 обратно собрать с структуру?

Я вот пытался сделать так
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#define BIT_EEPROM 16
uint8_t reg[] = {RTC_BKP_DR1,RTC_BKP_DR2,RTC_BKP_DR3,RTC_BKP_DR4,RTC_BKP_DR5,RTC_BKP_DR6,RTC_BKP_DR7,RTC_BKP_DR8,RTC_BKP_DR9,RTC_BKP_DR10};
void Write_Struct(uint32_t *data, uint8_t adr, uint8_t size)
{
    uint8_t i;
    for(i = adr; i < ((size *8)/BIT_EEPROM + adr); i++)
    {
        uint16_t _data = (*data >> (i - adr)*BIT_EEPROM) >> ((i*BIT_EEPROM)? 0 : BIT_EEPROM);
        HAL_RTCEx_BKUPWrite(&hrtc, reg[i],_data);
    }
    char str[20];
        sprintf(str, "%d   %d   %d   %d   ", i,size, HAL_RTCEx_BKUPRead(&hrtc, reg[0]), data);
    LCDI2C_setCursor(0,2);
    LCDI2C_write_String(str);
}
void Read_Struct(uint32_t* data, uint8_t adr, uint8_t size)
{
    uint8_t i;
    for(i = adr; i < ((size *8)/BIT_EEPROM); i++)
    {
        *data |= (*data >> (i - adr)*BIT_EEPROM) >> HAL_RTCEx_BKUPRead(&hrtc, reg[i]);
    }
}
0
Модератор
Эксперт по электронике
8978 / 6744 / 921
Регистрация: 14.02.2011
Сообщений: 23,854
01.04.2020, 07:41
Dima-chan, открой для себя union, а так же приведение типов
и такие вопросы лучше задавать в ветке про Си, ибо к микроконтролерам они имеют весьма далекое отношение
0
0 / 0 / 0
Регистрация: 06.07.2018
Сообщений: 124
01.04.2020, 12:00  [ТС]
Эту тему перенес Модератор\Админ

Добавлено через 1 час 43 минуты
Всё получилось!
Все спасибо за помощь

Делюсь функциями
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
#define BIT_EEPROM 16
uint8_t reg[] = {RTC_BKP_DR1,RTC_BKP_DR2,RTC_BKP_DR3,RTC_BKP_DR4,RTC_BKP_DR5,RTC_BKP_DR6,RTC_BKP_DR7,RTC_BKP_DR8,RTC_BKP_DR9,RTC_BKP_DR10};
void Write_Struct(void *data, int len, uint8_t adr)
{
  uint16_t *data16 = (uint16_t *)data;
  for (int i = adr; i < len / 2; i++)
    HAL_RTCEx_BKUPWrite(&hrtc, reg[i], data16[i - adr]);
 
  // если размер нечётный, то дописываем последний байт.
  // Можно этого не делать, если в цикле проверять "i < (len + 1) / 2" (т.е. округлять деление в большую сторону),
  // но в этом случае вместе с последним байтом будет записан байт из за пределов переданной структуры
  if (len & 1)
    HAL_RTCEx_BKUPWrite(&hrtc, reg[len / 2 + adr], data16[len / 2 + adr] & 0xff);  // "& 0xff" нужен, что бы обнулить байт, который находится за пределами данных
}
void Read_Struct(void *data, int len, uint8_t adr)
{
    uint16_t _data[len];
    uint8_t i;
    for(i = adr; i < ((len *8)/BIT_EEPROM); i++)
    {
        _data[i-adr] = HAL_RTCEx_BKUPRead(&hrtc, reg[i]);
    }
    memcpy(data, &_data, len);
}
вызов
C
1
2
3
Write_Struct(&sit, sizeof(sit), 0);
    HAL_Delay(1000);
    Read_Struct(&sit2, sizeof(sit), 0);
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
01.04.2020, 12:00
Помогаю со студенческими работами здесь

Передать struct в новую форму (Загвоздка)
В общем обычно вместо struct использую классы, но на этот раз понадобился именно struct. Как то один хороший человек объяснил мне, что...

Передача struct в функцию
Всех приветствую! Я что-то не понял как передать struct в функцию. Код такой: *.cpp #include &lt;vcl.h&gt; #pragma hdrstop ...

Объявить функцию в STRUCT {} С++
Доброй ночи Создаю меню в консоле Задумка такая - для каждого пункта меню запускать свою функцию Как функцию объявить в структуре...

Не могу разобраться как передать корректно передать массив из функции в функцию
//--------------------------------------------------------------------------- #pragma hdrstop ...

Написать функцию, которая могла бы передать значение в другую функцию
как сделать функцию которая бы могла передать значеие в другую функцию ну к примеру a=4*b; где b=sin(fi);


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

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru