Перейти к содержанию
    

растолкуйте следующее Си-свинство.

моя не понимать что это означает.Си (winavr) это по-моему полное свинство.

 

static void advanceCircleByFixedAngle(void)
{
char    d;

#define DIVIDE_BY_64(val)  (val + (val > 0 ? 32 : -32)) >> 6    /* И вот   это,ну вот что за херня с набором символов? */
    reportBuffer.dx = d = DIVIDE_BY_64(cosinus); /* Вот это, что за хрень такая понаписана ?*/
    sinus += d;
    reportBuffer.dy = d = DIVIDE_BY_64(sinus);
    cosinus -= d;
}

Изменено пользователем ветерок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

моя не понимать что это означает.Си (winavr) это по-моему полное свинство.

 

static void advanceCircleByFixedAngle(void)
{
char    d;

#define DIVIDE_BY_64(val)  (val + (val > 0 ? 32 : -32)) >> 6    /* И вот   это,ну вот что за херня с набором символов? */
    reportBuffer.dx = d = DIVIDE_BY_64(cosinus); /* Вот это, что за хрень такая понаписана ?*/
    sinus += d;
    reportBuffer.dy = d = DIVIDE_BY_64(sinus);
    cosinus -= d;
}

 

#define DIVIDE_BY_64(val) (val + (val > 0 ? 32 : -32)) >> 6

- это МАКРОС под названием DIVIDE_BY_64

если вместо переменной val подставить значение то он вычислит следующее:

1. если значение >0 то берем число 32, если <=0 , то берем число -32

2. к этому числу прибавляем "значение"

3. результат сдвигаем на 6 бит вправо, т.е. делим на 64

 

Это все равно, что подставить в строку

reportBuffer.dx = d = DIVIDE_BY_64(cosinus);

вместо DIVIDE_BY_64(cosinus)

вот это: (cosinus + (cosinus > 0 ? 32 : -32)) >> 6;

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

о,благо дарю !

А где почитать что в d сначала записывается DIVIDE_BY_64(cosinus)

а уже результат в :reportBuffer.dx

По-моему это не только не логично с точки зрения чтения но и вообще возмутительно!

Вольности в Си меня просто поражают,всех бы таких вольномыслящих пересадил на Basic

 

Но это всё фигня по сравнению с makefilesами которые пишут эти же авторы)))

Изменено пользователем ветерок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

моя не понимать что это означает.Си (winavr) это по-моему полное свинство.

Это способ округления. Вместо деления на 64 используется сдвиг вправо на 6 бит. Это справедливо, когда число делится на 64 нацело. Однако, если это не так, то хочется, чтобы деление было по арифметическим правилам, т.е. округлялось в ближайшую сторону, а не усекалось. Для этого и существует типовой способ - добавить (или отнять у отрицательных) половину делителя, а потом уже делить с усечением. Именно это тот дефайн и делает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ещё вопросик

если операция происходит с такой точностью то где указан тип переменной cosinus например

как это не выдаёт ошибку ?

/* Name: main.c
* Project: hid-mouse, a very simple HID example
* Author: Christian Starkjohann
* Creation Date: 2008-04-07
* Tabsize: 4
* Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH
* License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)
* This Revision: $Id$
*/

/*
This example should run on most AVRs with only little changes. No special
hardware resources except INT0 are used. You may have to change usbconfig.h for
different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or
at least be connected to INT0 as well.

We use VID/PID 0x046D/0xC00E which is taken from a Logitech mouse. Don't
publish any hardware using these IDs! This is for demonstration only!
*/

#include <avr/io.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>  /* for sei() */
#include <util/delay.h>     /* for _delay_ms() */

#include <avr/pgmspace.h>   /* required by usbdrv.h */
#include "usbdrv.h"
#include "oddebug.h"        /* This is also an example for using debug macros */

/* ------------------------------------------------------------------------- */
/* ----------------------------- USB interface ----------------------------- */
/* ------------------------------------------------------------------------- */

