Easyelectronics.ru

Электроника для всех
Текущее время: 29 мар 2017, 00:37

Часовой пояс: UTC + 5 часов



    • Изготовление печатных плат
    • Создание принципиальных схем и проектирование печатных плат
    • Симуляция работы на spice моделях
    • Просмотр GERBER файлов

Начать новую тему Ответить на тему  [ Сообщений: 307 ]  На страницу 1, 2, 3, 4, 5 ... 13  След.
Автор Сообщение
 Заголовок сообщения: Вопросы о С.
СообщениеДобавлено: 19 июл 2011, 01:36 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2010, 01:03
Сообщения: 643
Откуда: Херсон
Доброго времени суток всем читающим сии строки!
В который раз сажусь писать прогу на Си, и вспоминаю про АССЕМБЛЕР...
Есть некий код...

Show


... макро для настройки последовательного интерфейса.

Внимание Вопрос.
Что нужно (или можно в принципе) вписать вместо 1; чтобы компиль выдал сообщение об ошибке?

Или поставте меня на правильные рельсы.
Как его можно переписать? Да так, чтобы хоть ругался когда это нужно и как мне это нужно.

А то что-то я не могу понять, как это ...

_________________
Если руки золотые, то не важно с какого места они растут.
Изображение
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 июл 2011, 03:50 
Старожил

Зарегистрирован: 22 июн 2010, 21:53
Сообщения: 891
Откуда: Brussels
стерто т.к. не уверен что верно :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 июл 2011, 04:58 
Здравствуйте!

Зарегистрирован: 28 янв 2010, 03:54
Сообщения: 3
Все if что вы написали будут просто скомпилированы, формулы конечно соптимизируются в числа, но сам if будет скомпилирован просто в код.

С/С++ не поддерживает сложные вычесления в препроцессоре, поэтому тоже не получится. Есть токо единственный способ, но у него есть недостатки, в виде невозможности выдачи адекватного сообщения об ошибке.

Делается это так.

Код:
#define COMPILE_TIME_ASSERT(expr)       char UNIQUE_NAME[expr]
#define UNIQUE_NAME                     MAKE_NAME(__LINE__)
#define MAKE_NAME(line)                 MAKE_NAME2(line)
#define MAKE_NAME2(line)                constraint_ ## line

COMPILE_TIME_ASSERT((1.0-(Fclk/(16.0*(uint16_t)((Fclk/(16UL*_BAUD)-1.0)+1.0)))/(float)_BAUD) > 0.02);


В результате код скомпилируется если expr true. И соответственно получите ошибку если false. Вот тока ошибка будет выглядеть чтото типа "cannot allocate an array of constant size 0". Если это все запрятано гдето глубоко в макросах, то еще хуже.
Максимум что можно сделать, это вбить немного информации в название массива UNIQUE_NAME, что кстати и придется сделать, так как финт с __LINE__ в макросах не пройдет, если проверок больше чем одна.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 июл 2011, 09:02 
Старожил
Аватара пользователя

Зарегистрирован: 22 апр 2010, 09:08
Сообщения: 623
есть директивы #error и #warning


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 июл 2011, 12:05 
Старожил

Зарегистрирован: 22 мар 2010, 22:54
Сообщения: 3886
через
#if ()
#error "..."
#endif
вполне можно реализовать, если отказаться от дробных чисел.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 июл 2011, 14:55 
Старожил

Зарегистрирован: 01 июл 2010, 15:30
Сообщения: 470
Откуда: Энгельс
Pumba писал(а):
Делается это так.
...

Надо только учитывать, что всё тело макроса mInitUSART после макроподстановки будет одной строкой и два раза COMPILE_TIME_ASSERT там не применить. Нужно все запихать в одно константное выражение. Объяыление массива, нужно засунуть в typedef, чтоб он места не занимал. И вместо нулевой длинны массива при ложном условии лучше использовать -1. GCC по умолчанию проглатывает массивы нулевой длинны и даже предупреждения не выводит. Чтоб они вызывали ошибку нужно с опциями -pedantic или -ansi компилировать.
Код:
#define CONCAT2(First, Second) (First ## Second)
#define CONCAT(First, Second) CONCAT2(First, Second)
#define C_STATIC_ASSERT(expr) typedef char CONCAT(static_assert_failed_at_line_, __LINE__) [(expr) ? 1 : -1]

