0
\$\begingroup\$

I'm having some problem with my code and I can't get my two loops working properly. I'm new to C programming so I might have got the basic loop concepts wrong. I've got 10 LED lights connected to my different ports on my microchip which are rotating in order from the first to last, and then back to the first again. The issue I'm facing is that I'm trying to get one of the buttons on the microchip to work as a start for the loop, but my code won't work. If you could take a look at this I'd greatly appreciate it.

void delay(int d);

int main(void)
{


TRISCbits.TRISC3 = 0;
TRISCbits.TRISC4 = 0;
TRISCbits.TRISC5 = 0;
TRISBbits.TRISB4 = 0;
TRISAbits.TRISA9 = 0;   
TRISBbits.TRISB2 = 0;
TRISBbits.TRISB0 = 0;
TRISAbits.TRISA1 = 0;
TRISAbits.TRISA11 = 0;

while (1)
{
    if (PORTAbits.RA11 == 1) {
    PORTCbits.RC3 = 1;
    delay(500);
    PORTCbits.RC3 = 0;
    delay(500);

    PORTCbits.RC4 = 1;
    delay(500);
    PORTCbits.RC4 = 0;
    delay(500);

    PORTCbits.RC5 = 1;
    delay(500);
    PORTCbits.RC5 = 0;
    delay(500);   

    PORTBbits.RB4 = 1;
    delay(500);
    PORTBbits.RB4 = 0;
    delay(500); 

    PORTAbits.RA9 = 1;
    delay(500);
    PORTAbits.RA9 = 0;
    delay(500);

    PORTBbits.RB2 = 1;
    delay(500);
    PORTBbits.RB2 = 0;
    delay(500); 

    PORTBbits.RB0 = 1;
    delay(500);
    PORTBbits.RB0 = 0;
    delay(500); 

    PORTAbits.RA1 = 1;
    delay(500);
    PORTAbits.RA1 = 0;
    delay(500);

    PORTBbits.RB0 = 1;
    delay(500);
    PORTBbits.RB0 = 0;
    delay(500); 

    PORTBbits.RB2 = 1;
    delay(500);
    PORTBbits.RB2 = 0;
    delay(500); 

    PORTAbits.RA9 = 1;
    delay(500);
    PORTAbits.RA9 = 0;
    delay(500);

    PORTBbits.RB4 = 1;
    delay(500);
    PORTBbits.RB4 = 0;
    delay(500); 

    PORTCbits.RC5 = 1;
    delay(500);
    PORTCbits.RC5 = 0;
    delay(500);  

    PORTCbits.RC4 = 1;
    delay(500);
    PORTCbits.RC4 = 0;
    delay(500);
    }

    else {
        TRISCbits.TRISC3 = 0;
        TRISCbits.TRISC4 = 0;
        TRISCbits.TRISC5 = 0;
        TRISBbits.TRISB4 = 0;
        TRISAbits.TRISA9 = 0;
        TRISBbits.TRISB2 = 0;
        TRISBbits.TRISB0 = 0;
        TRISAbits.TRISA1 = 0;
        TRISAbits.TRISA11 = 0;
    }

}

return 1;

}

void delay(int d)
{
 int i;

while(d)
{
    i = 100;
    while (i)
    {
        i--;
    }

    d--;
}
}
\$\endgroup\$
  • 1
    \$\begingroup\$ What exactly isn't working? If you're hoping that reading RA11 will trigger some action, it'd need to be an input, you've set it as an output and don't ever set its state such that the main 'if' ever does anything. \$\endgroup\$ – Phil G Apr 18 at 13:49
  • \$\begingroup\$ @PhilG I'm sorry if I wasn't clear enough. The button is not working properly. When I start the program, the while loop runs once, and then it stops. I want the loop to start when the button is pressed down, but nothing happens to the lights when I press it down. (The button is called A11, which initially is set to 0, and then I use as a condition in the if-loop.) \$\endgroup\$ – D.Jhn Apr 18 at 13:55
  • \$\begingroup\$ In the ELSE section, shouldn't they be PORTx or LATx not TRISx? I presume you are trying to clear all the outputs when the button is released. As others have said, TRISA11 should be 1. \$\endgroup\$ – HandyHowie Apr 18 at 14:16
  • \$\begingroup\$ Which processor are you using? Are there other functions on A11 that are overriding the GPIO? \$\endgroup\$ – HandyHowie Apr 18 at 14:18
  • \$\begingroup\$ A schematic would also be useful. \$\endgroup\$ – HandyHowie Apr 18 at 14:23
1
\$\begingroup\$

You need to set TRISAbits.TRISA11 = 1; to make the input readable. As it is, you have it set as an output, so it won't ever read any change at the pin, and the code doesn't either set it to a state that will cause the main 'if' sequence to run. (edit - that's not entirely true, you can read the state the output pin is forced to, but it's clearly not acceptable to force a logic 0 output high, it'll sink a fair amount of current).

The 'else' I suspect is intended to be setting the output latches all back to zero, in which case you need to be writing "LATCbits.LATC3 = 0;" etc.

There's plenty of people that will jump on writing to "PORTCbits.RC5 = 0;" as being wrong, writes should be to the latch, and reads can be from either the latch or port, depending on whether you want to know what it is intended to be set as (to avoid the RMW issue) or what it has actually achieved (depending on the external circuit), but in the vast majority of the PIC port structures, both a PORT and LAT write set the same latch regardless.

\$\endgroup\$
  • \$\begingroup\$ Earlier today I tried setting TRISA11 = 1, which if I remember correctly, just ran the loop like normal without having to use the button. What do I need to do in order for the loop to not start until the button is pressed? \$\endgroup\$ – D.Jhn Apr 18 at 14:10
  • \$\begingroup\$ Is the input actually changing state? does the switch pull it up against a pull-down resistor? \$\endgroup\$ – Phil G Apr 18 at 14:14
  • \$\begingroup\$ I'm not sorry if I fully understand what you mean with the latter question. \$\endgroup\$ – D.Jhn Apr 18 at 14:27
  • 1
    \$\begingroup\$ When you're relying on an external stimulus to make actions happen, you need to look not only at the code that is reacting to that stimulus, but whether the pin is actually changing logic states to cause the code to execute. If you meter the voltage on pin A11, is it at the low logic level until the button is pushed? \$\endgroup\$ – Phil G Apr 18 at 14:39

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.