выдача 32 бит из одномерного массива (PROGMEM)
- Войдите на сайт для отправки комментариев
Втр, 15/02/2022 - 12:28
Имеется программа для Arduino NANO, в которой есть одномерный массив размером в 4 КБ в связи с чем он из SRAM перенесен во FLASH. Вот так:
const static unsigned long register0[] PROGMEM = {
0x00000000,0x01111111,0x02222222,0x03333333 и т.д.};
Есть указатель, который меняется энкодером от 0x01 до 0x0FFF
Надо по SPI выдать данные из массива наружу. Именно тот dword, на который смотрит указатель.
Для отладки я сделал в одном блоке SPI выдачу указателя, выдачу из массива dword по PROGMEM (я так думаю, по крайней мере) и выдачу из массива dowrd с указателем, прописанным вручную. Сейчас имею: указатель формируется правильно, вывод из массива правильный, если индекс прописан жестко и полный бред при попытке подставить указатель в качестве индекса.
void loop()
{
digitalWrite(lePin, LOW);
shiftOut(dataPin, clkPin, MSBFIRST, freqNow>>8);
shiftOut(dataPin, clkPin, MSBFIRST, freqNow);
digitalWrite(lePin, HIGH);
digitalWrite(lePin, LOW); //Загружаем в ADF данные по указателю freqNow (now debug data)
shiftOut(dataPin, clkPin, MSBFIRST, pgm_read_byte (register0 [freqNow>>24]));
shiftOut(dataPin, clkPin, MSBFIRST, pgm_read_byte(register0 [freqNow]>>16));
shiftOut(dataPin, clkPin, MSBFIRST, pgm_read_byte(register0 [freqNow]>>8));
shiftOut(dataPin, clkPin, MSBFIRST, pgm_read_byte(register0 [freqNow]));
digitalWrite(lePin, HIGH);
digitalWrite(lePin, LOW);
shiftOut(dataPin, clkPin, MSBFIRST, register0 [0x172]>>24);
shiftOut(dataPin, clkPin, MSBFIRST, register0 [0x172]>>16);
shiftOut(dataPin, clkPin, MSBFIRST, register0 [0x172]>>8);
shiftOut(dataPin, clkPin, MSBFIRST, register0 [0x172]);
digitalWrite(lePin, HIGH);
digitalWrite(dataPin, LOW);
delay (100);
}
Потому что ты полный бред пишешь, только он и получается.
сравни внимательно. как ты извлекаешь значение из массива по "жесткому индексу" и как по указателю. Найди отличие, исправь опечатку и проверяй
Написан бред, но обсуждать его невозможно, т.к. нет номеров строк. Вставьте код правильно и сделайте его полным, а не огрызком, чтобы можно было скомпилировать и запустить.
И, да, кстати, какая именно религия запретила Вам использовать pgm_read_dword ? Если уж Вы не умеете формировать байтовые адреса, это могло бы выручить.
Здравствуйте, Евгений!
Дело не в религии, а, вероятно, в отсутствии необходимых навыков. shiftOut, насколько я знаю, умеет работать только с byte. Так что если надо выдать 32 бита по SPI по shiftOut, то надо байтами выводить. Скетч может и корявый, но рабочий весь, за исключением чтения из массива по указателю. Потому и не стал его весь публиковать. Отдельное спасибо b707. Он мою проблему понял и задал вектор ее поиска. Разбираюсь, но пока тщетно. Указатель у меня "не той системы"? Есть у меня простой выход - уйти на Cortex-M0+, там SRAM больше и работает все, проверено (без PROGMEM, естественно), но хочется разобраться.
Всё, что могу сказать - это повторить, если Вы не поняли с первого раза: Вставьте код правильно и сделайте его полным, а не огрызком, чтобы можно было скомпилировать и запустить
Что же до pgm_read_dword, то какое он имеет отношение к shiftOut и чем он ему мешает, знаете только Вы :(
Hologram, для начала - не надо писать что вы отправляете данные в шифтрегистр "по SPI" - это неверно и раздражает жутко. При некоторой похожести протокол общения со сдвиговым - ЭТО НЕ SPI
Далее, по вашим ошибкам. При чем тут указатель! Вы два обращения к массиву - через переменную и через константный индекс - сравнили? у вас в одном случае банальная опечатка.
Когда найдете - а оно все равно не заработает - тогда приходите снова. И лучше бы вы для начала почитали, чем отличается доступ в памяти к байту и к лонгу. Причем не важно - в прогмем или нет, у вас непонимание более базовое