Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: Вопросы по С/С++ (СИ)

Пт ноя 24, 2017 22:48:29

]
И дальше, зная что каждое поле занимает 1 байт обращаемся как к массиву. Даже если будут разные типы, мы же знаем их
размер, но будет чуть сложнее.

не надо так делать. __packed__ и прочее для случаев, когда без них не обойтись (например, для заголовкой сетевых пакетов).
У автора вопроса явно не этот случай.


Не надо никаких union-ов. Зачем запутывать? Если четыре поля ошибок нормально (я не телепат), то
Код:
typedef struct{
   uint8_t error1;
   uint8_t error2;
   uint8_t error3;
   uint8_t error4;
};

void err_copy_123 (Type_error *dst, Type_error *src)
{
    dst->error1 = src->error1;
    dst->error2 = src->error2;
    dst->error3 = src->error3;
}


Просто, понятно, переносимо, будет работать, как и задуманно (копировать три нужных поля) если в структуру добавить еще полей (и не важно в каком порядке) и даже, если в будущем поле увеличится (например, uint16_t error2;). А если еще и имена полей и функций будут отражать суть - по мне, так вообще будет хорошо.
Чем не устраивает?

Re: Вопросы по С/С++ (СИ)

Пн ноя 27, 2017 20:58:28

Мммм, у меня затык в вроде бы простом месте. Препроцессор. Есть макрос COMMAPOS, который я могу назвать LEFT, RIGHT или не назвать совсем.
Так вот, если я этот макрос не определяю, то почему-то компилируется условие #if, а не #else:
Код:
#if COMMAPOS == LEFT
#warning Left
#else
#warning Not LEFT
#endif

#if COMMAPOS == RIGHT                    
#warning Right
#else
#warning Not right
#endif

Так что если макрос не определён, я получаю:
main.c:498: warning: (162) #warning: Left
main.c:505: warning: (162) #warning: Right

Хотя ожидал получить в обоих случаях "not".

Что я не понимаю?

Чёрт, да ему до фонаря на значение этого макроса!

Re: Вопросы по С/С++ (СИ)

Пн ноя 27, 2017 21:19:52

в условияй макросов нельзя сравнивать со строками. Определите макросы LEFT и RIGHT как числа или символы, тогда прокатит

Re: Вопросы по С/С++ (СИ)

Пн ноя 27, 2017 22:08:59

В гугле нашел такой пример: http://www.c-cpp.ru/books/if-else-elif-i-endif
Например, следующий фрагмент использует значение ACTIVE_COUNTRY для определения де­нежного знака:

Код:
 #define US 0
 #define ENGLAND 1
 #define FRANCE 2
 #define ACTIVE_COUNTRY US
 #if ACTIVE_COUNTRY==US
 char currency[] = "dollar";
 #elif ACTIVE_COUNTRY==ENGLAND
 char currency[] = "pound";
 #else
 char currency[] = "franc";
 #endif


С цифрами, конечно, работает.

Хм. вот еще нагуглил: •Expressions must have integral type and can include only integer constants, character constants, and the defined operator
Как понять character constant? это один символ?

Добавлено after 39 minutes 10 seconds:
Ага. Этот фокус работает:
#define COMMAPOS 'L'
#if COMMAPOS == 'L'

Re: Вопросы по С/С++ (СИ)

Пн ноя 27, 2017 23:21:06

Есть макрос COMMAPOS, который я могу назвать LEFT, RIGHT или не назвать совсем.

Так определяете?
Код:
#define COMMAPOS LEFT

А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D

Re: Вопросы по С/С++ (СИ)

Вт ноя 28, 2017 00:41:29

А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D

емнип поведение в #if при сравнении с идентификатором, не определенным как макрос, в стандарте не описано и дано на откуп компилятору. GCC, к примеру, приводит их к числовому нулю
expression is a C expression of integer type, subject to stringent restrictions. It may contain:
...
- Identifiers that are not macros, which are all considered to be the number zero. This allows you to write #if MACRO instead of #ifdef MACRO, if you know that MACRO, when defined, will always have a nonzero value. Function-like macros used without their function call parentheses are also treated as zero.

