我的中断例程无法正确访问数组



对此的更新-math.h(使用MPIDE编译器)中的trig函数似乎存在一些问题-难怪我的调试器使用自己的math.h看不到这一点,因此给了我预期的(正确的解决方案)。我在微芯片板上偶然发现了这一点,并实现了"快速正弦/余弦"算法(请参阅devmaster dot.com)。我的ISR和ColourWheel阵列现在可以完美工作了。

我必须说,作为一个C/C++的新手,我已经花了很多时间来审查和重新审查我自己的代码中的错误。我脑海中最后一件可能的事情是,毫无疑问,几十年前编写的一些非常基本的函数可能会出现这样的问题。

我想,如果我能访问实际阵列的屏幕转储,我会更早地发现这个问题,但由于我的芯片连接到我的led立方体,我无法直接访问芯片中的数据。

嘿,嗨!!-当我有机会的时候,我会发布一个u管视频的链接,显示我现在已经能够编程的波函数,在我的LED立方体上看起来很好。

Russell

ps非常感谢大家在这里的帮助-它给了我一些寻找的途径,让我彻底放弃了-在此之前,我对endianes当然不太了解,所以了解了这一点,以及一些系统化的方法来实现强大的调试方法。

在中断例程中尝试访问数组时遇到问题。

下面是来自is例程内部的一段代码。

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位)。

这不起作用,我的颜色输出到我的LED表现不正确。

然而,如果我按如下方式更改代码,那么例程将工作

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之后缺少的(是打字错误。

在没有调试器的情况下,所指出的研究技术是:

  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. 恢复到原始程序并重新测试。收集结果并与基本情况进行比较。

确信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;
   }

最新更新