#define mInitUSART(_BAUD,_U2X,CSise,RX,TX,IntRX,IntTX,IntUDR) \
   enum{ cond1 = (1.0-(Fclk/(16.0*(uint16_t)((Fclk/(16UL*_BAUD)-1.0)+1.0)))/(float)_BAUD) > 0.02,\
      cond2 = (1.0-(Fclk/(16.0/(1+_U2X)*(uint16_t)((Fclk/(16UL/(1+_U2X)*_BAUD)-1.0)+1.0)))/(float)_BAUD) < -0.02};\
   C_STATIC_ASSERT(cond1 && cond2);\
   do\
   {\
      UBRRH = (uint16_t) (Fclk /(16UL/(1+_U2X) * _BAUD)-1.0)>>8;\
      UBRRL = (uint8_t) (Fclk /(16UL/(1+_U2X) * _BAUD)-1.0);\
      UCSRC = (1<<URSEL)|(CSise<<UCSZ0);\
      UCSRB = (RX<<RXEN)|(TX<<TXEN)|(IntRX<<RXCIE)|(IntTX<<TXCIE)|(IntUDR<<UDRIE);\
      UCSRA = (_U2X<<U2X);\
   }while(0)

Как-то так.
Правда, сообщения об ощибках будут типа:
../test.c:51: error: size of array 'static_assert_failed_at_line_51' is negative


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 19 июл 2011, 15:12 
Старожил

Зарегистрирован: 30 апр 2010, 22:56
Сообщения: 1490
Откуда: Киев
Блин, ну все же уже украдено до нас )

Код:
  #include <avr/io.h>

   #define F_CPU 4000000

   static void
   uart_9600(void)
   {
   #define BAUD 9600
   #include <util/setbaud.h>
   UBRRH = UBRRH_VALUE;
   UBRRL = UBRRL_VALUE;
   #if USE_2X
   UCSRA |= (1 << U2X);
   #else
   UCSRA &= ~(1 << U2X);
   #endif
   }


и читаем до просветления <util/setbaud.h>

Если хотим, чтобы выпадало с ошибкой, меняем соответствующий #warning на #error


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 20 июл 2011, 01:42 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2010, 01:03
Сообщения: 643
Откуда: Херсон
Большая (слабо сказано), ОГРОМНАЯ (нет), СЕРДЕЧНАЯ ВСЕМ БЛАГОДАРНОСТЬ.

Подсказали точки опоры да рычаги выкручивания "рук" компилю.

Получилось довольно прилично. IHMO.


Show


Цитата:
#include <util/setbaud.h>

И рядом не стоял.

Код. Судите сами. Ничего лишнего.
Код:
  mInitUSART1(38400,U2XOFF,CSZ8bit,RXON,TXON,INTRXON,INTTXON,INTUDRON);
26c:   10 bc          out   0x20, r1   ; 32
26e:   85 e0          ldi   r24, 0x05   ; 5
270:   89 b9          out   0x09, r24   ; 9
272:   86 e8          ldi   r24, 0x86   ; 134
274:   80 bd          out   0x20, r24   ; 32
276:   88 ef          ldi   r24, 0xF8   ; 248
278:   8a b9          out   0x0a, r24   ; 10
27a:   1b b8          out   0x0b, r1   ; 11

Осталось найти недостатки этого кода. Ctrl+F всем.

_________________
Если руки золотые, то не важно с какого места они растут.
Изображение
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 20 июл 2011, 01:57 
Старожил

Зарегистрирован: 30 апр 2010, 22:56
Сообщения: 1490
Откуда: Киев
Код будет точно такой же, но без черезжопного ASSERT сквозь определение массивов. Хочешь стоя и в гамаке - да пожалуйста.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 09 сен 2011, 23:16 
Только пришел