Re: Вопросы по С/С++ (СИ)

Вт ноя 28, 2017 02:56:08

Добрый день подскажите в С как нибудь можно в цикле по полям структуры пройтись? и проверить их скажем на больше меньше числа. А в C ++ ?

Допустим как-то так, и надо выявить какая именно авария произошла.
Код:
typedef struct{
   uint8_t error1;
   uint8_t error2;
   uint8_t error3;
   uint8_t error4;
}Type_error;


Или перекопировать из одной переменной Type_error в другую с таким же типом , только несколько полей скажем все кроме одного.

Код:
Type_error  Err1;
Type_error  Err2;
Err1.error1=Err2.error1;  // Вот это как сделать по феншую ?
Err1.error2=Err2.error2;
Err1.error3=Err2.error3;


А обязательно структура нужна ? Если бы это был постоянный ввод с неизвестным размером данных, это одно. Но тут же все
в пределах размера стека. Можно и без структуры обойтись.
Код:
uint8_t  Err1[4] ={0};
uint8_t  Err1[4] ={0};
Err1[0]=Err2[0];
Err1[1]=Err2[1];
Err1[2]=Err2[2];

//сравниваем
if (Err1[0] < 2) return false;
else if (Err1[0] == 4) return false;
else if (Err1[0] > 8) return true;

//Или как показывали раньше, через switch

Можно и по маске сравнивать и весь массив обежать при желании.

Re: Вопросы по С/С++ (СИ)

Вт ноя 28, 2017 07:34:08

А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D
Ага, тогда если бы я перед этим определил
Код:
#define LEFT 1
#define RIGHT 2

то это заработало бы?

Re: Вопросы по С/С++ (СИ)

Вт ноя 28, 2017 07:47:08

Может заработало бы, а может и нет.
Вообще, негоже сравнивать что-то неопределённое, хоть в макросе, хоть в коде. Странно, что компилятор на это не матерится.
Правильней было бы сделать через :
Код:
#if !defined( COMMAPOS )  // или #ifndef
  ....  // Тут действия, при неопределённом "COMMAPOS"
#else
  ....  // Тут действия, при определённом "COMMAPOS"
#endif

Re: Вопросы по С/С++ (СИ)

Вт ноя 28, 2017 14:00:28

Ага, тогда если бы я перед этим определил
Код:
#define LEFT 1
#define RIGHT 2

то это заработало бы?


да, в основном должно

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 13:37:46

Есть код для семисегментника,к портам подключен беспорядочно, вот так-
Код:
#define SEG_A_ON GPIOD->ODR |= GPIO_PIN_5
#define SEG_B_ON GPIOA->ODR |= GPIO_PIN_2
#define SEG_C_ON GPIOC->ODR |= GPIO_PIN_7
#define SEG_D_ON GPIOD->ODR |= GPIO_PIN_3
#define SEG_E_ON GPIOD->ODR |= GPIO_PIN_1
#define SEG_F_ON GPIOA->ODR |= GPIO_PIN_1
#define SEG_G_ON GPIOC->ODR |= GPIO_PIN_6
#define SEG_DP_ON GPIOD->ODR |= GPIO_PIN_2

