|
|
View previous topic :: View next topic |
Author |
Message |
RatFink
Joined: 01 May 2004 Posts: 49
|
OK, this is big, but I really need some help. |
Posted: Sat May 22, 2004 3:43 pm |
|
|
I think it's just my formating.
I have basically 4 processes, all dependant upon which button I push (Warm, Preheat, Plastic, and Metal). so far everything works just as it should except one thing, it keeps trying to print all the info from each process at once. after I push one button, it should just stay in that loop, but it keeps going to other loops and printing that info also and probably trying to do that process.
I know this is a big favor, but can somebody look at this and see what I have wrong? each process is commented for begining and end.
Code: | void main(void)
{
int16 HEAT; /* create HEAT */
int COUNT; /* create TIMER */
/* Set up A/D */
byte start;
int_count=INTS_PER_SECOND;
set_rtcc(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
seconds = 0;
lcd_init(); /* Initialize the LCD */
ADCON0 = 0x69; /* Fosc/8, A/D enabled */
OPTION = 0x07; /* TMR0 prescaller, 1:256, PORTB pullups */
ADCON1 = 0x0E; /* Left justify, 1 analog channel, VDD and Vss references */
TRISB = 0x0F; /* PORTD Inputs and 0utputs */
PORTB = 0x0F; /*Sets up PORTD*/
TRISE = 0x01;
do
{;}
while (PB_Warm&&PB_Preheat&&PB_Plastic&&PB_Metal == 1);
BACK:
/* start warm process */
if (PB_Warm == 0)
{
Bake = 1;
Vent = 0;
COUNT = 0;
lcd_gotoxy(0,1);
printf(lcd_putc, "Warming.");
}
/* Temp Function */
GO = 1; /* Start A/D conversion */
do
{;}
while (ADIF == 0 ); /* Wait for conversion to complete */
ADIF = 0;
Go =0;
HEAT = make16(ADRESH, ADRESL);
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
/* end warm process */
/* start preheat process */
else if (PB_Preheat == 0)
{
Bake = 1;
Vent = 0;
COUNT = 0;
lcd_gotoxy(0,1);
printf(lcd_putc, "Pre-Heat");
}
/* Temp Function */
GO = 1; /* Start A/D conversion */
do
{;}
while (ADIF == 0 ); /* Wait for conversion to complete */
ADIF = 0;
Go =0;
HEAT = make16(ADRESH, ADRESL);
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
/* end preheat process */
/* start plastic process */
else if (PB_Plastic == 0)
{
Bake = 1;
Vent = 0;
COUNT = 1;
}
/* Temp Function */
GO = 1; /* Start A/D conversion */
do
{;}
while (ADIF == 0 ); /* Wait for conversion to complete */
ADIF = 0;
Go =0;
HEAT = make16(ADRESH, ADRESL); /* Combine ADRESH and ADRESL into one 16 bit value */
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
if (COUNT == 1);
{
int TIMER = 2;
lcd_gotoxy(0,1);
lcd_putc("PLSTC");
if (TIMER > 0)
{
lcd_gotoxy(6,1);
printf(lcd_putc, "%d", TIMER);
if(seconds == 60)
{
--TIMER;
seconds = 0;
}
}
if (TIMER == 0)
{
Bake = 0;
Vent = 1;
COUNT = 0;
lcd_gotoxy(0,1);
lcd_putc("VENTING.");
}
}
/* end plastic process */
/* start metal process */
else if (PB_Metal == 0)
{
Bake = 1;
Vent = 0;
COUNT = 1;
}
/* Temp Function */
GO = 1; /* Start A/D conversion */
do
{;}
while (ADIF == 0 ); /* Wait for conversion to complete */
ADIF = 0;
Go =0;
HEAT = make16(ADRESH, ADRESL); /* Combine ADRESH and ADRESL into one 16 bit value */
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
if (COUNT == 1);
{
int TIMER = 2;
lcd_gotoxy(0,1);
lcd_putc("METAL");
if (TIMER > 0)
{
lcd_gotoxy(6,1);
printf(lcd_putc, "%d", TIMER);
if(seconds == 60)
{
--TIMER;
seconds = 0;
}
}
if (TIMER == 0)
{
Bake = 0;
Vent = 1;
COUNT = 0;
lcd_gotoxy(0,1);
lcd_putc("VENTING.");
}
}
/* END METAL process */
|
|
|
|
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Sat May 22, 2004 4:05 pm |
|
|
To simplify your code change
Code: |
GO = 1; /* Start A/D conversion */
do
{;}
while (ADIF == 0 ); /* Wait for conversion to complete */
ADIF = 0;
Go =0;
|
to
Code: |
GO = 1; /* Start A/D conversion */
while (GO); /* Wait for conversion to complete */
|
The do syntax confuses me and may also confuse the compiler. The Go bit is cleared on the completion of a reading by the hardware. You don't need to clear it manualy.
These lines
Code: | do
{;}
while (PB_Warm&&PB_Preheat&&PB_Plastic&&PB_Metal == 1);
|
are just going enter a closed loop if all of the variables are none zero. If you have those variable mapped to pins it will wait for at lease one pin to be zero and then continue. |
|
|
RatFink
Joined: 01 May 2004 Posts: 49
|
|
Posted: Sat May 22, 2004 4:10 pm |
|
|
OOH simplifying is good, I will try that. Should I completely replace the part you quoted with the stuff you wrote?
And yes, as long as all this pins are high (Not pushed) it should do nothing.
what I want it to do is wait, then once a button is pushed, it should do the action associated with that button, but for some reason it is exiting that loop and trying to do the other processes also. |
|
|
RatFink
Joined: 01 May 2004 Posts: 49
|
|
Posted: Sat May 22, 2004 5:44 pm |
|
|
Thanks Neutone, that did simplify the code and it still works. I'm slowly figuring this out and I think I know what is wrong, just a few more things to try. |
|
|
RatFink
Joined: 01 May 2004 Posts: 49
|
|
Posted: Sun May 23, 2004 12:07 am |
|
|
Nope, It's not working, grrrrrrr. |
|
|
RatFink
Joined: 01 May 2004 Posts: 49
|
|
Posted: Sun May 23, 2004 1:04 am |
|
|
Got it!
I sure wish I could figure out how to write functions outside of main and call them from in main, this might have been easier.
Code: | void main(void)
{
int16 HEAT; /* create HEAT */
int COUNT; /* create COUNT */
int TIMER;
/* Set up A/D */
byte start;
int_count=INTS_PER_SECOND;
set_rtcc(0);
setup_counters( RTCC_INTERNAL, RTCC_DIV_256);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
seconds = 0;
lcd_init(); /* Initialize the LCD */
ADCON0 = 0x69; /* Fosc/8, A/D enabled */
OPTION = 0x07; /* TMR0 prescaller, 1:256, PORTB pullups */
ADCON1 = 0x0E; /* Left justify, 1 analog channel, VDD and Vss references */
TRISB = 0x0F; /* PORTD Inputs and 0utputs */
PORTB = 0x0F; /*Sets up PORTD*/
TRISE = 0x01;
do
{;}
while (PB_Warm&&PB_Preheat&&PB_Plastic&&PB_Metal == 1);
/* start warm process */
if (PB_Warm == 0)
{
{
Bake = 1;
Vent = 0;
}
while (TRUE)
{
lcd_gotoxy(0,1);
printf(lcd_putc, "Warming.");
/* Temp Function */
GO = 1; /* Start A/D conversion */
while (GO); /* Wait for conversion to complete */
HEAT = make16(ADRESH, ADRESL);
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
}
}
/* end warm process */
/* start preheat process */
if (PB_Preheat == 0)
{
{
Bake = 1;
Vent = 0;
}
while (TRUE)
{
lcd_gotoxy(0,1);
printf(lcd_putc, "Pre-Heat");
/* Temp Function */
GO = 1; /* Start A/D conversion */
while (GO); /* Wait for conversion to complete */
HEAT = make16(ADRESH, ADRESL);
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
}
}
/* end preheat process */
/* start plastic process */
if (PB_Plastic == 0)
{
{
Bake = 1;
Vent = 0;
Timer = 1;
lcd_gotoxy(0,1);
lcd_putc("PLSTC");
}
while (TRUE)
{
/* Temp Function */
GO = 1; /* Start A/D conversion */
while (GO); /* Wait for conversion to complete */
HEAT = make16(ADRESH, ADRESL); /* Combine ADRESH and ADRESL into one 16 bit value */
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
/* Timer */
if (TIMER > 0)
{
lcd_gotoxy(6,1);
printf(lcd_putc, "%d", TIMER);
if(seconds == 60)
{
--TIMER;
seconds = 0;
}
}
if (TIMER == 0)
{
Bake = 0;
Vent = 1;
lcd_gotoxy(0,1);
lcd_putc("VENTING.");
}
}
}
/* end plastic process */
/* start metal process */
if (PB_Metal == 0)
{
{
Bake = 1;
Vent = 0;
Timer =2;
lcd_gotoxy(0,1);
lcd_putc("METAL");
}
while (TRUE)
{
/* Temp Function */
GO = 1; /* Start A/D conversion */
while (GO); /* Wait for conversion to complete */
HEAT = make16(ADRESH, ADRESL); /* Combine ADRESH and ADRESL into one 16 bit value */
HEAT = HEAT*(5.0/65535)*100; /* Load HEAT with A/D value */
lcd_gotoxy(0,2);
printf(lcd_putc, "TEMP %lu", HEAT);
/* Timer */
if (TIMER > 0)
{
lcd_gotoxy(6,1);
printf(lcd_putc, "%d", TIMER);
if(seconds == 60)
{
--TIMER;
seconds = 0;
}
}
if (TIMER == 0)
{
Bake = 0;
Vent = 1;
COUNT = 0;
lcd_gotoxy(0,1);
lcd_putc("VENTING.");
}
}
}
/* END METAL process */
} |
It's ugly, but it's mine and it works.
I'll take any tips though on how to clean it up, simplify, or make it more effecient. |
|
|
Karthick Guest
|
Rescue 911 |
Posted: Sun May 23, 2004 10:13 am |
|
|
Try using function, to simplify your code!!
Try using the interrupts or timer to check the stat of the input... this will aid to simplify your code and effective. In teh event of all buttons are pressed your code will fail. anyways try timer int or RB int |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Sun May 23, 2004 11:09 am |
|
|
RatFink wrote: | Got it! [img]
I sure wish I could figure out how to write functions outside of main and call them from in main, this might have been easier.
|
Simple example:
Code: |
#include <16F877A.h>
#device *=16
#device adc=10
#use delay(clock=20000000,RESTART_WDT)
#fuses WDT,HS, PUT, NOPROTECT, NODEBUG, BROWNOUT, NOLVP, NOCPD, NOWRT
#use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8,restart_wdt)
// function prototypes
void Init_PIC(void);
void MyFunction(int8 i);
void DisplayADC(void);
// all lines above here could be put into header file, "crapola.h" for example
// then replaced in the source file by a single line #include "crapola.h"
void main(void)
{
int8 i;
Init_PIC();
i=0;
while(1)
{
printf("\r\nHello world!");
delay_ms(1000);
MyFunction(i++);
delay_ms(1000);
DisplayADC();
delay_ms(1000);
}
}
// Initialize the PIC
void Init_PIC(void)
{
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_counters(RTCC_INTERNAL,WDT_2304MS);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
}
// Do something in a function outside of main()
void MyFunction(int8 i)
{
printf("\r\ni = %d", i);
}
// display readings from first 4 adc channels
void DisplayADC(void)
{
int8 i;
unsigned int16 value;
for(i=1;i<=4;i++)
{
set_adc_channel(i);
delay_us(100); // set channel settle
value = read_adc();
printf("\tADC %d = %ld", i, value);
}
} |
I just slapped this together and haven't tested it on hardware but it does compile clean.
I suggest you get a copy of K & R's "C Programming Lanugage", 2nd edition and read it. It is a bit dated but you will learn LOTS from that book. Plus you won't break your arms lifting it like some C lanugage books, it is only about 240 pages... _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
RatFink
Joined: 01 May 2004 Posts: 49
|
|
Posted: Sun May 23, 2004 11:19 am |
|
|
rwyoung,
I will check that out. I did try to buy that book yesterday but Barnes and Noble didn't have it so I bought the O'Reilly book, it didn't help much towards the functions issue, it just left me confused. |
|
|
rwyoung
Joined: 12 Nov 2003 Posts: 563 Location: Lawrence, KS USA
|
|
Posted: Sun May 23, 2004 1:27 pm |
|
|
C compilers require prior knowledge of the function before it can be called. There are two ways to do this:
1) Write your code so that the functions appear in calling order top-to-bottom in your .c file. A pain in the [spam] to do and not good practice.
2) Use Header files and put fuction prototypes in the header file. A function prototype gives the function type (eg void, int8, etc) the exact function name and the argument list types. Then in your .c module you must use exactly that same pattern.
example:
Code: |
int8 DoSomething(int8 a, int8 b); // this is the prototype
|
That line can be in your header file and #included at the top of the .c file where the function lives and works. In the case of the CCS compiler, those are the SAME .c file because it doesn't allow multiple .C files in a project (there are ways around this but that is another story).
Then somewhere down in your .c file is
Code: |
// this is the same as prototype but without the trailing semicolon
int8 DoSomething(int8 a, int8 b)
{
int8 retval;
retval = a + b;
return(retval);
}
|
A pointless function but you see what is happening. I have written a function to do something with two 8-bit integer variables "a" and "b" and return to me the result of that something. If I didn't need to get a result back I'd make the function a "void" function which some people would call a subroutine. (Side note, a subroutine typically does NOT return a result while a function does. There are exceptions to this rule when you start fooling around with global data and pointers. But we are keeping it simple here.)
The CCS compiler allows you to use library functions as supplied from CCS, for example the function "read_adc()" is a library function. This is a special case for the CCS compiler where you are not #including a header file that gives the function prototype. CCS has set up their library functions to act as extensions to the C language. So in this case you don't need to provide a prototype for the same reason you aren't providing a prototype for "for" or "if".
C compilers are not mind-readers so if you make your own functions you must provide a function prototype. This lets the compiler check the calling parameters and return types for errors during compile. _________________ Rob Young
The Screw-Up Fairy may just visit you but he has crashed on my couch for the last month! |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|