Обновление к этому — кажется, есть некоторые проблемы с функциями триггера в 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++; }
Я предполагаю, что пропавший (
после if
это опечатка.
Указанная методика исследования при отсутствии отладчика:
Подтвердите еще раз этот тест if( ( 0b00000000111111111110101010111110 >> 16 ) & ( 1 << bitpos ) )
работает. Собрать (распечатать) результат для каждого bitpos
хранить 0b00000000111111111110101010111110
в элементе 0 массива. Повторите с if( ( ColourWheel[0] >> 16 ) & ( 1 << bitpos ) )
, Соберите результаты и сравните с базовым вариантом.
хранить 0b00000000111111111110101010111110
во всех элементах массива. Повторите с if( ( ColourWheel[Colour] >> 16 ) & ( 1 << bitpos ) )
для нескольких разных значений цвета (назначается вручную). Соберите результаты и сравните с базовым вариантом.
хранить 0b00000000111111111110101010111110
во всех элементах массива. Повторите с if( ( ColourWheel[Colour] >> 16 ) & ( 1 << bitpos ) )
со значением для цвета обычно назначается. Соберите результаты и сравните с базовым вариантом.
Вернитесь к исходной программе и повторите тестирование. Соберите результаты и сравните с базовым вариантом.
Уверен, что значение в 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;
}