Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

programming with pic16f887 not going good........

Status
Not open for further replies.

0144224

Newbie level 4
Joined
Oct 16, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,359
Just a quick overview. I'm about 3 weeks into my C program at School and we're working with the pic16f887. I've been working on this lab for 2 days and its driving my crazy, I'm really stuck now! It's so hard to explain here in detail where I'm going wrong because I don't really know myself. I will post my code below and if someone can point me in the right direction that would be great. All I'm trying to do is get a voltage reading from my pot if the voltage is between certain points. If it is bewteen the voltage reference points I set then the LED indicators and or buzzers will sound. I have choosen RB3,RB4 as the outputs to my leds and AN13 as my analog input pin

#include <htc.h>
__CONFIG(LVPDIS &BORDIS & INTCLK & WDTDIS &PWRTEN);

unsigned char Lights[]={0xff};
static unsigned int ADReading = 0;\
float value = 0;
void Initialize();
void GetAnalogVoltage();

main()
{
Initialize();
for(;;) // a for statement that will go on forever
GetAnalogVoltage();

}


void Initialize()
{
OSCCON = 0x7E; // Sets up internal oscillator for 8 MHz.
PORTB =0; // sets porta to 0
TRISB4 = 0; // Selects the output pin.
TRISB3 = 0,
ANS13 = 1; // pin is assigned as an analog input
TRISB = 0; // Trisb is output to light led's
ADCON0 = 10110000; // Selected the input and frequency of oscilation 8mghs/32
ADCON1 = 10000000; // Sets voltage reference A/D conversion results right justified, vdd +, vdd -



}

void GetAnalogVoltage() // Data type, all of the below processes the conversion
{
char i;
ADON = 1; //Analog to Digital Clock is enabled
for(i = 0;i<6;i++); // loop for delay. Waiting time for acquisition
GODONE = 1; // Anolog to Digital conversion in progress, by setting this bit to 1 it starts the conversion cycle
while(GODONE); // Puts the results of the conversion cycle in a while loop. when low the results will go to ADreading
ADReading = ADRESH *256 + ADRESL; // multiplies hi value by 256 and adds low value giving us a 10bit value
value =(5.0*(ADReading/1023.0));

PORTB=0xff;

if(value >=1&&value <=4)
{
TRISB3 =1;

}
else(value <=1&&value >=4);
{
TRISB4 =1;

}
}
 

john blue

Advanced Member level 3
Joined
Jun 7, 2007
Messages
821
Helped
213
Reputation
430
Reaction score
204
Trophy points
1,323
Activity points
4,749
you didn't include your PIC header files... =)

---------- Post added at 02:15 ---------- Previous post was at 02:13 ----------

use #include < pic.h> to include all PIC eader ~~
 

betwixt

Super Moderator
Staff member
Joined
Jul 4, 2009
Messages
14,931
Helped
4,874
Reputation
9,766
Reaction score
4,662
Trophy points
1,393
Location
Aberdyfi, West Wales, UK
Activity points
127,018
Also make better use of '(' and ')' to make your comparisons less ambiguous. For example, change "if(value >=1&&value <=4)" to "if((value >= 1) && (value <= 4))".
I'm not sure the "static" declaration for ADReading is actually doing anything.
You should also consider changing the range calculation to improve accuracy. At the moment you take a value between 0 and 1023 and divide it by 1023 so the result will always be less than 1. If you change the calculation so it multiplies by 5 first, then divides by 1023 you will probably get better accuracy. It might also be necessary to use add a "(float)" cast in the calculation, I'm not sure how HTC deals with type promotions.

You also never turn the buzzer off !

Brian.
 

0144224

Newbie level 4
Joined
Oct 16, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,359
Great thanks for the reply and tips. As I said before I've only been programming with C for just over 3 weeks so its slow going right now!
 

0144224

Newbie level 4
Joined
Oct 16, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,359
Well I've updated my program a bit but I still can't get it to work. I have checked the voltages at ANS13 as the pot is changed and they're changing as expected but something in my program must not be working correctly. Something tells me maybe my "if" statements are wrong, I'm really a bit lost right now. I've checked my circuit wiring and I'm 100% sure everything is connected correctly.