Есть массив для цифр, не пойму как это работает, как вывести например там символ F
Код:
uint8_t _SYM[][3] =
{
  {1 << 2 | 1 << 1, 1 << 5 | 1 << 1 | 1 << 3, 1 << 7},         // 0
  {1 << 2, 0, 1 << 7},                                         // 1
  {1 << 2, 1 << 5 | 1 << 1 | 1 << 3, 1 << 6},                  // 2
  {1 << 2, 1 << 3 | 1 << 5, 1<<6 | 1 << 7},                    // 3
  {1 << 2 | 1 << 1, 0, 1 << 6 | 1 << 7},                       // 4
  {1 << 1, 1 << 5 | 1 << 3, 1 << 6 | 1 << 7},                  // 5
  {1 << 1, 1 << 1 | 1 << 5 | 1 << 3, 1 << 6 | 1 << 7},         // 6
  {1 << 2, 1 << 5, 1 << 7},                                    // 7
  {1 << 1 | 1 << 2, 1 << 5 | 1 << 1 | 1 << 3, 1 << 6 | 1 << 7},// 8
  {1 << 1 | 1 << 2, 1 << 5 | 1 << 3, 1 << 6 | 1 << 7},         // 9
  {0x00, 0x00, 0x00},                                          //
};

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 13:57:09

Код:
{1 << 1 | 1 << 5, 1 << 6 | 1 << 7},         // F

Вообще, вместо магических чисел, лучше обозначить сегменты - "A", "B", ....
Тогда символ "F" будет уже выглядеть примерно так :
Код:
{1 << A | 1 << E, 1 << F | 1 << G},         // F
что более наглядней.

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 14:12:02

Не получается так F, вот остаток кода,связанный с этим-
Код:
uint8_t _SYM_MASK[3] = {0xF9, 0xD1, 0x3F}; // A, D, C маски чтобы не затронуть остальные биты портов
uint8_t LED[3] = {0x00, 0x00, 0x00};
uint8_t LED_CURR = 0;

  // занесем новые данные по сегментам
  GPIOA->ODR = GPIOA->ODR & _SYM_MASK[0];
  GPIOD->ODR = GPIOD->ODR & _SYM_MASK[1];
  GPIOC->ODR = GPIOC->ODR & _SYM_MASK[2];

  GPIOA->ODR = GPIOA->ODR | _SYM[LED[LED_CURR]][0];
  GPIOD->ODR = GPIOD->ODR | _SYM[LED[LED_CURR]][1];
  GPIOC->ODR = GPIOC->ODR | _SYM[LED[LED_CURR]][2];

  // включаем нужный разряд
  if (LED_OFF[LED_CURR] == 0)
  {
    GPIOB->DDR = GPIOB->DDR | _DIG_MASK[LED_CURR][0];
    GPIOD->ODR = GPIOD->ODR & _DIG_MASK[LED_CURR][1];
  }

  if (LED_DP[LED_CURR] & 0x01) // точку включаем отдельно
     SEG_DP_ON;

  LED_CURR++;
  if (LED_CURR > 2)
    LED_CURR = 0;

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 14:30:24

Да в бинарном виде запишите в массив пины порта (к котрому подключён 7-ми сегментник) да и всё))

char LED[3] = {0x0b01110010, 0x0b01000010, 0x0b00010010}; // A, B, C, ...

Для вывода наберите:

PORTB=LED[0]; // вывод A. (вместе с точной)
...
PORTB=LED[1]; // вывод B. (вместе с точной)
...
PORTB=LED[2]; // вывод C. (вместе с точной)
...
и т.д. ))

дефайны ещё всякие.. нафиг они тут нужны))

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 14:34:10

dm211 писал(а):вот остаток кода,связанный с этим-
Что-то у Вас какая-то путаница в коде.
Маски какие-то, массив символов из 3-х рядов (причём одинаковых), ... Зачем это всё ?
Создали одномерный массив для символов и выбираем из него нужный символ, записывая в порт. Всё.

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 14:36:43

Аlex писал(а):Создали одномерный массив для символов и выбираем из него нужный символ, записывая в порт. Всё.
массив-то можно одномерный, а вот на счет записи в порт - не выйдет: у него сегменты по разным портам разбросаны:
dm211 писал(а):#define SEG_B_ON GPIOA->ODR |= GPIO_PIN_2
#define SEG_C_ON GPIOC->ODR |= GPIO_PIN_7
#define SEG_D_ON GPIOD->ODR |= GPIO_PIN_3

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 15:23:06