Зарегистрирован: 09 сен 2011, 22:56
Сообщения: 9
Приветствую уважаемое сообщество!
Наконец-то нашел тему куда можно задать вопрос по сям (использую winavr, но код платформеннонезависимый)
Хочется сделать некий универсальный интерфейс для кольцевого буфера (уарт, клавиатура, и мало ли чего еще).
Задаем typedef:
Код:
typedef struct {
    uint8_t *buf;
    uint8_t head;
    uint8_t tail;
    uint8_t count;
} ringbuffer;

ringbuffer KeyBuf;

Затем делаем malloc для buf, и оперируем функциями putbuf(&KeyBuf,byte) и getbuf(&KeyBuf).
Но я изначально бы хотел иметь разный размер буфера для клавиатуры (8 байт) и уарта (16-32 байт), и это усложняет код.
Надо либо добавлять еще байт в структуру (что не хочется категорически), либо указывать размер в #define, но тогда передавать его в параметрах функции.
Есть ли еще какой вариант для данного решения? Не хочется переходить на С++ - там вроде можно использовать шаблоны, но я плюсы практически не знаю.
Пока на мой взгляд из существующих вариантов менее накладным выглядит второй - второй параметр при передаче функции в winavr вроде передается через регистры.
Спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 09 сен 2011, 23:53 
Старожил

Зарегистрирован: 01 июл 2010, 15:30
Сообщения: 470
Откуда: Энгельс
На мой взгляд, не стоит размазывать сущности по разным местам. Лучше хранить размер в структуре. Будет проще.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 сен 2011, 00:01 
Только пришел

Зарегистрирован: 09 сен 2011, 22:56
Сообщения: 9
Будут больше накладные расходы. Каждый вызов переменной size - а это при каждом сравнении - лезть в структуру. Придется сразу эту переменную копировать в локальную переменную процедуры.
Но с точки зрения красоты и объектного подхода - согласен, в структуре хранить правильней.
Я надеялся, что есть еще какой-нибудь способ сделать это на макросах или еще как-нибудь :)

Все, вопрос закрыт в пользу поля в структуре, ибо потребовались еще флаги в структуре, и все удачно разместилось.
Спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 сен 2011, 15:12 
Старожил

Зарегистрирован: 28 дек 2010, 03:18
Сообщения: 741
Откуда: Оренбург
Забота о накладных расходах при обращении к структуре, как-то расходится с решением использовать malloc.

_________________
arogov.com


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 21 сен 2011, 23:10 
Старожил
Аватара пользователя

Зарегистрирован: 10 апр 2010, 18:47
Сообщения: 2477
Откуда: Харьков
Как отрицательное число сделать положительным?
к примеру :
cnt=-200;
как сделать , чтобы стало
cnt=200;?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 21 сен 2011, 23:16 
Супермодератор
Аватара пользователя

Зарегистрирован: 28 янв 2010, 05:47
Сообщения: 1031
Откуда: Винница
abs() из stdlib
или
if(cnt<0)cnt=-cnt;

_________________
Show


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 22 сен 2011, 10:03 
Старожил

Зарегистрирован: 28 дек 2010, 03:18
Сообщения: 741
Откуда: Оренбург
Можно так (для signed char):
(cnt&0x80 && (cnt=~cnt++));

_________________
arogov.com


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 22 сен 2011, 10:31 
Старожил

Зарегистрирован: 30 апр 2010, 22:56
Сообщения: 1490
Откуда: Киев
Можно, но непрозрачно - с первого взгляда неясно что делается. Ну и варнинги, естетственно.
С другой стороны, у процессора есть команды COM и NEG, которые, собственно, задействуются в функции abs.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 22 сен 2011, 23:05 
Только пришел

Зарегистрирован: 09 сен 2011, 22:56
Сообщения: 9
Alekzzz писал(а):
Забота о накладных расходах при обращении к структуре, как-то расходится с решением использовать malloc.


Да, посмотрел, в проекте +600 байт за malloc

В итоге, получилось достаточно красиво:
1. Описываю структуру, в которой *buf (последним параметром - это важно) и уже конкретную процедуру с buf[SIZE], где SIZE в #define.
2. И во всех процедурах просто привожу тип к базовому.