PROGMEM char usbHidReportDescriptor[52] = { /* USB report descriptor, size must match usbconfig.h */
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x02,                    // USAGE (Mouse)
    0xa1, 0x01,                    // COLLECTION (Application)
    0x09, 0x01,                    //   USAGE (Pointer)
    0xA1, 0x00,                    //   COLLECTION (Physical)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM
    0x29, 0x03,                    //     USAGE_MAXIMUM
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x03,                    //     REPORT_COUNT (3)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x95, 0x01,                    //     REPORT_COUNT (1)
    0x75, 0x05,                    //     REPORT_SIZE (5)
    0x81, 0x03,                    //     INPUT (Const,Var,Abs)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x09, 0x38,                    //     USAGE (Wheel)
    0x15, 0x81,                    //     LOGICAL_MINIMUM (-127)
    0x25, 0x7F,                    //     LOGICAL_MAXIMUM (127)
    0x75, 0x08,                    //     REPORT_SIZE (8)
    0x95, 0x03,                    //     REPORT_COUNT (3)
    0x81, 0x06,                    //     INPUT (Data,Var,Rel)
    0xC0,                          //   END_COLLECTION
    0xC0,                          // END COLLECTION
};
/* This is the same report descriptor as seen in a Logitech mouse. The data
* described by this descriptor consists of 4 bytes:
*      .  .  .  .  . B2 B1 B0 .... one byte with mouse button states
*     X7 X6 X5 X4 X3 X2 X1 X0 .... 8 bit signed relative coordinate x
*     Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0 .... 8 bit signed relative coordinate y
*     W7 W6 W5 W4 W3 W2 W1 W0 .... 8 bit signed relative coordinate wheel
*/
typedef struct{
    uchar   buttonMask;
    char    dx;
    char    dy;
    char    dWheel;
}report_t;

static report_t reportBuffer;
static int      sinus = 7 << 6, cosinus = 0;
static uchar    idleRate;   /* repeat rate for keyboards, never used for mice */


/* The following function advances sin/cos by a fixed angle
* and stores the difference to the previous coordinates in the report
* descriptor.
* The algorithm is the simulation of a second order differential equation.
*/
static void advanceCircleByFixedAngle(void)
{
char    d;

#define DIVIDE_BY_64(val)  (val + (val > 0 ? 32 : -32)) >> 6    /* округление деления */
    reportBuffer.dx = d = DIVIDE_BY_64(cosinus);
    sinus += d;
    reportBuffer.dy = d = DIVIDE_BY_64(sinus);
    cosinus -= d;
}

/* ------------------------------------------------------------------------- */

usbMsgLen_t usbFunctionSetup(uchar data[8])
{
usbRequest_t    *rq = (void *)data;

    /* The following requests are never used. But since they are required by
     * the specification, we implement them in this example.
     */
    if((rq->bmRequestType & USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS){    /* class request type */
        DBG1(0x50, &rq->bRequest, 1);   /* debug output: print our request */
        if(rq->bRequest == USBRQ_HID_GET_REPORT){  /* wValue: ReportType (highbyte), ReportID (lowbyte) */
            /* we only have one report type, so don't look at wValue */
            usbMsgPtr = (void *)&reportBuffer;
            return sizeof(reportBuffer);
        }else if(rq->bRequest == USBRQ_HID_GET_IDLE){
            usbMsgPtr = &idleRate;
            return 1;
        }else if(rq->bRequest == USBRQ_HID_SET_IDLE){
            idleRate = rq->wValue.bytes[1];
        }
    }else{
        /* no vendor specific requests implemented */
    }
    return 0;   /* default for not implemented requests: return no data back to host */
}

/* ------------------------------------------------------------------------- */

int __attribute__((noreturn)) main(void)
{
uchar   i;

    wdt_enable(WDTO_1S);
    /* Even if you don't use the watchdog, turn it off here. On newer devices,
     * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!
     */
    /* RESET status: all port bits are inputs without pull-up.
     * That's the way we need D+ and D-. Therefore we don't need any
     * additional hardware initialization.
     */
    odDebugInit();
    DBG1(0x00, 0, 0);       /* debug output: main starts */
    usbInit();
    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */
    i = 0;
    while(--i){             /* fake USB disconnect for > 250 ms */
        wdt_reset();
        _delay_ms(1);
    }
    usbDeviceConnect();
    sei();
    DBG1(0x01, 0, 0);       /* debug output: main loop starts */
    for(;;){                /* main event loop */
        DBG1(0x02, 0, 0);   /* debug output: main loop iterates */
        wdt_reset();
        usbPoll();
        if(usbInterruptIsReady()){
            /* called after every poll of the interrupt endpoint */
            advanceCircleByFixedAngle();
            DBG1(0x03, 0, 0);   /* debug output: interrupt report prepared */
            usbSetInterrupt((void *)&reportBuffer, sizeof(reportBuffer));
        }
    }
}

/* ------------------------------------------------------------------------- */

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

о,благо дарю !

А где почитать что в d сначала записывается DIVIDE_BY_64(cosinus)

а уже результат в :reportBuffer.dx

По-моему это не только не логично с точки зрения чтения но и вообще возмутительно!

Вольности в Си меня просто поражают,всех бы таких вольномыслящих пересадил на Basic

 

в строке: reportBuffer.dx = d = DIVIDE_BY_64(cosinus);

происходит сразу 2 присваивания: переменным "reportBuffer.dx" и "d" присваивается значение DIVIDE_BY_64(cosinus). И в какой последовательности они присваиваются, знает только компилятор :), а это значит, что программисту, писавшему этот код, было все равно в какой последовательности присваивать значения :)