/* This c program will take a voltage reading from a pot. If the voltage is between 1 and 4 volts the program will light a green led.
/if voltage is below 1 volt or above 4 it will light the red led and sound the alarm */


#include <pic.h>
#include <htc.h>
__CONFIG(LVPDIS &BORDIS & INTCLK & WDTDIS &PWRTEN);

unsigned char Lights[]={0xff};
static unsigned int ADReading = 0;\
float value = 0;
void Initialize();
void GetAnalogVoltage();

main()
{
Initialize();
for(;;) // a for statement that will go on forever
GetAnalogVoltage();

}


void Initialize()
{
OSCCON = 0x7E; // Sets up internal oscillator for 8 MHz.
TRISB5 = 1; // Selects the INPUT pin.
ANS13 = 1; // pin is assigned as an analog input
ADCON0 = 11010000; // Analog channel pins for ans13 selected
ADCON1 = 10000000; // Sets voltage reference A/D conversion results right justified, Voltage reference bits VCFG1 VSS set to 0, VCFG0 VDD Set to 0,



}

void GetAnalogVoltage() // Data type, all of the below processes the conversion
{
char i;
ADON = 1; //Analog to Digital Clock is enabled
for(i = 0;i<6;i++); // loop for delay. Waiting time for acquisition
GODONE = 1; // Anolog to Digital conversion in progress, by setting this bit to 1 it starts the conversion cycle
while(GODONE); // Puts the results of the conversion cycle in a while loop. when low the results will go to ADreading
ADReading = (ADRESH *256) + ADRESL; // multiplies hi value (ADRESH) by 256 and adds the low value (ADRESL) giving us a 10bit value
value =(5.0*(ADReading/1023.0)); // Range calculation, Multiply the Value in ADReading by 5 then Divides the result by 1023

//PORTB=0xff;

if(value>=1&&value<=4) // If voltage value is above 1v and below 4v then Green LED (RB4) will light up
{
RB3 = 1;
RB4 = 0;


}
if(value<=1&&value>=4); // If voltage value is below 1v and above 4v then Red LED (RB3) will light up
{
RB4 = 1;
RB3 = 0;


}
}
 
Last edited:

Buriedcode

Full Member level 6
Joined
May 6, 2004
Messages
357
Helped
43
Reputation
86
Reaction score
7
Trophy points
1,298
Location
London
Activity points
8,887
First of all I would strip the code back to basics. Make sure you are reading your ADC correctly. This can be done simply with 8 LED's connected to a port (port D?), just use your ADC read routine, and copy the ADRESH to the port, you'll soon know if its working or not. Break your code down into modules, confirming each 'module' is working correctly before attempting to put them all together - it may seem tedious but it's a methodical process that you just have to slog through. No confusion, just something to do for 20 minutes with a cup of coffee :)

I have done the above for years, and I rarely need an in-circuit-debugger. Simply adding very small routines to light an LED if something happens (no comparisons, just say, lighting an LED when inside a loop, another LED in another loop etc..). You could also add a button as a breakpoint, so the code stops at a certain point, until you press the button, when it will carry on.

Re-read the post by Betwixt, he's made some excellent points that I was going to make. In your second lot of code, you have two IF statements that are essentially opposite. No need to make the second comparison, just use 'else'. Example:

if ((value>=1) && (value<=4)) // If voltage value is between 1v and 4v then Green LED (RB4) will light up
{
RB3 = 1;
RB4 = 0;
}
else; // the voltage must be outside of above range.
{
RB4 = 1;
RB3 = 0;
}

You don't 'have' to use the ADC. I believe the 16F887 has two comparators which are ideal for windowing, but only one voltage reference module, so you would need to set the ranges externally with resistors. Not as cool as an ADC, but it'll work.
 
Last edited:

0144224

Newbie level 4
Joined
Oct 16, 2010
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,359
You guys are great! I really appreciate the information you provide.

Thanks again!
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Top