Есть массив для цифр, не пойму как это работает, как вывести например там символ F

похоже STM8 - тут посмотреть может понятнее будет:
http://caxapa.ru/795691.html
F:
Код:
   case 'F':
             GPIOD->ODR|=  (1<<1);  // PD1 (A) 
             GPIOA->ODR&=  ~(1<<3);  // PA3 (B) 
             GPIOC->ODR&=  ~(1<<3);  // PC3 (C) 
             GPIOC->ODR&=  ~(1<<6);  // PC6 (D) 
             GPIOC->ODR|= (1<<7); // PC7 (E) 
             GPIOC->ODR|=  (1<<4);  // PC4 (F) 
             GPIOA->ODR|=  (1<<2);  // PA2 (G) 

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 15:47:33

ARV писал(а):а вот на счет записи в порт - не выйдет:
Ну значит запись в несколько портов :)
Не вижу проблемы...

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 20:09:39

Маски какие-то, массив символов из 3-х рядов (причём одинаковых), ... Зачем это всё ?
Создали одномерный массив для символов и выбираем из него нужный символ, записывая в порт. Всё.


Угу, при нынешней дешивезне изготовления pcb, "кулибинство" в разводке пинов под 7сегментник -лишний геморрой в софте.
Это было оправдано ещё лет так 5 назад, при рассово-верном лутЪ.

Сейчас и софтовый ногодрыг для LED -лишь блажь и УГ.
В юзаемых тобой 32пЫк есть же DMA?

Re: Вопросы по С/С++ (СИ)

Пн дек 11, 2017 20:51:11

Угу, при нынешней дешивезне изготовления pcb, "кулибинство" в разводке пинов под 7сегментник -лишний геморрой в софте.

ну я например извращался для stm8s103f3 - там тупо нет ни одного целого порта gpio, физически разведенного на ноги) максимум порт D, от него есть 6 пинов
Спойлер
Код:
....
typedef struct {
   GPIO_TypeDef* port;
   GPIO_Pin_TypeDef pin;
}segment_t;
...
segment_t seg[8]={
      {GPIOD, GPIO_PIN_1}, // A
      {GPIOD, GPIO_PIN_2}, // B
      {GPIOD, GPIO_PIN_3}, // C
      {GPIOD, GPIO_PIN_4}, // D
      {GPIOC, GPIO_PIN_4}, // E
      {GPIOC, GPIO_PIN_5}, // F
      {GPIOC, GPIO_PIN_7}, // G
      {GPIOC, GPIO_PIN_6}  // DP
};

#define SEG_DP_MASK 0b10000000

// set bit represents live segments: DP G  F  E  D  C  B  A
//                               0b  0  0  0  0  0  1  1  0
uint8_t digit_mask[10]={
      0b00111111, // 0
      0b00000110, // 1
      0b01011011, // 2
      0b01001111, // 3
      0b01100110, // 4
      0b01101101, // 5
      0b01111101, // 6
      0b00000111, // 7
      0b01111111, // 8
      0b01101111  // 9
};
...
#define writeHigh(port,pins) port->ODR |= (pins)
#define writeLow(port,pins) port->ODR &= ~(pins)
#define ValBit(VAR,Place)         ((uint8_t)(VAR) & (uint8_t)((uint8_t)1<<(uint8_t)(Place)))
...
void led_setbuf(uint16_t newval){
   buf[0]=digit_mask[newval%10];
   newval/=10;
   buf[1]=digit_mask[newval%10];
   newval/=10;
   buf[2]=digit_mask[newval%10]|SEG_DP_MASK;
}
...
void led_display_digit(uint8_t seg_mask) {
      uint8_t i;
      for (i = 0; i < 8; i++) {
         if (ValBit(seg_mask,i) == 0) {
            writeLow(seg[i].port, seg[i].pin);
         } else {
            writeHigh(seg[i].port, seg[i].pin);
         }
      }
}
...
Ответить