Официальный сайт компании Arduino по адресу arduino.cc
Указатели указатели указатели (помогите разобраться)
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Пнд, 25/02/2019 - 17:24
Доброго дня !
Задача следующая:
использую Mega 2560
работаю с PWM-ами
нужно их постоянно обновлять
имеется массив из 15-ти байт
эти 15 байт надо переложить в 15ть регистров OCR
пытаюсь делать это в цикле
для этого создаю вот такой массив
unsigned int *OCR[15] = {(unsigned int*)&OCR3B, (unsigned int*)&OCR3C, (unsigned int*)&OCR0B, (unsigned int*)&OCR3A, (unsigned int*)&OCR4A, (unsigned int*)&OCR4B, (unsigned int*)&OCR4C, (unsigned int*)&OCR2B, (unsigned int*)&OCR2A, (unsigned int*)&OCR1A, (unsigned int*)&OCR1B, (unsigned int*)&OCR1C, (unsigned int*)&OCR5C, (unsigned int*)&OCR5B, (unsigned int*)&OCR5A};
далее в цикле работаю
for (byte w = 0; w < 15; w++) { if (PWM[w] != BA[w]) { *OCR[w] = PWM[w]; }; if (PWM[w] >= PWMMin) {PWMzero = false;}; }
...вроде всё нормально работает но иногда какие-то глюки как будто новое значение ШИМа залетает не в тот OCR
+ уверен что дело именно в этих кусках кода т.к. если делать всё без цикла то проблема исчезает
- думаю что не правильно работаю с указателями НО что именно ????
Тут сразу несколько ошибок. Во-первых, Вы смешали в один массив разные данные. Например, OCR3B - 16-ти разрядный, а OCR0B - восьмиразрядный.
Вот вторых, Вы их описани как указатели на int и тем самым потеряли то, что они на самомд деле регистры, а это важно, т.к. запись/чтение 16-тиразрядные регистры осуществляется не как попало, а в строго определённом порядке (даташит - 17.3). Целые же компилятор может писать как попало.
Так что попробыйте сгачала описать их все однородно, причём правильно, сохраняя тот факт, что они регистры, а не просто целые. Думаю, должно помочь. Если нет, то там посмотрим.
про 16ти разрядные....8ми разрядные
все эти регистры я вытащил из тела analogWrite(pin, 0...255) и по сути просто избавился от перебора case, проведя инициализацию заранее
да мне и не нужны 16ти разрядные ШИМы
про смешение в одном массиве ....
это же адреса регистров и они все одинаковой разрядности (адреса)
или я вообще не туда :(
да мне и не нужны 16ти разрядные ШИМы
Это Ваши проблемы. Писать в них всё равно нужно правильно, ссылку на раздел даташита я давал.
Вы кодом помочь можете ?
Я? Пока нет, сейчас хоккей начинается.
мне не срочно
если найдёте время...)))...буду признателен
мне не срочно
если найдёте время...)))...буду признателен
думаю вы не поняли. Это была ирония. Здесь код за других писать не принято.
Вам надо разобраться. что такое регистры и чем они отличаются от обычных переменных. Информацию вам дали.
А если это для вас сложно - тогда не лезьте "улучшать" AnalogWrite() - пользуйтесь кодом с case
а вот такой код
компилятор сам "превратит" в правильную последовательность записи сначала старшего байта потом младшего ?
[/quote]
А если это для вас сложно - тогда не лезьте "улучшать" AnalogWrite() - пользуйтесь кодом с case
[/quote]
нет времени порожняк гонять (много бесполезных команд)
дайте хоть пример как правильно писать в РЕГИСТР через указатель ?
а вот такой код
компилятор сам "превратит" в правильную последовательность записи сначала старшего байта потом младшего ?
а вот такой код
компилятор сам "превратит" в правильную последовательность записи сначала старшего байта потом младшего ?
...а то же самое через указатель как реализовать ?
нет времени порожняк гонять (много бесполезных команд)
вы чего пытаетесь добиться-то? Улучшить Вайринг? или построить конкретный проект?
Каждый конкретный пин PWM завязан на свой таймер и свой регистр. Если Вы не пишете свою "лучщую библиотеку на все времена" - значит у вас каждый пин несет свою нагрузку и никакого switch-case там и в помине нет и никакого выбора из 15 пинов через массив нафик не нужно.
нет времени порожняк гонять (много бесполезных команд)
вы чего пытаетесь добиться-то? Улучшить Вайринг? или построить конкретный проект?
Каждый конкретный пин PWM завязан на свой таймер и свой регистр. Если Вы не пишете свою "лучщую библиотеку на все времена" - значит у вас каждый пин несет свою нагрузку и никакого switch-case там и в помине нет и никакого выбора из 15 пинов через массив нафик не нужно.
...ооооо....значит ли это что компилятор не включит в результирующий код все эти case для каждого шима ?
...ооооо....значит ли это что компилятор не включит в результирующий код все эти case для каждого шима ?
зависит от того, как вы их пропишете. Если у вас пин - константа или задан дефайном, оптимизатор, скорее всего, выкинет все ветки switch. кроме нужной.
Но я имел в виду другое. Пишите код под конткретный таймер и конкретный регистр, восе без массивов и свитчей
...ооооо....значит ли это что компилятор не включит в результирующий код все эти case для каждого шима ?
зависит от того, как вы их пропишете. Если у вас пин - константа или задан дефайном, оптимизатор, скорее всего, выкинет все ветки switch. кроме нужной.
Но я имел в виду другое. Пишите код под конткретный таймер и конкретный регистр, восе без массивов и свитчей
да...сейчас так и сделано...для каждого шима отдельная строка под конкретный регистр
попробовал заменять запись в регистр стандртной analogWrite (сначала один выход потом 2 и т.д.) и похоже компилятор действительно выкидывает лишние case (судя по размеру занимаемой скетчем)
похоже вопрос снят
однако всё же призамене, во всех 15ти строках, записи в регист на analogWrite, размер скетчя вырос на 430 байт
...а то же самое через указатель как реализовать ?
Не знаю, т.к. не знаю, чего именно Вы хотите добиться.
Только это не самая первая Ваша проблема. Первая проблема - смесь 8-ми и 16-битных регистров.
Вы ведь всё преобразуете к указателю на int. Значит любая запись будет производиться в ДВА байта! Итак Вы пишете ДВА байта по адресу, где живёт 8-битный регистр. Куда пишется второй байт? Напрягитесь! Правильно, в соседний регистр. Вы понимаете, что там начинается?
...там начинается другой шим
и с учетом этого не стоит этот огород городить
однако всё же призамене, во всех 15ти строках, записи в регист на analogWrite, размер скетчя вырос на 430 байт
я вам уже третий раз говорю -не обязательно использовать analogWrite. Пишите через регистры напрямую. Только не надо городить свитч-кейс или массив ссылок - пишите каждый канал отдельно.
Если все же хочется упаковывать управления пинами в классах,то использовать лямда функции .
Если все же хочется упаковывать управления пинами в классах,то использовать лямда функции .
Зачем?
Если все же хочется упаковывать управления пинами в классах,то использовать лямда функции .
Зачем?
Просто Пух, после автоматов, до них добрался.
Просто Пух, после автоматов, до них добрался.
А! Понятно :)