Salk 0 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба Наверняка эта "проблема" уже избитая и банальна, но я столкнулся с ней в первые и хочется понять её природу. Суть такая, имеется код для работы с внешним АЦП MCP3421 по I2c. Вот тут я его инициализирую его (посылаю cfg байт): uint8_t cfg_MCP3421_18bit_PGA8 = 0x1F; // Ждем готовности на шине I2c while(HAL_I2C_IsDeviceReady(&hi2c3, 0xD0, 1, HAL_MAX_DELAY) != HAL_OK); // Шлем конфигурационный байт HAL_I2C_Master_Transmit_IT(&hi2c3, 0xD0, &cfg_MCP3421_18bit_PGA8, 1); И дальше принимаем 4 байта данных (4й - подтверждение введенного конфига). В такой редакции все работает. Но если я хочу эти две строчки обернуть в функцию и вызвать её, передав тот же конфигурационный байт, то ничего не выходит. При приеме какой-то левый мусор, явно конфигурационный байт посылается неверный. uint8_t cfg_MCP3421_18bit_PGA8 = 0x1F; // Функция инициализации АЦП Init_I2c_MCP3421(&hi2c3, cfg_MCP3421_18bit_PGA8); // Сама функция void Init_I2c_MCP3421(I2C_HandleTypeDef *hi2c, uint8_t cfg) { // ждем готовности на шине I2c while(HAL_I2C_IsDeviceReady(hi2c, 0xD0, 1, HAL_MAX_DELAY) != HAL_OK); // Шлем конфигурационный байт HAL_I2C_Master_Transmit_IT(hi2c, 0xD0, (uint8_t*)&cfg, 1); } // Структура фунц. приема: "HAL_I2C_Master_Transmit_IT(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint8_t *pData, uint16_t Size)" В чем разница этих двух подходов понять не могу. Передаю в функцию обычный байт, он там принимается, cfg становится равный cfg_MCP3421_18bit_PGA8 = 0x1F - это видно при отладке, но по I2c улетает фиг знает что. Еще работает, если в функции, перед отправкой по I2c, байт cfg предварительно перезаписать в любую глобальную переменную, и её уже в свою очередь отправлять. Если объявить буферную переменную, как локальную внутри функции, то работать уже не будет. uint8_t CFG = 0; void Init_I2c_MCP3421(I2C_HandleTypeDef *hi2c, uint8_t cfg) { CFG = cfg; // I2c_Transmited_Block(&hi2c3, addr_MCP3421_Write, cfg_MCP3421_18bit_PGA1); // I2c_Transmited_Mem(&hi2c3, addr_MCP3421_Write, cfg_MCP3421_18bit_PGA1); while(HAL_I2C_IsDeviceReady(hi2c, addr_MCP3421_Write, 1, HAL_MAX_DELAY) != HAL_OK); HAL_I2C_Master_Transmit_IT(hi2c, addr_MCP3421_Write, (uint8_t*)&CFG, 1); } Думал, может компилятор голову морочит, но на разных режимах оптимизации и полностью без неё (NONE) результат один. Пишу на HAL в Cube IDE. Вред ли это проблема с HAL, скорее что-то чисто СИ-шное :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alag57 0 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба HAL_I2C_Master_Transmit_IT(hi2c, 0xD0, cfg, 1); Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба В 01.07.2022 в 19:24, Salk сказал: В чем разница этих двух подходов понять не могу. Передаю в функцию обычный байт, он там принимается, cfg становится равный cfg_MCP3421_18bit_PGA8 = 0x1F - это видно при отладке, но по I2c улетает фиг знает что. В том, что: в 1-м случае вы функции HAL_I2C_Master_Transmit_IT() передаёте указатель на переменную в глобальной памяти; а во 2-м - указатель на переменную в автоматической памяти (на стеке). И если эта функция - не блокирующая (завершает выполнение не завершив использование данных по переданному указателю), то после выхода из вашей Init_I2c_MCP3421() переданная в HAL_I2C_Master_Transmit_IT() переменная будет разрушена. В 01.07.2022 в 19:24, Salk сказал: Пишу на HAL в Cube IDE. Вот в этом-то и беда... всего этого кубокодерства.... 100500 раз уже писалось..... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба On 7/1/2022 at 7:40 PM, jcxz said: Вот в этом-то и беда... всего этого кубокодерства.... 100500 раз уже писалось..... Проблема не в Кубе, а в знании С. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salk 0 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба Понял, принял, спасибо. Пойду дальше нубить. Не ракеты на Марс все же отправляю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Salk 0 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба Что-то не то. Цитата HAL_I2C_Master_Transmit_IT(hi2c, 0xD0, cfg, 1); Init_I2c_MCP3421(&hi2c3, cfg_MCP3421_18bit_PGA8); void Init_I2c_MCP3421(I2C_HandleTypeDef *hi2c, uint8_t cfg) { while(HAL_I2C_IsDeviceReady(hi2c, addr_MCP3421_Write, 1, HAL_MAX_DELAY) != HAL_OK); HAL_I2C_Master_Transmit_IT(hi2c, addr_MCP3421_Write, cfg, 1); } // Получаю предупреждение "passing argument 3 of 'HAL_I2C_Master_Transmit_IT' makes pointer from integer without a cast " И не работает. Цитата а во 2-м - указатель на переменную в автоматической памяти (на стеке). Какой тогда выход? Я действительно в ступоре, куда хоть копать скажите, что искать. Только не кидайтесь всей книгой по СИ целиком :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 184 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба В 01.07.2022 в 20:40, Salk сказал: Какой тогда выход? Я действительно в ступоре, куда хоть копать скажите, что искать. Только не кидайтесь всей книгой по СИ целиком :) Во-первых: внимательно изучить требования функции HAL_I2C_Master_Transmit_IT() которую используете (раз уж предпочитаете жить не своим умом). В её описании должно быть упоминание о характере работы функции (блокирующая/неблокирующая) и о требованиях к времени жизни данных передаваемых в неё по указателю. Если описания нет - изучить код функции и всех других, которые она вызывает. Во-вторых: обеспечить требования к данным переданным в функцию. Если функция неблокирующая - значит должен быть какой-то способ ожидания завершения использования ею переданных ей данных. (ожидания заверешния транзакции). Или найти другую функцию (либо блокирующую либо которой можно передать данные в динамической памяти и которыми она владеет с момента передачи). Или ещё как. Способов может быть 100500. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
alag57 0 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба &cfg Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
x893 35 1 июля, 2022 Опубликовано 1 июля, 2022 · Жалоба On 7/1/2022 at 7:40 PM, jcxz said: Вот в этом-то и беда... всего этого кубокодерства.... 100500 раз уже писалось..... Проблема не в Кубе, а в понимании работы процессора на основе написанных текстов. А главное не менять cfg пока не будет вызван callback Первый способ - неправильный. Второй - правильный Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться