Continue to Site

# Help with C program, 16F877A

Status
Not open for further replies.

#### Marcoscr

##### Newbie level 4
16f877a sample c programs

Hello!

I am new at this forum,
I am starting in PIC programming, I have bought a PIC16F877A, and I am having problems with my first attempt to program this PIC, now I really don't know what else to do, I hope someone can guide me through this.

What I am trying to do is to control 2 DC motor by sensing a photoresistor, I used OPAMP's to generate a high signal by comparing to a reference voltage with the photoresistor's voltage.

Inputs=
A0: sensor1
A1:sensor2
A2:sensor3
A3:sensor4
outputs=
B0:motor1
B1:motor1(reverse); I used a H bridge for now.
B2:motor2

here is my code:

#include <16F877A.h>
#use delay(clock=4000000)
fuses NOWDT
#use standard_io(A)
#use standard_io(B)

void main() {

inicio_rutina:
OUTPUT_B(0x00);

inicio:

if (input(pin_A0))
{
goto avance;
}
else
goto inicio;

avance:
{
delay_ms(5000);
do {
output_B(0b00000001);
}
while (!(input(pin_A1))||(!(input(pin_A3))));
}
{
if (input(pin_A1))
else
goto retrocede;
}

{
while (input(pin_A1))
{
output_low(PIN_B0);
delay_ms(1000);
output_high(PIN_B1);
goto avance;
}
}

retrocede:
if (!(input(pin_A0)))
{
do {
output_high(PIN_B2);
}
while (!(input(pin_A2)));
}
else
goto retrocede;

goto inicio_rutina;

}

#### Los Frijoles

##### Full Member level 1
output_high( pin_b1 );

First of all, NEVER use gotos in C! The support may be there, but its bad practice to use it.

Now that I got that out of the way, what exactly is the problem? What compiler are you using?

I can see a few case issues: your PIN_* references look like they should always be capitalized so you should make sure that they are.

If you are having trouble making the motor go, make sure that you are using MOSFETs in your h-bridge, not transistors. Transistors are current controlled devices rather than voltage controlled and they might be trying to draw current from the microcontroller that isn't there. Using MOSFETs or one of those monolithic motor driver ICs will fix this issue.

#### Marcoscr

##### Newbie level 4
output_b(); ccs

Los Frijoles said:
First of all, NEVER use gotos in C! The support may be there, but its bad practice to use it.

Now that I got that out of the way, what exactly is the problem? What compiler are you using?

I can see a few case issues: your PIN_* references look like they should always be capitalized so you should make sure that they are.

If you are having trouble making the motor go, make sure that you are using MOSFETs in your h-bridge, not transistors. Transistors are current controlled devices rather than voltage controlled and they might be trying to draw current from the microcontroller that isn't there. Using MOSFETs or one of those monolithic motor driver ICs will fix this issue.

Sorry, I didn't gave enough information...

I am using CCS compiler (PIC C compiler).
The problem is that the program is getting in a loop, maybe because of those "gotos", so, I have not tested the hole circuit with my h-bridge, but thanks for the advise!

I am using Proteus to simulate, but is not working...

Without using gotos, what do you recommend in this case?

Thanks for the replay!

#### Los Frijoles

##### Full Member level 1
I was about to re-write your code to work without gotos, but then I saw something interesting:
Code:
llenado:
{
while (input(pin_A1))
{
output_low(PIN_B0);
delay_ms(1000);
output_high(PIN_B1);
goto avance;
}
}
It would appear that this code will bring B0 low, wait a second, bring it high, and then jump to avance without checking to see if A1 is still high. Is this what you intended to happen? I could easily see this causing your problems.

EDIT: Here is an example of what your code could look like without gotos. I think it is much easier to read:
Code:
#include <16F877A.h>
#use delay(clock=4000000)
fuses NOWDT
#use standard_io(A)
#use standard_io(B)

void retrocede(void);

void main()
{
OUTPUT_B(0);

while(!input(pin_A0)); //wait until A0 goes high
while(1)
{
//avance:
delay_ms(5000);
do {
output_B(0b00000001);
}
while (!(input(pin_A1))||(!(input(pin_A3))));
if (input(pin_A1))
{
}
else
{
retrocede();
}
}
}

{
while(input(pin_A1))
{
output_low(PIN_B0);
delay_ms(1000);
output_high(PIN_B1);
delay_ms(1000);
}
}

void retrocede(void)
{
while(input(pin_A0)); //wait for A0 to go low
do
{
output_high(PIN_B2);
} while (!(input(pin_A2)))

while(!input(pin_A0)); //wait until A0 goes high
}
I have never used CCS so I don't know if this is correct from a CCS standpoint, but the code should compiler under ANSI C.

### Marcoscr

Points: 2

#### Marcoscr

##### Newbie level 4
In that part it turn port B off, wait, and the turn port b1, which is the other motor( I think I spelled it wrong in my first post), when it goes back to "avance" the very first line is another delay, and then turn off the 2nd motor and turn on the 1rst and keep it like this until A1 or A3 is high.

The problem seems to happen from the beginning of the program, It doesn't surprise me that you will find a thousand or more mistake, I am just learning... I thought it would be easier!

Edit: Thanks, I will give it a try!
by the way... which compiler do you use?

Thanks!

#### daviddlc

##### Full Member level 5
Marco in my opinion you are on the correct path, the best way to learn is to do hands on projects.