Моя подпрограмма прерывания не обращается к массиву правильно

Обновление к этому — кажется, есть некоторые проблемы с функциями триггера в math.h (с использованием компилятора MPIDE) — неудивительно, что я не смог увидеть это с моим отладчиком, который использовал свой собственный math.h и поэтому дал мне ожидаемый (правильные решения). Я обнаружил это случайно на платах микрочипов и вместо этого реализовал алгоритм «быстрый синус / косинус» (см. Devmaster dot com для этого). Мои массивы ISR и ColourWheel теперь работают отлично.

Должен сказать, что, будучи новичком в C / C ++, я потратил много часов на просмотр и повторный анализ моего собственного кода на наличие ошибок. Последнее, что мне пришло в голову, было то, что некоторые очень простые функции, которые, без сомнения, были написаны десятилетия назад, могли создать такие проблемы.

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

Хей-хо !! — когда у меня будет возможность, я опубликую ссылку на видео с U-образной трубкой, показывающее волновую функцию, которую я теперь смог запрограммировать, и которая выглядит неплохо на моем светодиодном кубе.

Рассел

п.с.
Огромное спасибо всем вам за вашу помощь здесь — это остановило меня, чтобы я полностью сдался, предоставив мне несколько путей, чтобы преследовать — конечно, не очень много знал о бесконечности до того, как об этом так узнали, и о некоторых систематических способах выработать надежный подход к отладке. ,

У меня проблема при попытке доступа к массиву в процедуре прерывания.

Ниже приведен фрагмент кода внутри ISroutine.

if (CubeStatusArray[x][y][Layer]){
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
if((ColourWheel[Colour]>>16)&(1<<bitpos)) { // This line seems to cause trouble
setHigh(SINRED_PORT,SINRED_PIN);
}
else {
setLow(SINRED_PORT,SINRED_PIN);
}
}
}
..........

ColourWheel [Color] был объявлен следующим образом в начале моей программы (вне какой-либо функции)

static volatile uint32_t ColourWheel[255]; //this is the array from which
//the colours can be obtained -
//all set as 3 eight bit numbers
//using up 24 bits of a 32bit
//unsigned int.

Этот фрагмент кода использует каждый бит восьмибитного сегмента кода и соответственно устанавливает высокий / низкий порт / вывод с помощью MSB (затем у меня есть другой код, который обновляет микросхему драйвера TLC5940 IC LED для каждого высокого уровня / низкий на выводе, и код продолжает принимать зеленые и синие 8 битов аналогичным образом).

Это не работает, и мои цвета, выводимые на светодиоды, работают неправильно.

Тем не менее, если я изменю код следующим образом, процедура будет работать

if (CubeStatusArray[x][y][Layer]){
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
if(0b00000000111111111110101010111110>>16)&(1<<bitpos)) { // This line seems to cause trouble
setHigh(SINRED_PORT,SINRED_PIN);}
else {
setLow(SINRED_PORT,SINRED_PIN);
}
}
}
..........

(фактическое двоичное число в строке не имеет значения (первые 8 битов всегда равны нулю, следующие 8 битов представляют красный цвет, следующие — синий цвет и т. д.)

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

Ниже приведен фактический код, показывающий полное обновление RGB:

                if (CubeStatusArray[x][y][Layer]){
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
{if((ColourWheel[Colour]>>16)&(1<<bitpos))
{setHigh(SINRED_PORT,SINRED_PIN);}
else
{setLow(SINRED_PORT,SINRED_PIN);}}
{if((ColourWheel[Colour]>>8)&(1<<bitpos))
{setHigh(SINGREEN_PORT,SINGREEN_PIN);}
else
{setLow(SINGREEN_PORT,SINGREEN_PIN);}}
{if((ColourWheel[Colour])&(1<<bitpos))
{setHigh(SINBLUE_PORT,SINBLUE_PIN);}
else
{setLow(SINBLUE_PORT,SINBLUE_PIN);}}
pulse(SCLK_PORT, SCLK_PIN);
pulse(GSCLK_PORT, GSCLK_PIN);
Data_Counter++;
GSCLK_Counter++;                          }

0

Решение

Я предполагаю, что пропавший ( после if это опечатка.

Указанная методика исследования при отсутствии отладчика:

  1. Подтвердите еще раз этот тест if( ( 0b00000000111111111110101010111110 >> 16 ) & ( 1 << bitpos ) ) работает. Собрать (распечатать) результат для каждого bitpos

  2. хранить 0b00000000111111111110101010111110 в элементе 0 массива. Повторите с if( ( ColourWheel[0] >> 16 ) & ( 1 << bitpos ) ), Соберите результаты и сравните с базовым вариантом.

  3. хранить 0b00000000111111111110101010111110 во всех элементах массива. Повторите с if( ( ColourWheel[Colour] >> 16 ) & ( 1 << bitpos ) ) для нескольких разных значений цвета (назначается вручную). Соберите результаты и сравните с базовым вариантом.

  4. хранить 0b00000000111111111110101010111110 во всех элементах массива. Повторите с if( ( ColourWheel[Colour] >> 16 ) & ( 1 << bitpos ) ) со значением для цвета обычно назначается. Соберите результаты и сравните с базовым вариантом.

  5. Вернитесь к исходной программе и повторите тестирование. Соберите результаты и сравните с базовым вариантом.

0

Другие решения

Уверен, что значение в ColourWheel[Colour] не так, как ожидалось или нестабильно. Проверьте диапазон индекса и получите доступ один раз. Увеличение скорости кода включено.


[Редактировать] Если принимающей стороне не нравятся более медленные изменения сигнала, вызванные заменой константы на ColourWheel[Colour]>>16Более эффективный код может решить эту проблему.


 if (CubeStatusArray[x][y][Layer]){
uint32_t value = 0;
uint32_t maskR = 0x800000UL;
uint32_t maskG = 0x8000UL;
uint32_t maskB = 0x80UL;
if ((Colour >= 0) && (Colour < 255)) {
value = ColourWheel[Colour];
}
// All you need to do is shift 'value'
for(int8_t bitpos=7; bitpos >= 0; bitpos--){
{ if( (value & maskR) // set red
}
{ if( (value & maskG) // set green
}
{ if( (value & maskB) // set blue
}
value <<= 1;
}
0

По вопросам рекламы [email protected]