И эффективно, и по памяти экономно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 26 окт 2011, 06:38 
Свой человек

Зарегистрирован: 08 май 2010, 18:00
Сообщения: 172
S_Alex писал(а):
Есть некий код...

Жесть жесткая. Не советую никому писать вот таких вот макросов.
VelAndr писал(а):
Хочется сделать некий универсальный интерфейс для кольцевого буфера (уарт, клавиатура, и мало ли чего еще).
Затем делаем malloc для buf, и оперируем функциями putbuf(&KeyBuf,byte) и getbuf(&KeyBuf).

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 ноя 2011, 00:43 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2010, 01:03
Сообщения: 643
Откуда: Херсон
Продолжаем мучаться с Си.
Есть функция которая читает данные из буфера и устанавливает флаг Z если буфер пуст.
Каким х..м это можно сделать на Си?
Код:
data = ReadBuf();
if(флаг нуля или переноса)
делаем это;
else
делаем вот это;


На масме было так
Код:
if ZERO?
...


может на Си есть что-то похожее?

_________________
Если руки золотые, то не важно с какого места они растут.
Изображение
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 ноя 2011, 00:59 
Старожил
Аватара пользователя

Зарегистрирован: 27 янв 2010, 01:04
Сообщения: 814
Откуда: Черноголовка
На Си единственный выход, как я вижу - вручную установить этот флаг:
SREG|=1<<1; //Устанавливаем в 1 1-й разряд, т.е. флаг Z
Я пробовал записывать в SREG в Си, компилятор не жалуется.

А у меня такой вопрос:
Есть код:
Из временной структуры, адрес которой передан в функцию, копируются параметры в глобальную структуру motors.
Код:
#define MOTORS_NUMBER 3

typedef struct
{
   int params[MOTORS_NUMBER][2];
}new_motors_params;

unsigned char MoveDrillByXYZ(unsigned int new_timer_period, new_motors_params *b)
{
   timer_period=new_timer_period;
   /*for(unsigned char a=0;a<MOTORS_NUMBER;a++)
   {
      motors[a].period=(unsigned int)(b->params[a][0]);
      motors[a].step_number=b->params[a][1];
   }*/
   int *c=(int *)b->params[0];
   for(unsigned char a=0;a<MOTORS_NUMBER;a++)
   {
      motors[a].period=*c;
      c++;
      motors[a].step_number=*c;
      c++;
   }
   return 1;
}


А вот дизасм последней части функции - цикла for:
Код:
195:            motors[a].period=*c;
+000001A1:   01DB        MOVW      R26,R22        Copy register pair
+000001A2:   918D        LD        R24,X+         Load indirect and postincrement
+000001A3:   919D        LD        R25,X+         Load indirect and postincrement
+000001A4:   93900073    STS       0x0073,R25     Store direct to data space
+000001A6:   93800072    STS       0x0072,R24     Store direct to data space
197:            motors[a].step_number=*c;
+000001A8:   8182        LDD       R24,Z+2        Load indirect with displacement
+000001A9:   8193        LDD       R25,Z+3        Load indirect with displacement
+000001AA:   93900075    STS       0x0075,R25     Store direct to data space
+000001AC:   93800074    STS       0x0074,R24     Store direct to data space
198:            c++;
+000001AE:   01FD        MOVW      R30,R26        Copy register pair
+000001AF:   9632        ADIW      R30,0x02       Add immediate to word
195:            motors[a].period=*c;
+000001B0:   9612        ADIW      R26,0x02       Add immediate to word
+000001B1:   918D        LD        R24,X+         Load indirect and postincrement
+000001B2:   919C        LD        R25,X          Load indirect
+000001B3:   9713        SBIW      R26,0x03       Subtract immediate from word
+000001B4:   9390007D    STS       0x007D,R25     Store direct to data space
+000001B6:   9380007C    STS       0x007C,R24     Store direct to data space
196:            c++;
+000001B8:   01DF        MOVW      R26,R30        Copy register pair
+000001B9:   9612        ADIW      R26,0x02       Add immediate to word
197:            motors[a].step_number=*c;
+000001BA:   8182        LDD       R24,Z+2        Load indirect with displacement
+000001BB:   8193        LDD       R25,Z+3        Load indirect with displacement
+000001BC:   9390007F    STS       0x007F,R25     Store direct to data space
+000001BE:   93800000    STS       0x0000,R24     Store direct to data space
195:            motors[a].period=*c;
+000001C0:   9612        ADIW      R26,0x02       Add immediate to word
+000001C1:   918D        LD        R24,X+         Load indirect and postincrement
+000001C2:   919C        LD        R25,X          Load indirect
+000001C3:   9713        SBIW      R26,0x03       Subtract immediate from word
+000001C4:   93900087    STS       0x0087,R25     Store direct to data space
+000001C6:   93800086    STS       0x0086,R24     Store direct to data space
197:            motors[a].step_number=*c;
+000001C8:   9614        ADIW      R26,0x04       Add immediate to word
+000001C9:   918D        LD        R24,X+         Load indirect and postincrement
+000001CA:   919C        LD        R25,X          Load indirect
+000001CB:   9715        SBIW      R26,0x05       Subtract immediate from word
+000001CC:   93900089    STS       0x0089,R25     Store direct to data space
+000001CE:   93800088    STS       0x0088,R24     Store direct to data space


