Easyelectronics.ru

Электроника для всех
Текущее время: 25 июн 2017, 22:24

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



    • The World's Cheapest PCB Prototyping: 10 шт. 2-слоя 100*100mm 2$(около 140rub), изготовление за 24 часа.
    • Создание принципиальных схем и проектирование печатных плат
    • Крупнейший китайский онлайн магазин радиодеталей. Скидка 50%
    • Просмотр 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
Сообщения: 914
Откуда: 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
Сообщения: 3996
через
#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
Сообщения: 1520
Откуда: Киев
Блин, ну все же уже украдено до нас )

Код:
  #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
Сообщения: 1520
Откуда: Киев
Код будет точно такой же, но без черезжопного 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
Сообщения: 2482
Откуда: Харьков
Как отрицательное число сделать положительным?
к примеру :
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
Сообщения: 1520
Откуда: Киев
Можно, но непрозрачно - с первого взгляда неясно что делается. Ну и варнинги, естетственно.
С другой стороны, у процессора есть команды 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
Сообщения: 4935
Откуда: Донецк-Мариуполь
Компилятор так оптимизировал. Ему показалось быстрее.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: 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 часов


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

Сейчас этот форум просматривают: нет зарегистрированных пользователей


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

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

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