5
\$\begingroup\$

I have been trying to run the following code:

void reset();

int board[8][8];
int i,switcher,j,k;

void main() {
    TRISB = 0X00;
    TRISD = 0X00;
    TRISC = 0X00;
    reset();
    ADCON1 = 0X06;
    TRISA =0X11;
    while(1)
    {
        for( i=0;i<16;i++)
        {
            switcher = i;
            PORTB.F0  = switcher%2;
            switcher /= 2;
            PORTB.F1 = switcher%2;
            switcher /= 2;
            PORTB.F2 = switcher%2;
            switcher /= 2;
            PORTB.F3 = switcher%2 ;
            if (!PORTA.F0 == board[i/8][i%8])
                break;
            delay_ms(1000);
       }
       switcher = i;
       PORTC.F0   =  switcher%2;
       switcher /= 2;
       PORTC.F1 = switcher%2;
       switcher /= 2;
       PORTC.F2 = switcher%2;
       switcher /= 2;
       PORTC.F3 = switcher%2 ;
       switcher /= 2;
       PORTC.F4 = switcher%2;
       switcher /= 2;
       PORTC.F5 = switcher%2 ;
       break;
   }
}

void reset()
{
    PORTB = 0;
    PORTD = 0;
    PORTC= 0;
}

On running this code, it's showing

"Not enough RAM" error.

However on running this code :

void reset();

int board[80][80];

void main() {
    TRISB = 0X00;
    TRISD = 0X00;
    TRISC = 0X00;
    reset();
    ADCON1 = 0X06;
    TRISA =0X11;
}

void reset()
{
    PORTB = 0;
    PORTD = 0;
    PORTC= 0;
}

It runs successfully with no errors (Note that I am creating a multidimensional array of 80x80 whereas for the previous one it's only 8x8). Can someone help me in identifying the cause for the problem? And if possible then also the proper solution for the problem ?

\$\endgroup\$
  • 5
    \$\begingroup\$ Your array presumably uses more memory than the chip has. In the second case, you never actually use it, so it is dropped by the compiler and there is no issue. \$\endgroup\$ – Chris Stratton Sep 9 at 15:01
  • 2
    \$\begingroup\$ You have probably chosen the wrong part for a task approached in this way, but you should also be using a bitmap not a full int (which is likely 2 or even 4 bytes) to store what appears to be a binary value. \$\endgroup\$ – Chris Stratton Sep 9 at 15:03
  • 1
    \$\begingroup\$ I have tried using uint8_t for declaring variables instead of int , which i assume should only take around 100 bytes for the program . But still it is showing the same error. \$\endgroup\$ – ferty567 Sep 9 at 15:23
  • 2
    \$\begingroup\$ That's still using 8 bits to store only one. And there may be other reservations taking memory beyond just your array. \$\endgroup\$ – Chris Stratton Sep 9 at 15:33
  • \$\begingroup\$ Ok Chris i will try. Thank you for your reply. \$\endgroup\$ – ferty567 Sep 9 at 15:35
13
\$\begingroup\$

The PIC16f877a only has 368 bytes of memory, meaning that the 8x8 array is already in danger of exhausting available memory (either 128 or 256 bytes depending on sizeof(int)) given a requirement for other structures (other symbols, stack, etc).

However, in the second program, your compiler recognizes that you do not access the 80x80 array in any way, and thus optimizes it out. As a result, the linker doesn't need to find space for a variable of size 80*80*sizeof(int) bytes and the program is successfully compiled and linked.

Presumably, you are only using each element of the array for a single boolean value--in that case you can reduce your space requirements to 64 bytes of space by packing the data more efficiently. This answer describes one way to do this, where bitwise operations are used to index into an array of uint8_t values. Alternatively, you could try using your existing technique (2D integer array) with a uint8_t[8][8] to avoid making larger code changes, but this remains wasteful of memory (8x waste).

\$\endgroup\$
  • \$\begingroup\$ Thanks a lot for your quick reply! Can you please recommend a good micro-controller having a decent RAM ? \$\endgroup\$ – ferty567 Sep 9 at 15:05
  • \$\begingroup\$ @ferty567 I'd start by seeing if you can make do with what you have given the advice and link at the end; past that I don't really have a clear favorite (and product recommendations are a bit off-topic for this site) but I've been using the atmega328p as a generic microcontroller for small projects where I don't have a specific requirement that it can't handle. It's available in a DIP package and has 2 KB of RAM; I'm certain that if you needed even more you could shop around for a specific uC with a suitable amount. \$\endgroup\$ – ζ-- Sep 9 at 15:07
  • \$\begingroup\$ The reason I used a PIC16F577a because it is having 40 pins . Whereas Atmega328p is only having 28 pins . Can you please suggest me a micro-controller having pins comparable to 40 or a way to increase the number of operable pins in Atmega328p ? \$\endgroup\$ – ferty567 Sep 9 at 15:16
  • 1
    \$\begingroup\$ @ferty567 Unfortunately high pin counts are often incompatible with DIP packages due to cost/market reasons--almost all uCs with 1K or RAM and 40 I/Os are SMT nowadays. If you really need to use DIP packages and can handle the higher latency you could consider an I/O expander such as one or more MCP23017/MCP23s17 units, which provide 16 I/Os per chip. You will need to use SPI or I2C in this case. \$\endgroup\$ – ζ-- Sep 9 at 15:23
  • 2
    \$\begingroup\$ Thanks for your replies . Hope you keep helping like this. :) \$\endgroup\$ – ferty567 Sep 9 at 15:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.