Компилирую с помощью WinAVR. Ну вот почему он не может нормально разложить цикл for, а пишет три раза одно и то же? Как мне приказать ему сделать все так, как я хочу?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 ноя 2011, 01:06 
Старожил

Зарегистрирован: 31 янв 2010, 20:19
Сообщения: 4905
Откуда: Донецк-Мариуполь
Компилятор так оптимизировал. Ему показалось быстрее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 ноя 2011, 01:14 
Старожил
Аватара пользователя

Зарегистрирован: 30 янв 2010, 01:03
Сообщения: 643
Откуда: Херсон
Sparker писал(а):
На Си единственный выход, как я вижу - вручную установить этот флаг:
SREG|=1<<1; //Устанавливаем в 1 1-й разряд, т.е. флаг Z
Я пробовал записывать в SREG в Си, компилятор не жалуется.


Так мне не устанавливать нужно, проверить установлен или нет.
на одном форуме видел вот такую SREG & (1<<SREG_C) проверку, но она блин тормознутая
генерит 3 команды, а не одну. Как хотелось бы.
Код:
  if(SREG & (1<<SREG_C))
71e:   0f b6          in   r0, 0x3f   ; 63
720:   00 fe          sbrs   r0, 0
722:   02 c0          rjmp   .+4         ; 0x728 <__vector_12+0x2e>

_________________
Если руки золотые, то не важно с какого места они растут.
Изображение
Изображение


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 ноя 2011, 08:10 
Свой человек

Зарегистрирован: 08 май 2010, 18:00
Сообщения: 172
S_Alex писал(а):
на одном форуме видел вот такую SREG & (1<<SREG_C) проверку, но она блин тормознутая
генерит 3 команды, а не одну. Как хотелось бы.
Код:
  if(SREG & (1<<SREG_C))

Я в ассемблере не шарю и не знаю уменьшит ли это количество команд, но попробуй вот так:
Код:
#define   SREG_C_MASK      1<<SREG_C
if (SREG & SREG_C_MASK)

Если для тебя 3 строчки - это тормоза, то тут я не знаю :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Вопросы о С.
СообщениеДобавлено: 10 ноя 2011, 08:12 
Свой человек

Зарегистрирован: 08 май 2010, 18:00
Сообщения: 172
Sparker писал(а):
Компилирую с помощью WinAVR. Ну вот почему он не может нормально разложить цикл for, а пишет три раза одно и то же? Как мне приказать ему сделать все так, как я хочу?

Написать ассемблерную вставку самому )


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 307 ]  На страницу 1, 2, 3, 4, 5 ... 13  След.

Часовой пояс: UTC + 5 часов


Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot], MasterAlexei, Кот495


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB