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

Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
viiv
Грызет канифоль
Сообщения: 289
Зарегистрирован: Чт ноя 06, 2014 13:09:06

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

Сообщение viiv »

[uquote="Zat",url="/forum/viewtopic.php?p=3241741#p3241741"]]
И дальше, зная что каждое поле занимает 1 байт обращаемся как к массиву. Даже если будут разные типы, мы же знаем их
размер, но будет чуть сложнее.[/uquote]
не надо так делать. __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;). А если еще и имена полей и функций будут отражать суть - по мне, так вообще будет хорошо.
Чем не устраивает?
Реклама
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

Мммм, у меня затык в вроде бы простом месте. Препроцессор. Есть макрос 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".

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

Чёрт, да ему до фонаря на значение этого макроса!
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Реклама
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

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

Сообщение arkhnchul »

в условияй макросов нельзя сравнивать со строками. Определите макросы LEFT и RIGHT как числа или символы, тогда прокатит
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

В гугле нашел такой пример: 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'
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Siarzhuk
Потрогал лапой паяльник
Сообщения: 353
Зарегистрирован: Вс янв 19, 2014 22:41:55

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

Сообщение Siarzhuk »

[uquote="uldemir",url="/forum/viewtopic.php?p=3244433#p3244433"]Есть макрос COMMAPOS, который я могу назвать LEFT, RIGHT или не назвать совсем.[/uquote]
Так определяете?

Код: Выделить всё

#define COMMAPOS LEFT
А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D
Одновременным нажатием LIGHT и POWER, РП Sangean ATS-909X (ver 1.29) превращается в ATS-909XR! ;-)
Реклама
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

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

Сообщение arkhnchul »

[uquote="Siarzhuk",url="/forum/viewtopic.php?p=3244521#p3244521"]А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D[/uquote]
емнип поведение в #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.
Реклама
Аватара пользователя
Zat
Встал на лапы
Сообщения: 119
Зарегистрирован: Пн ноя 02, 2009 05:27:41
Откуда: С-Пб

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

Сообщение Zat »

[uquote="pokk",url="/forum/viewtopic.php?p=3240362#p3240362"]Добрый день подскажите в С как нибудь можно в цикле по полям структуры пройтись? и проверить их скажем на больше меньше числа. А в 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;
[/uquote]

А обязательно структура нужна ? Если бы это был постоянный ввод с неизвестным размером данных, это одно. Но тут же все
в пределах размера стека. Можно и без структуры обойтись.

Код: Выделить всё

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
Можно и по маске сравнивать и весь массив обежать при желании.
Аватара пользователя
uldemir
Друг Кота
Сообщения: 7359
Зарегистрирован: Пт авг 28, 2009 21:34:30
Откуда: 845-й км.

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

Сообщение uldemir »

[uquote="Siarzhuk",url="/forum/viewtopic.php?p=3244521#p3244521"]А LEFT во что определён? Если ни во что - то ваш #if сравнивает ничто с ничем. А они равны. :-D[/uquote]Ага, тогда если бы я перед этим определил

Код: Выделить всё

#define LEFT 1
#define RIGHT 2
то это заработало бы?
А люди посмотрят и скажут: "Собаки летят. Вот и осень."
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Может заработало бы, а может и нет.
Вообще, негоже сравнивать что-то неопределённое, хоть в макросе, хоть в коде. Странно, что компилятор на это не матерится.
Правильней было бы сделать через :

Код: Выделить всё

#if !defined( COMMAPOS )  // или #ifndef
  ....  // Тут действия, при неопределённом "COMMAPOS"
#else
  ....  // Тут действия, при определённом "COMMAPOS"
#endif 
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

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

Сообщение arkhnchul »

[uquote="uldemir",url="/forum/viewtopic.php?p=3244653#p3244653"]Ага, тогда если бы я перед этим определил

Код: Выделить всё

#define LEFT 1
#define RIGHT 2
то это заработало бы?[/uquote]

да, в основном должно
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

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

Сообщение dm211 »

Есть код для семисегментника,к портам подключен беспорядочно, вот так-

Код: Выделить всё

#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},                                          //
};
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

Код: Выделить всё

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

Код: Выделить всё

{1 << A | 1 << E, 1 << F | 1 << G},         // F
что более наглядней.
dm211
Прорезались зубы
Сообщения: 208
Зарегистрирован: Вс дек 10, 2006 19:26:13

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

Сообщение dm211 »

Не получается так 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;
roman.com
Друг Кота
Сообщения: 9149
Зарегистрирован: Вт мар 13, 2012 12:16:13
Откуда: .ru

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

Сообщение roman.com »

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

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

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

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

дефайны ещё всякие.. нафиг они тут нужны))
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

dm211 писал(а):вот остаток кода,связанный с этим-
Что-то у Вас какая-то путаница в коде.
Маски какие-то, массив символов из 3-х рядов (причём одинаковых), ... Зачем это всё ?
Создали одномерный массив для символов и выбираем из него нужный символ, записывая в порт. Всё.
Аватара пользователя
ARV
Ум, честь и совесть. И скромность.
Сообщения: 18546
Зарегистрирован: Чт дек 28, 2006 08:19:56
Откуда: Новочеркасск
Контактная информация:

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

Сообщение ARV »

А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
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...

Мой уютный бложик... заходите!
Аватара пользователя
oleg110592
Друг Кота
Сообщения: 3832
Зарегистрирован: Сб сен 10, 2011 17:46:25

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

Сообщение oleg110592 »

[uquote="dm211",url="/forum/viewtopic.php?p=3256664#p3256664"]Есть массив для цифр, не пойму как это работает, как вывести например там символ F[/uquote]
похоже 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)  
Аватара пользователя
Аlex
Модератор
Сообщения: 4614
Зарегистрирован: Чт мар 18, 2010 23:09:57
Откуда: Планета Земля
Контактная информация:

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

Сообщение Аlex »

ARV писал(а):а вот на счет записи в порт - не выйдет:
Ну значит запись в несколько портов :)
Не вижу проблемы...
Аватара пользователя
dosikus
Друг Кота
Сообщения: 3604
Зарегистрирован: Пн июл 28, 2008 22:12:01

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

Сообщение dosikus »

[uquote="Аlex",url="/forum/viewtopic.php?p=3256722#p3256722"]Маски какие-то, массив символов из 3-х рядов (причём одинаковых), ... Зачем это всё ?
Создали одномерный массив для символов и выбираем из него нужный символ, записывая в порт. Всё.[/uquote]

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

Сейчас и софтовый ногодрыг для LED -лишь блажь и УГ.
В юзаемых тобой 32пЫк есть же DMA?
arkhnchul
Друг Кота
Сообщения: 3092
Зарегистрирован: Пн апр 06, 2015 11:01:53
Откуда: москва, уфа

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

Сообщение arkhnchul »

[uquote="dosikus",url="/forum/viewtopic.php?p=3257066#p3257066"]Угу, при нынешней дешивезне изготовления pcb, "кулибинство" в разводке пинов под 7сегментник -лишний геморрой в софте.[/uquote]
ну я например извращался для 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);
			}
		}
}
...
Ответить

Вернуться в «Разные вопросы по МК»