По части вольностей, это сначала так кажется, вольность в С очень мнимая :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А учебники не читать, это Ваша принципиальная позиция или просто потому что лень?

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Lebets_VI

да точно округление и есть ...

 

Lebets_VI

да действительно сначала reportBuffer.dx=d

а потом всему этому присвоили DIVIDE_BY_64(cosinus)

Да Си он не для всякого разума.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ещё вопросик

если операция происходит с такой точностью то где указан тип переменной cosinus например

как это не выдаёт ошибку ?

 

cosinus имеет тип int, как и sinus. Обеим переменным тип присвоен списком:

static int sinus = 7 << 6, cosinus = 0;

Т.е. через запятую можно было бы наквасить еще много переменных, и они все были бы типа int.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

SSerge

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

к следующему разу некоторые тонкости забываю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

да действительно сначала reportBuffer.dx=d

а потом всему этому присвоили DIVIDE_BY_64(cosinus)

Да Си он не для всякого разума.

неправильно. присвоение 2 переменным происходит одно и то же

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хм..ясно...

я всё же одно понять не могу, реальный синус косинус тут вообще считается или нет ?

мышка же как-то крутится по окружности

я вижу тут эти тригонометрии просто как integer реально определили тоесть это просто переменные,а не функции ?

 

 

Xenia

ооо,точно!!

слона не заметил.

странно для чего присваивать 7 и сдвигать на 6 бит,если можно было сразу присвоить результирующее значение

Изменено пользователем ветерок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

хм..ясно...

я всё же одно понять не могу, реальный синус косинус тут вообще считается или нет ?

мышка же как-то крутится по окружности

странно для чего присваивать 7 и сдвигать на 6 бит,если можно было сразу присвоить результирующее значение

 

static int sinus = 7 << 6, cosinus = 0; - начальное присвоение: синус = 0x1C0, косинус = 0

пляска мышки происходит в ф-ции advanceCircleByFixedAngle(void), т.к. в ней меняются координаты мыши.

а реального вычисления синуса и косинуса здесь не происходит. Автор просто так назвал переменные :) типа синус - это координата Y, а косинус - это координата Х.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно...

почему мышка крутится покруга тогда а не по повёрнутому квадрату

ведь

advanceCircleByFixedAngle(void)

=

static void advanceCircleByFixedAngle(void)
{
char    d;

#define DIVIDE_BY_64(val)  (val + (val > 0 ? 32 : -32)) >> 6    /* округление */
    reportBuffer.dx = d = DIVIDE_BY_64(cosinus); /*  */
    sinus += d;
    reportBuffer.dy = d = DIVIDE_BY_64(sinus);
    cosinus -= d;
}

на сколько я понял.

эта функция даёт линейное приращение x и y сначала под 45градусов вверх затем вниз на восток,затем на вниз на юг и наконец на запад.

тоесть как я уже сказал по квадрату повёрнутому.

 

Xenia

замужем,дети есть ?

:)

Изменено пользователем ветерок

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно...

почему мышка крутится покруга тогда а не по повёрнутому квадрату

 

Ну можно же взять ручку и бумажку и проанализировать 5-10 вызовов этой ф-ции, что бы понять какие данные генерируются вашим HID-устройством.

Если хотите, я проделаю эту процедуру :)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...