Компилятору виднее. Так, глядя на результат инверсии, sizeof(int) небось 2 рапортует.WiseLord писал(а):Но ведь это на 8-битном AVR происходило, вот в чём прикол.
Вопросы по С/С++ (СИ)
Re: Вопросы по С/С++ (СИ)
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Задал вопрос здесь, но всё же вопрос ближе к данному топику.
В общем, не могу понять почему членам структуры не присваиваются значения?
Код убрал под спойлер
В общем, не могу понять почему членам структуры не присваиваются значения?
Код убрал под спойлер
Спойлер
Код: Выделить всё
#include "stm32f2xx_hal.h"
CAN_HandleTypeDef hcan1;
static void MX_CAN1_Init(void);
int main(void)
{
while (1)
{
//Смотрю значения до присваивания и вывожу в UART. Результат следующий: по идее, там - мусор)
hcan1.pTxMsg->DLC = 0xF5;
hcan1.pTxMsg->Data[0] = 0xE1;
hcan1.pTxMsg->Data[1] = 0x01;
hcan1.pTxMsg->Data[2] = 0x00;
hcan1.pTxMsg->Data[3] = 0x08;
hcan1.pTxMsg->Data[4] = 0x1B;
hcan1.pTxMsg->Data[5] = 0x19;
hcan1.pTxMsg->Data[6] = 0x00;
hcan1.pTxMsg->Data[7] = 0x08;
//Присваиваю значения членам структуры pTxMsg
hcan1.pTxMsg->DLC = 0x08;
hcan1.pTxMsg->Data[0] = 0x00;
hcan1.pTxMsg->Data[1] = 0x01;
hcan1.pTxMsg->Data[2] = 0x02;
hcan1.pTxMsg->Data[3] = 0x03;
hcan1.pTxMsg->Data[4] = 0x04;
hcan1.pTxMsg->Data[5] = 0x05;
hcan1.pTxMsg->Data[6] = 0x06;
hcan1.pTxMsg->Data[7] = 0x07;
//Смотрю значения членов структуры после присваивания и вывожу в UART. Результат - тот же самый мусор
hcan1.pTxMsg->DLC = 0xF5;
hcan1.pTxMsg->Data[0] = 0xE1;
hcan1.pTxMsg->Data[1] = 0x01;
hcan1.pTxMsg->Data[2] = 0x00;
hcan1.pTxMsg->Data[3] = 0x08;
hcan1.pTxMsg->Data[4] = 0x1B;
hcan1.pTxMsg->Data[5] = 0x19;
hcan1.pTxMsg->Data[6] = 0x00;
hcan1.pTxMsg->Data[7] = 0x08;
}
}
/* CAN1 init function */
void MX_CAN1_Init(void)
{
hcan1.Instance = CAN1;
hcan1.Init.Prescaler = 5;
hcan1.Init.Mode = CAN_MODE_NORMAL;
hcan1.Init.SJW = CAN_SJW_1TQ;
hcan1.Init.BS1 = CAN_BS1_6TQ;
hcan1.Init.BS2 = CAN_BS2_5TQ;
hcan1.Init.TTCM = DISABLE;
hcan1.Init.ABOM = DISABLE;
hcan1.Init.AWUM = DISABLE;
hcan1.Init.NART = DISABLE;
hcan1.Init.RFLM = DISABLE;
hcan1.Init.TXFP = DISABLE;
HAL_CAN_Init(&hcan1);
}
Код: Выделить всё
* @file stm32f2xx_hal_can.h
typedef struct
{
CAN_TypeDef *Instance; /*!< Register base address */
CAN_InitTypeDef Init; /*!< CAN required parameters */
CanTxMsgTypeDef* pTxMsg; /*!< Pointer to transmit structure */
CanRxMsgTypeDef* pRxMsg; /*!< Pointer to reception structure */
__IO HAL_CAN_StateTypeDef State; /*!< CAN communication state */
HAL_LockTypeDef Lock; /*!< CAN locking object */
__IO uint32_t ErrorCode; /*!< CAN Error code */
}CAN_HandleTypeDef;
typedef struct
{
uint32_t Prescaler; /*!< Specifies the length of a time quantum.
This parameter must be a number between Min_Data = 1 and Max_Data = 1024 */
uint32_t Mode; /*!< Specifies the CAN operating mode.
This parameter can be a value of @ref CAN_operating_mode */
uint32_t SJW; /*!< Specifies the maximum number of time quanta
the CAN hardware is allowed to lengthen or
shorten a bit to perform resynchronization.
This parameter can be a value of @ref CAN_synchronisation_jump_width */
uint32_t BS1; /*!< Specifies the number of time quanta in Bit Segment 1.
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_1 */
uint32_t BS2; /*!< Specifies the number of time quanta in Bit Segment 2.
This parameter can be a value of @ref CAN_time_quantum_in_bit_segment_2 */
uint32_t TTCM; /*!< Enable or disable the time triggered communication mode.
This parameter can be set to ENABLE or DISABLE. */
uint32_t ABOM; /*!< Enable or disable the automatic bus-off management.
This parameter can be set to ENABLE or DISABLE */
uint32_t AWUM; /*!< Enable or disable the automatic wake-up mode.
This parameter can be set to ENABLE or DISABLE */
uint32_t NART; /*!< Enable or disable the non-automatic retransmission mode.
This parameter can be set to ENABLE or DISABLE */
uint32_t RFLM; /*!< Enable or disable the receive FIFO Locked mode.
This parameter can be set to ENABLE or DISABLE */
uint32_t TXFP; /*!< Enable or disable the transmit FIFO priority.
This parameter can be set to ENABLE or DISABLE */
}CAN_InitTypeDef;
typedef struct
{
uint32_t StdId; /*!< Specifies the standard identifier.
This parameter must be a number between Min_Data = 0 and Max_Data = 0x7FF */
uint32_t ExtId; /*!< Specifies the extended identifier.
This parameter must be a number between Min_Data = 0 and Max_Data = 0x1FFFFFFF */
uint32_t IDE; /*!< Specifies the type of identifier for the message that will be transmitted.
This parameter can be a value of @ref CAN_Identifier_Type */
uint32_t RTR; /*!< Specifies the type of frame for the message that will be transmitted.
This parameter can be a value of @ref CAN_remote_transmission_request */
uint32_t DLC; /*!< Specifies the length of the frame that will be transmitted.
This parameter must be a number between Min_Data = 0 and Max_Data = 8 */
uint8_t Data[8]; /*!< Contains the data to be transmitted.
This parameter must be a number between Min_Data = 0 and Max_Data = 0xFF */
}CanTxMsgTypeDefRe: Вопросы по С/С++ (СИ)
Свой вопрос снимаю
Re: Вопросы по С/С++ (СИ)
У меня тоже есть снова вопрос. Пишу в Keil-е. Есть функция для посылки данных через i2c описанная так:
Так вот, если я хочу в data передать длинную инициализационную последовательность. последовательность не меняется и потому в ОЗУ держать нет смысла. Значит объявляю константой:
В результате получаю ошибку:
Потом, почему-то, не позволет объявление этого массива сделать непосредственно рядом с вызовом этой функции (хотя IAR на это не возражал). Самое интересное, если бы инициализационные коды были бы печатные, то конструкция
пороходит, несмотря на то, что ему в данном случае передаётся константная строка.
Вопрос собственно и состоит, как эту инициализационную последовательность изящно засунуть в память программ не куроча функцию.
Код: Выделить всё
t_i2c_status i2c_wr_reg(unsigned char address, unsigned char reg_addr, char * data, unsigned char length);Код: Выделить всё
const char init_sequence[] = {
// Init sequence for 128x64 OLED module
SSD1306_DISPLAYOFF,
....
SSD1306_DISPLAYON //--turn on oled panel
}Код: Выделить всё
main.c(178): error: #167: argument of type "const char *" is incompatible with parameter of type "char *"
i2c_wr_reg(SD1306_I2C_ADDRESS, 0x00, init_sequence, sizeof(init_sequence));
main.c: 0 warnings, 1 errorКод: Выделить всё
i2c_wr_reg(SSD1306_I2C_ADDRESS, 0x00, "start_sequence", sizeof(init_sequence)); Вопрос собственно и состоит, как эту инициализационную последовательность изящно засунуть в память программ не куроча функцию.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
А если в аргументах функции передавать не прямо init_sequence, а с приведением типа: (char *)init_sequence?
Re: Вопросы по С/С++ (СИ)
Да, спасибо, этот вариант прокатил.
Ах! вот если бы еще была возможность передавать эти последовательности неименованными...
Ах! вот если бы еще была возможность передавать эти последовательности неименованными...
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Re: Вопросы по С/С++ (СИ)
А что говорит? Попробуйте static - это выпихнет локальную переменную в глобальную область, сохранив её видимость локальной.uldemir писал(а):Потом, почему-то, не позволет объявление этого массива сделать непосредственно рядом с вызовом этой функции (хотя IAR на это не возражал).
В строковый литерал можно запихать всё что угодно: "\x00\xFFHalli\xCCHallo!\x1F", ещё можно каждый код задефайнить как строчкуuldemir писал(а):Самое интересное, если бы инициализационные коды были бы печатные, то конструкция
#define AGA "\xFF"
#define OGO "\x00"
#define UGU "\xCC"
i2c_wr_reg( ..., AGA OGO UGU AGA, ...);
компилятор её склеит в один литерал и подставит при оформлении вызова.
константная строка и массив константных символов - судя по всему для него [компилятора] различные типы. Гораздо интереснее, что он не ругается на снятие const при такой передаче - ведь внутри функции это обычный указатель - в который функция может нагадить.uldemir писал(а):пороходит, несмотря на то, что ему в данном случае передаётся константная строка.
Вопрос в том, что семантика функции предполагает модификацию передаваемого буффера - мол, не огорожен указатель const-ом - не говорите что вас не предупреждали.uldemir писал(а):Вопрос собственно и состоит, как эту инициализационную последовательность изящно засунуть в память программ не куроча функцию.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Siarzhuk писал(а):А что говорит?
Код: Выделить всё
main.c(211): error: #268: declaration may not appear after executable statement in block
char start_col[] = {SSD1306_COLUMNADDR, 0, SSD1306_LCDWIDTH-1, SSD1306_PAGEADDR, 0, 7};
main.c: 0 warnings, 1 errorСпособ интересный, но тогда снова придётся делать два комплекта дефайнов - для констант и для строк. Ладно, попробую обойтись.Siarzhuk писал(а):В строковый литерал можно запихать всё что угодно: "\x00\xFFHalli\xCCHallo!\x1F",
О! это хорошо решает проблему. Спасибо. жаль только, не могу найти хорошую библиотеку для мастера I2C для stm32f0. Приходится дёргать огрызки из разных источников.Siarzhuk писал(а):У прожжёного дизайнера библиотек в определении отдаваемого на передачу буфера обязательно const будет.
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Re: Вопросы по С/С++ (СИ)
Добрый день, подскажите при модульном программировании в каких случаях подключение других модуль производить в .h файле а в каких в .c файле. Раньше об этом не задумывался и постоянно подключал все в .h но недавно начали вылазить ошибки типа циклическое включение заголовков, так как тогда не было времени сильно разбираться некоторые заголовки перемести в .с файл и все заработало. А вот теперь при формировании новых библиотек задумался где что подключать.
Re: Вопросы по С/С++ (СИ)
Чтобы не было циклического включения и повторного переопределения ставят в .h файлах "экран"
Код: Выделить всё
#ifndef _DRIVER_H_
#define _DRIVER_H_
....сам х-файл
#endif
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Re: Вопросы по С/С++ (СИ)
Включать нужно туда, где это используется. Нужны типы int32_t в foo.h, включи stdint.h в foo.h. Если они нужны в foo.c, то включи stdint.h в foo.c. Нужны в обоих файлах (обычно так и бывает) включи в оба файла, и не важно, что в foo.c они будут опосредовано включены через foo.h. Лучше явно указать зависимости, а не надеяться, что кто-то где-то уже включил. Если при этом возникают ошибки - это проблема архитектуры, пересмотри зависимости между модулями.
Re: Вопросы по С/С++ (СИ)
Сюшная классика - все переменные до́лжно определять в начале блока. Многие компиляторы не так строги - и дозволяют разбрасывать объявления где заблагорассудится. Впрочем обойти тоже можно - огородившись "фиктивным" блоком:uldemir писал(а):declaration may not appear after executable statement in block [....] т.е. совершенно это неприемлет. Хотя, помнится, в IARе такое делал.
Код: Выделить всё
int i = 0;
[...]
i = 9;
{ // <- огораживаемся, огораживаемся
int u = 5; // и никто больше не ругается на это объявление
send (u);
} // ну вот и всё - окончен блок, беру шинель иду домой ...
У препроцессора есть возможность т.н. stringify с помощью одинарного # префикса - превращать число в строку. Вот если задавать коды в восьмеричных константах - по идее должно сработать:uldemir писал(а):Способ интересный, но тогда снова придётся делать два комплекта дефайнов - для констант и для строк.
Код: Выделить всё
#define S(_code) "\0" _S(_code)
#define _S(_code) #_code
#define OGO 000 // decimal 0
#define AGA 050 // decimal 40
const char* ppd = S(OGO) S(AGA); // const char* ppd = "\0" "000" "\0" "050";
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Для ARM gcc генерит одинаковый код при чтении, но разный при записи. Например, дляApparatchik писал(а):ARV писал(а): Есче интересно знать, битовые поля применяются когда оперативной памяти мало или просто для удобства. На сколько это выгоднее конструкции типа var |= 1 << 4;
Код: Выделить всё
RCC_CFGR->HPRE = presc;
Код: Выделить всё
RCC->CFGR = RCC->CFGR & ~RCC_CFGR_HPRE | (presc << 4);
Увы, подобным образом описаны только несколько регистров в CMSIS...ARV писал(а): на сколько я в курсе, подобным образом вся периферия ARM описана в соответствующих хедерах, и вся работа с нею ведется подобным образом
Программирование C++
Привет всем! Для чего нужен суффикс типа вещественной переменной? Читаю книгу - там объявление используется с суффиксом, в других статьях используется без него. Компилятор компилирует два варианта написания.
В чем разница между объявлениями переменной с суффиксом и без:
float a=7.56F;
и
float a=7,56;
В чем разница между объявлениями переменной с суффиксом и без:
float a=7.56F;
и
float a=7,56;
Все гениальное - просто
- WiseLord
- Друг Кота
- Сообщения: 4905
- Зарегистрирован: Чт апр 11, 2013 11:19:59
- Откуда: Минск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
В первом случае константа 7.56F - типа float, во втором константа 7.56 - типа double. Переменные же в обоих случаях float, и к ним эти суффиксы никак не относятся.
Будь компилятор поглупее и с отключенной оптимизацией, можно было бы предположить, что во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
Будь компилятор поглупее и с отключенной оптимизацией, можно было бы предположить, что во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
Re: Вопросы по С/С++ (СИ)
Хм, по ошущениям львиная доля применений f-суффикса - затыкать предупреждения компилятора на "возможную потерю точности" при приведении double литерала к типу float. Т.е. компилятор в сомнениях - или мы явно хотим использовать double константу, но почему-то втискиваем её во float, или просто неряшливо пишем код [без f-суффиксов] и тоже заслуживаем "фе" с его стороны. Но, с другой стороны, если преобразование 7.5 <-> 7.5f происходит без потери точности - отчего-бы и не соптимизировать.WiseLord писал(а):во втором случае он бы сгенерировал более сложный машинный код с приведением типов.
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! 
Re: Вопросы по С/С++ (СИ)
Возможно ли в switch case использовать не отдельные числа, а промежутки чисел?
Например:
switch(a)
{
case 1: код; break;
case 2: код; break;
case 3: код; break;
...............
}
Можно ли на место числа 1, 2 или 3 вставить промежутки 1-2, 3-5 и т.д. ?
Например:
switch(a)
{
case 1: код; break;
case 2: код; break;
case 3: код; break;
...............
}
Можно ли на место числа 1, 2 или 3 вставить промежутки 1-2, 3-5 и т.д. ?
Все гениальное - просто
- ARV
- Ум, честь и совесть. И скромность.
- Сообщения: 18544
- Зарегистрирован: Чт дек 28, 2006 08:19:56
- Откуда: Новочеркасск
- Контактная информация:
Re: Вопросы по С/С++ (СИ)
Да, такое возможно (как минимум, GCC поддерживает):
Код: Выделить всё
switch(f){
case 0 ... 5 : break;
case 6 ... 155: break;
default:
break;
}если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
при взгляде на многих сверху ничего не меняется...
Мой уютный бложик... заходите!
Re: Вопросы по С/С++ (СИ)
Спасибо ARV ! Компилятор AtmelStudio с восторгом принял Ваш вариант кода. Я когда то видел такой вариант записи, пробовал писать, но забыл про пробелы - а писал так, например 1...3 . По этому компилятор и ругался.
Все гениальное - просто
- Hand-Maker
- Поставщик валерьянки для Кота
- Сообщения: 2142
- Зарегистрирован: Чт дек 12, 2013 11:18:14
- Откуда: Украина, Черновцы
Re: Вопросы по С/С++ (СИ)
Котаны, прошу помощи.
Си начал колупать недавно, опыта мало.
Мне надо объявить поле битов, но так, чтобы оно было видно во всех файлах *.с
Просто с переменной проблем не возникло, в main.c декларировал переменную, в main.h указал, что она extern -- и все поехало. А вот со структурой не получается.
Предыдущий программисть для однобитных флажков использовал целые байты. Теперь это боком вылазит, хочу эти флажки в поле затолкать.
Посоветуйте, плз!
Си начал колупать недавно, опыта мало.
Мне надо объявить поле битов, но так, чтобы оно было видно во всех файлах *.с
Просто с переменной проблем не возникло, в main.c декларировал переменную, в main.h указал, что она extern -- и все поехало. А вот со структурой не получается.
Предыдущий программисть для однобитных флажков использовал целые байты. Теперь это боком вылазит, хочу эти флажки в поле затолкать.
Посоветуйте, плз!