Goliard Опубликовано 1 декабря, 2016 Поделиться Опубликовано 1 декабря, 2016 Доброго времени суток. Требуется помощь в переделывание прошивки для работы сервопривода. Я сам так и не разобрался, теперь прошу помощи. Готов оплатить труд, Вообщем имеется код прошивки под Ардуино на атмеге 328 и нужно изменить прошивку на "чистый" С++. UselessMachine.pde 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Viktor26 Опубликовано 1 декабря, 2016 Поделиться Опубликовано 1 декабря, 2016 Почему именно на ++? Может просто на чистый С? 0 Не знаеш как? Спроси у Google'а !!! Ссылка на комментарий Поделиться на другие сайты Поделиться
20% скидка на весь каталог электронных компонентов в ТМ Электроникс!Акция "Лето ближе - цены ниже", успей сделать выгодные покупки!Плюс весь апрель действует скидка 10% по промокоду APREL24 + 15% кэшбэк и бесплатная доставка!Перейти на страницу акции Реклама: ООО ТМ ЭЛЕКТРОНИКС, ИНН: 7806548420, info@tmelectronics.ru, +7(812)4094849
солар Опубликовано 2 декабря, 2016 Поделиться Опубликовано 2 декабря, 2016 7 часов назад, Viktor26 сказал: Почему Студенты и начинающие в подавляющем своем большинстве думают так. @Goliard , библиотеку серво ещё нужно. 0 Я не раздаю удочки. Я продаю рыбу. Ссылка на комментарий Поделиться на другие сайты Поделиться
Особенности хранения литиевых аккумуляторов и батареекПотеря емкости аккумулятора напрямую зависит от условий хранения и эксплуатации. При неправильном хранении даже самый лучший литиевый источник тока с превосходными характеристиками может не оправдать ожиданий. Технология, основанная на рекомендациях таких известных производителей литиевых источников тока, как компании FANSO и EVE Energy, поможет организовать правильный процесс хранения батареек и аккумуляторов. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
Nilas Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 (изменено) Здравствуйте всем! В программировании на С новичок. Переделываю программу из Ардуино в АВР Студию 4. Попался вот такой кусок кода: .............................................. void _orientCoordinates(uint16_t &x1, uint16_t &y1) { switch (_orientation) { case 0: // ok break; case 1: // ok y1 = _maxY - y1 - 1; _swap(x1, y1); break; case 2: // ok x1 = _maxX - x1 - 1; y1 = _maxY - y1 - 1; break; case 3: // ok x1 = _maxX - x1 - 1; _swap(x1, y1); break; } } .............................................. void _swap(uint16_t &a, uint16_t &b) { uint16_t w = a; a = b; b = w; } Посмотрев в инете, понял, что &a и &b - это "ссылки" на языке С++. Компилятор С ругается на такое. Как я понял, "ссылка" - это псевдоним переменной и все операции в итоге совершаются с ними. Можно ли тогда сделать код без "ссылок" и оставить одни переменные? Наведите на нужную мысль void _swap(uint16_t a, uint16_t b) // сделать так??? { uint16_t w = a; a = b; b = w; } void _orientCoordinates(uint16_t x1, uint16_t y1) { // и тут убрать??? Изменено 23 ноября, 2020 пользователем Nilas 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Выбираем схему BMS для корректной работы литий-железофосфатных (LiFePO4) аккумуляторов Обязательным условием долгой и стабильной работы Li-FePO4-аккумуляторов, в том числе и производства EVE Energy, является применение специализированных BMS-микросхем. Литий-железофосфатные АКБ отличаются такими характеристиками, как высокая многократность циклов заряда-разряда, безопасность, возможность быстрой зарядки, устойчивость к буферному режиму работы и приемлемая стоимость. Но для этих АКБ, также как и для других, очень важен контроль процесса заряда и разряда, а специализированных микросхем для этого вида аккумуляторов не так много. Инженеры КОМПЭЛ подготовили список имеющихся микросхем и возможных решений от разных производителей. Подробнее>> Реклама: АО КОМПЭЛ, ИНН: 7713005406, ОГРН: 1027700032161
Alex Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 Замените на указатели. PS: Ссылка - это тот же указатель. Просто доступ к ним синтаксически организуется как к переменной. Есть, конечно, ещё нюансы - не может быть пустой, и т.д... Но это Вам не нужно. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
BARS_ Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 (изменено) 3 часа назад, Nilas сказал: void _swap(uint16_t a, uint16_t b) // сделать так??? Вот так: oid _swap(uint16_t *a, uint16_t *b) { uint16_t w = *a; *a = *b; *b = w; } Изменено 23 ноября, 2020 пользователем BARS_ 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nilas Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 (изменено) Переделал на указатели: void _orientCoordinates(uint16_t *x1, uint16_t *y1) { switch (_orientation) { case 0: // ok break; case 1: // ok *y1 = _maxY - *y1 - 1; _swap(x1, y1); break; case 2: // ok *x1 = _maxX - *x1 - 1; *y1 = _maxY - *y1 - 1; break; case 3: // ok *x1 = _maxX - *x1 - 1; _swap(x1, y1); break; } } void _swap(uint16_t *a, uint16_t *b) { uint16_t w = *a; *a = *b; *b = w; } Объявил в хидер-файле функции как: void _swap(uint16_t *a, uint16_t *b); void _orientCoordinates(uint16_t *x1, uint16_t *y1); Но теперь компилятор выдает варнинги на тип переменных, хотя по моему разумению вроде как все одной масти (uint16_t): void _setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { _orientCoordinates(x0, y0); _orientCoordinates(x1, y1); if (x1 < x0) {_swap(x0, x1);} if (y1 < y0) {_swap(y0, y1);} .с:292:5: warning: passing argument 1 of '_orientCoordinates' makes pointer from integer without a cast [enabled by default] .h:148:9: note: expected 'uint16_t *' but argument is of type 'uint16_t' и т.д. на каждый аргумент. Хотя на эту функцию не ругается: ........................................... case 1: // ok *y1 = _maxY - *y1 - 1; _swap(x1, y1); break; ............................................ Или в вызове функции надо сразу ставить указатель: _orientCoordinates(*x0, *y0); , но тогда, как я понимаю, в функцию будут посылаться указатели на переменную (и получится указатель указателя), и обрабатываться будут они, а не переменные? Изменено 23 ноября, 2020 пользователем Nilas 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 Цитата _orientCoordinates(x0, y0); _orientCoordinates(x1, y1); Если функция принимает указатель, то логично же, передавать ей нужно адрес переменной, а не значение. 18 минут назад, Nilas сказал: Хотя на эту функцию не ругается: _swap(x1, y1); Потому, что x1 и y1 - указатели. И т.к. функция их же (указатели) и принимает, то ошибок нет. PS: Погуглите и почитайте про указатели. Это элементарное, что есть в этом языке. Так сказать, азы ... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nilas Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 Переделал на void _setWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) { _orientCoordinates(*x0,* y0); _orientCoordinates(*x1, *y1); if (x1 < x0) {_swap(*x0,* x1);} if (y1 < y0) {_swap(*y0, *y1);} Теперь ругается на каждый аргумент: .c:292:24: error: invalid type argument of unary '*' (have 'uint16_t') Совсем уже запутался. Понимаю что указатель это адрес переменной, но вот в использовании в функциях... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
BARS_ Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 _swap(&x0, &x1) 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Yurkin2015 Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 4 minutes ago, Nilas said: указатель это адрес переменной Указатель это переменная. Чтобы получить адрес, нужно использовать & _orientCoordinates(&x0, &y0); 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nilas Опубликовано 23 ноября, 2020 Поделиться Опубликовано 23 ноября, 2020 Получается, что при вызове функции берем адрес переменной _swap(&x0, &x1) В самой функции адрес "перекочевывает" в указатель переменной void _swap(uint16_t *a, uint16_t *b) И в самой функции оперирует с переменными через адресацию. Сейчас все нормально скомпилировалось! и в коде, и в голове 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 24 ноября, 2020 Поделиться Опубликовано 24 ноября, 2020 Неужели проще тыкать и писать на форум кучу слов, вместо того, чтобы сделать 1 запрос в поисковике и почитать ? Тема указателей разжёвана до некуда ... 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nilas Опубликовано 28 ноября, 2020 Поделиться Опубликовано 28 ноября, 2020 (изменено) Здравствуйте всем! В продолжение темы: третий день бьюсь с чтением из памяти даных. Уже и раскомментировал его, и вроде должен работать, но выдает не то, что надо. Уже всякого начитался в интернете, но в симуляции АВР Студии берутся не те данные, которые должны идти дальше в программе. Вот так сейчас: Скрытый текст ---------------------------------------шрифты--------------------------------------------------- #define fontdatatype const uint8_t #include <avr/pgmspace.h> fontdatatype Terminal6x8[] PROGMEM = { 0x06, 0x08, 0x20, 0x60, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Code for char пробел …………………………………………………………………………………. 0x06, 0x00, 0x24, 0x7E, 0x24, 0x7E, 0x24, // Code for char # Вызов из main: …………………………………………………………………. setFont(Terminal6x8); // Terminal6x8 – это и есть первый адрес шрифта drawChar(10, 180, 'D',COLOR_RED ); // setFont(&Terminal6x8[0]); //ПРОБОВАЛ ТАК, хотя это одно и то же ................................................................ В хидере: /* Font defines */ #define FONT_HEADER_SIZE 4 // 1: pixel width of 1 font character, 2: pixel height, #define readFontByte(x) pgm_read_byte(&cfont.font[x]) // берет байт Х по адресу cfont.font extern const uint8_t Terminal6x8[]; extern const uint8_t Terminal11x16[]; struct _currentFont { const uint8_t* font; uint8_t width; uint8_t height; uint8_t offset; uint8_t numchars; uint8_t nbrows; }cfont; …………………………………………………………………………….. /// Draw single character (pixel coordinates) uint16_t drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color); /// Set current font /// @param font Font name void setFont(const uint8_t * font); в .С файле …………………………………………………………………………. void setFont(const uint8_t* font) {БЫЛО: cfont.font = font; //адрес таблицы символов (указатель на таблицу) cfont.width = font[0]; //байт ширины символа cfont.height = font[1]; //байт высоты символа cfont.offset = font[2]; //байт смещения кода символа cfont.numchars = font[3]; //байт кол-ва символов в таблице шрифтов *********************************************СДЕЛАЛ ТАК, т.к. данные берем из памяти программ: cfont.font = font; cfont.width = (pgm_read_byte(font[0])); // БЕРЕТ cfont.height = (pgm_read_byte(font[1])); // ДАННЫЕ cfont.offset = (pgm_read_byte(font[2])); // НЕ ИЗ cfont.numchars = (pgm_read_byte(font[3])); // ТАБЛИЦЫ cfont.nbrows = cfont.height / 8; //кол-во целых байтов в высоту if (cfont.height % 8) cfont.nbrows++; // если высота делится с остатком, то +1 байт в высоту } uint16_t drawChar(uint16_t x, uint16_t y, uint16_t ch, uint16_t color) { uint8_t charData, charWidth; uint8_t h, i, j; uint16_t charOffset; charOffset = (cfont.width * cfont.nbrows) + 1; // кол-во байт на каждый символ charOffset = (charOffset * (ch - cfont.offset)) + FONT_HEADER_SIZE; // кол-во байт для смещения charWidth = pgm_read_byte(cfont.font[charOffset]); // первый байт – ширина символа charOffset++; // на первый байт данных символа for (i = 0; i <= charWidth; i++) { // каждый столбец шрифта (+1 пустой для интервала h = 0; // отслеживание высоты символа for (j = 0; j < cfont.nbrows; j++) { // каждый байт столбца if (i == charWidth) charData = (uint8_t)0x0; // вставить пустой столбец else charData = pgm_read_byte(cfont.font[charOffset]); charOffset++; // обработка каждой строки шрифта for (uint8_t k = 0; k < 8; k++) { if (h >= cfont.height) break; // выход, если высота больше высоты шрифта if (bitRead(charData, k)) drawPixel(x + i, y + (j * 8) + k, color); else drawPixel(x + i, y + (j * 8) + k, _bgColor); h++; }; }; }; return charWidth; } void drawText(uint16_t x, uint16_t y, char *s, uint16_t color) { uint16_t currx = x; // Print every character in string for (uint8_t k = 0; k < strlen(s); k++) { currx += drawChar(currx, y, s[k], color) + 1; } } ……………………………………………………………………………………………. Компилируется без ошибок. Не могу понять, где не так делаю. Изменено 28 ноября, 2020 пользователем Nilas 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 28 ноября, 2020 Поделиться Опубликовано 28 ноября, 2020 8 часов назад, Nilas сказал: должен работать setFont принимает const uint8_t* , а Вы ему подсовываете fontdatatype PROGMEM. Откуда уверенность, что всё должно работать ? Дальше программу даже не смотрел. Хватило этого 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nilas Опубликовано 28 ноября, 2020 Поделиться Опубликовано 28 ноября, 2020 fontdatatype определено дефайном как const uint8_t. PROGMEM указывает на flash память. 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Alex Опубликовано 28 ноября, 2020 Поделиться Опубликовано 28 ноября, 2020 1 час назад, Nilas сказал: PROGMEM указывает на flash память. А компилятор сам должен догадаться, что Вы в setFont захотите передать указатель на область flash ? 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Nilas Опубликовано 29 ноября, 2020 Поделиться Опубликовано 29 ноября, 2020 Понял почему были не те данные. В setFont(Terminal6x8); Terminal6x8 является указателем на массив (содержит его адрес), но если обращаться к отдельному его элементу, то надо указывать его адрес : cfont.height = (pgm_read_byte(&(font[1]))); Сейчас идут нужные данные из flash памяти. Буду дальше ковырять код 10 часов назад, Alex сказал: А компилятор сам должен догадаться Видимо сам догадывается, раз всё компилиться и работает 0 Ссылка на комментарий Поделиться на другие сайты Поделиться
Рекомендуемые сообщения
Присоединяйтесь к обсуждению
Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.
Примечание: Ваш пост будет проверен модератором, прежде чем станет видимым.