Re: Вопросы по С/С++ (СИ)
Добавлено: Пт май 13, 2016 14:17:13
Код: Выделить всё
typedef struct {
uint8_t pole_1 :1;
uint8_t pole_2 :4;
uint8_t pole_3 :3;
} my_struct_type;
my_struct_type my_struct = {
1,
13,
255
};
Код: Выделить всё
typedef struct {
uint8_t pole_1 :1;
uint8_t pole_2 :4;
uint8_t pole_3 :3;
} my_struct_type;
my_struct_type my_struct = {
1,
13,
255
};
Где логика, записывать в 3 бита, число, превышающее 7 ?Apparatchik писал(а):так будет правильно? несмотря на 255 я получу в третьем поле 7.
Код: Выделить всё
#define Maycount ((unsigned char) 0x22) ЕМНИП если знаковость типа не указана явно - то предполагается signed. Если нужен беззнаковый - тогда и осуществляем вот такой акт насилия над компилятором, выражающийся в явном приведении. Шестнадцатиричная константа имеет тип int. Напрямую скормить её, например, функции, ожидающей параметром unsigned char, уважающий себя компилятор не позволит. Приведение-же типа позволяет без помех "прострелить себе ногу".Darkmaster писал(а):в частности что дает Unsigned char..
Там где ждут именно unsigned char. Ну ешё в восьмибитном ембединге существует поверье, что если все целочисленные объявлять байтовыми - то будет всё работать легко и приятно. По крайней мере изучение соответствуюших продуктов жизнедеятельности обитателей оной области оставляет подобное ощущение.Darkmaster писал(а):и где подобное можно использовать ?
Код: Выделить всё
#define Maycount 0x25 Чтобы привести константу 0х22, имеющую тип int, к типу unsigned char. Для чего - тут уж по коду смотреть надо в какие "физиологические полости" программы глубокоуважаемый автор эту подстановку пристраивает. Видать там, в этих местах, были не очень рады int-у - вот и заткнули рот компилятору, чтобы не вякал.Darkmaster писал(а):с этим понятно давно) .... мы же добавили ишо и '(unsigned char)'
Код: Выделить всё
...
typedef union {
uint32_t raw;
struct {
uint8_t laddr;
uint8_t haddr;
uint8_t cmd;
uint8_t ncmd;
};
} NECCmd;
...
...
if ((uint8_t)(~necCmd.ncmd) == necCmd.cmd) {
// команда валидна, можно обрабатывать
}
...Код: Выделить всё
uint8_t a = 0b11001010;
uint8_t b = 0b00110101;Код: Выделить всё
if (~a == b) {
...
}Код: Выделить всё
if (0b11111111 00110101 == 00110101) {
...
}Подозреваю, что справа там тоже не 00110101 а 00000000 00110101 - т.е. полновесный int как результат implicit conversion в контексте if. PS: И как по мне 0xFF & результата инверсии менее парадоксально выглядит в глазах потомков чем приведение.WiseLord писал(а):фактически компилятор будет делать следующееТо есть результат побитовой инверсии 8-бит числа вовсе даже не 8-битен.Код: Выделить всё
if (0b11111111 00110101 == 00110101) { ... }
О да, тоже люблю такие случаи - как повод залезть в писания святых отцов и приобшиться к ещё одной крупице тайного знания, которое в беглом прочтении может быть понято лишь [практическими] шишками на определённых местах лобной стенки черепной коробки. PS: Заодно и повод разобраться с integer promotions - если ещё не.WiseLord писал(а):Вот такое вот неочевидное поведение компилятора, в которое никак не мог въехать.
Компилятору виднее. Так, глядя на результат инверсии, sizeof(int) небось 2 рапортует.WiseLord писал(а):Но ведь это на 8-битном AVR происходило, вот в чём прикол.
Код: Выделить всё
#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 */
}CanTxMsgTypeDefКод: Выделить всё
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)); А что говорит? Попробуйте static - это выпихнет локальную переменную в глобальную область, сохранив её видимость локальной.uldemir писал(а):Потом, почему-то, не позволет объявление этого массива сделать непосредственно рядом с вызовом этой функции (хотя IAR на это не возражал).
В строковый литерал можно запихать всё что угодно: "\x00\xFFHalli\xCCHallo!\x1F", ещё можно каждый код задефайнить как строчкуuldemir писал(а):Самое интересное, если бы инициализационные коды были бы печатные, то конструкция
константная строка и массив константных символов - судя по всему для него [компилятора] различные типы. Гораздо интереснее, что он не ругается на снятие const при такой передаче - ведь внутри функции это обычный указатель - в который функция может нагадить.uldemir писал(а):пороходит, несмотря на то, что ему в данном случае передаётся константная строка.
Вопрос в том, что семантика функции предполагает модификацию передаваемого буффера - мол, не огорожен указатель const-ом - не говорите что вас не предупреждали.uldemir писал(а):Вопрос собственно и состоит, как эту инициализационную последовательность изящно засунуть в память программ не куроча функцию.
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 будет.