ветерок 0 27 мая, 2012 Опубликовано 27 мая, 2012 (изменено) · Жалоба моя не понимать что это означает.Си (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; } Изменено 27 мая, 2012 пользователем ветерок Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lebets_VI 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба моя не понимать что это означает.Си (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; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ветерок 0 27 мая, 2012 Опубликовано 27 мая, 2012 (изменено) · Жалоба о,благо дарю ! А где почитать что в d сначала записывается DIVIDE_BY_64(cosinus) а уже результат в :reportBuffer.dx По-моему это не только не логично с точки зрения чтения но и вообще возмутительно! Вольности в Си меня просто поражают,всех бы таких вольномыслящих пересадил на Basic Но это всё фигня по сравнению с makefilesами которые пишут эти же авторы))) Изменено 27 мая, 2012 пользователем ветерок Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 36 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба моя не понимать что это означает.Си (winavr) это по-моему полное свинство. Это способ округления. Вместо деления на 64 используется сдвиг вправо на 6 бит. Это справедливо, когда число делится на 64 нацело. Однако, если это не так, то хочется, чтобы деление было по арифметическим правилам, т.е. округлялось в ближайшую сторону, а не усекалось. Для этого и существует типовой способ - добавить (или отнять у отрицательных) половину делителя, а потом уже делить с усечением. Именно это тот дефайн и делает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ветерок 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба ещё вопросик если операция происходит с такой точностью то где указан тип переменной 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)); } } } /* ------------------------------------------------------------------------- */ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lebets_VI 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба о,благо дарю ! А где почитать что в d сначала записывается DIVIDE_BY_64(cosinus) а уже результат в :reportBuffer.dx По-моему это не только не логично с точки зрения чтения но и вообще возмутительно! Вольности в Си меня просто поражают,всех бы таких вольномыслящих пересадил на Basic в строке: reportBuffer.dx = d = DIVIDE_BY_64(cosinus); происходит сразу 2 присваивания: переменным "reportBuffer.dx" и "d" присваивается значение DIVIDE_BY_64(cosinus). И в какой последовательности они присваиваются, знает только компилятор :), а это значит, что программисту, писавшему этот код, было все равно в какой последовательности присваивать значения :) По части вольностей, это сначала так кажется, вольность в С очень мнимая :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SSerge 4 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба А учебники не читать, это Ваша принципиальная позиция или просто потому что лень? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ветерок 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба Lebets_VI да точно округление и есть ... Lebets_VI да действительно сначала reportBuffer.dx=d а потом всему этому присвоили DIVIDE_BY_64(cosinus) Да Си он не для всякого разума. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Xenia 36 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба ещё вопросик если операция происходит с такой точностью то где указан тип переменной cosinus например как это не выдаёт ошибку ? cosinus имеет тип int, как и sinus. Обеим переменным тип присвоен списком: static int sinus = 7 << 6, cosinus = 0; Т.е. через запятую можно было бы наквасить еще много переменных, и они все были бы типа int. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ветерок 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба SSerge да мне бесполезно читать,я раз в год программирую к следующему разу некоторые тонкости забываю. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lebets_VI 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба да действительно сначала reportBuffer.dx=d а потом всему этому присвоили DIVIDE_BY_64(cosinus) Да Си он не для всякого разума. неправильно. присвоение 2 переменным происходит одно и то же Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ветерок 0 27 мая, 2012 Опубликовано 27 мая, 2012 (изменено) · Жалоба хм..ясно... я всё же одно понять не могу, реальный синус косинус тут вообще считается или нет ? мышка же как-то крутится по окружности я вижу тут эти тригонометрии просто как integer реально определили тоесть это просто переменные,а не функции ? Xenia ооо,точно!! слона не заметил. странно для чего присваивать 7 и сдвигать на 6 бит,если можно было сразу присвоить результирующее значение Изменено 27 мая, 2012 пользователем ветерок Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lebets_VI 0 27 мая, 2012 Опубликовано 27 мая, 2012 · Жалоба хм..ясно... я всё же одно понять не могу, реальный синус косинус тут вообще считается или нет ? мышка же как-то крутится по окружности странно для чего присваивать 7 и сдвигать на 6 бит,если можно было сразу присвоить результирующее значение static int sinus = 7 << 6, cosinus = 0; - начальное присвоение: синус = 0x1C0, косинус = 0 пляска мышки происходит в ф-ции advanceCircleByFixedAngle(void), т.к. в ней меняются координаты мыши. а реального вычисления синуса и косинуса здесь не происходит. Автор просто так назвал переменные :) типа синус - это координата Y, а косинус - это координата Х. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ветерок 0 28 мая, 2012 Опубликовано 28 мая, 2012 (изменено) · Жалоба Странно... почему мышка крутится покруга тогда а не по повёрнутому квадрату ведь 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 замужем,дети есть ? :) Изменено 28 мая, 2012 пользователем ветерок Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Lebets_VI 0 28 мая, 2012 Опубликовано 28 мая, 2012 · Жалоба Странно... почему мышка крутится покруга тогда а не по повёрнутому квадрату Ну можно же взять ручку и бумажку и проанализировать 5-10 вызовов этой ф-ции, что бы понять какие данные генерируются вашим HID-устройством. Если хотите, я проделаю эту процедуру :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться