Continue to Site

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.

[SOLVED] PIC16F877A: Timer1 Interrupt Problem! (Maybe a different problem from the rest!)

Status
Not open for further replies.

desmond1310

Member level 1
Member level 1
Joined
Apr 5, 2010
Messages
39
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Malaysia
Activity points
1,665
To the moderator: Please don't delete my thread. I'm sorry if this is a repeat, but here's how my problem is about:

I've been trying to use Timer1 interrupt as a timer where before reaching 6 sec, it should display 'Drying in Process', and after 6 sec, it should display 'Drying is Complete!'
Problem is after i programmed my PIC with my codes below (incomplete, but they are the most key of my program), it will only display a line of blank boxes. I cross referenced with a few programs, and i get the feeling mine should be working fine, but it's not :\
Can anyone point out my mistake(s)? Sorry for a long post.

Setup Timer1 (i placed this to initialize in my main() function)
Code:
void init_timer1(void)
{
	T1CKPS1 = 1;  
	T1CKPS0 = 1;  
	T1OSCEN = 1;             //Prescaler of 1:8
	T1SYNC = 1;    
	TMR1CS = 0;    
	TMR1H = 11;             
	TMR1L = 219;		//Period of 0.1 secs

	TMR1IE = 1;         
  	PEIE = 1;          
	GIE = 1;           
	TMR1ON = 1;    
	while (1);
}

ISR
Code:
void interrupt ISR(void)
{
	if(TMR1IE && TMR1IF)
   {
      //TMR0 Overflow ISR
      varinc++;  //Increment Over Flow Counter

      if(varinc==10)
      {
		counter++;
		varinc = 0;
      }

      //Clear Flag
      TMR0IF=0;
   }
}

Application section
Code:
void sixseconds(void)
{	
	if(counter<6)
{
	lcd_clr();								 				
	lcd_goto(0) ;							
	send_string("Drying In     ");			
	lcd_goto(20);						
	send_string("Process.     ");
}
	else if (counter==6)
{
	counter = 0;
	lcd_clr() ;											
	lcd_goto(0) ;							
	send_string("Drying Is     ");			
	lcd_goto(20);							
	send_string("Complete!     ");
}
}
 

You probably don't want to turn T1OSCEN on, it is for configuring T1 to use an oscillator made from a low frequency crystal between RC0 and RC1.
There also isn't much point in checking TMR1IE is enabled in the interrupt routine. If the IE bit isn't set the interrupt will not be called anyway.
You should ensure that 'counter' is set to zero at the start.

The line of boxes indicates one of two conditions, either the voltage that sets the contrast is wrong and all the pixels are turned on by default or, more likely, the LCD has not been initialized properly. Without knowing which compiler you use, I can't tell you which command to use but look for a way to send the configuration values to the LCD module. Also make sure that after powering on and after initializing the LCD, you leave a long enough delay for the display to complete it's internal initialization process, usually this take around 100mS.

Brian.
 

@betwixt, thank you for your advice, but the result is still the same. I'm using MPLAB. I have followed them closely and here's my edited codes.

I did a little experiment; i removed the 'while(1)' loop from my init_timer1 function and i managed to get it startup, but when i press for 6 seconds option, nothing happens. everything freezes up. I had to reset my PIC to get it back to main menu. But whenever i select other timer options again (1 second, 2 seconds), it freezes up also. I have included my LCD initialization code too. Can you or anyone still spot my mistake? I have been stuck here for 2 weeks.

Initialize timer1. I placed this in my main function for initialization.
Code:
void init_timer1(void)
{	
	counter = 0;
	T1CKPS1 = 1;   // bits 5-4  Prescaler Rate Select bits
	T1CKPS0 = 1;   // bit 4
	T1OSCEN = 0;   // bit 3 Timer1 Oscillator Enable Control bit 1 = on
	T1SYNC = 1;    // bit 2 Timer1 External Clock Input Synchronization Control bit...1 = Do not synchronize external clock input
	TMR1CS = 0;    // bit 1 Timer1 Clock Source Select bit...0 = Internal clock (FOSC/4)
	TMR1H = 11;             // preset for timer1 MSB register
	TMR1L = 219;		// preset for timer1 LSB register
	TMR1IE = 1;         // enable Timer1 interrupts
  	PEIE = 1;          // bit6 Peripheral Interrupt Enable bit...1 = Enables all unmasked peripheral interrupts
	GIE = 1;           // bit7 global interrupt enable
	TMR1ON = 1;    // bit 0 enables timer
	while(1);
}

ISR
Code:
void interrupt ISR(void)
{
	if(TMR1IF)
   {
      //TMR0 Overflow ISR
      varinc++;  //Increment Over Flow Counter

      if(varinc==10)
      {
		counter++;
		varinc = 0;
      }

      //Clear Flag
      TMR0IF=0;
   }
}

Application Section
Code:
void sixtyminutes(void)
{	
	
	if(counter<6)
{
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");
}
	else if (counter==6)
{
	counter = 0;
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}

LCD Config
Code:
	//configure lcd
	send_config(0b00000001);			//clear display at lcd
	send_config(0b00000010);			//lcd return to home 
	send_config(0b00000110);			//entry mode-cursor increase 1
	send_config(0b00001100);			//display on, cursor off and cursor blink off
	send_config(0b00111000);			//function set
 

I will simulate it later for you, I have no time at the moment. One thing did occur to me though, after the first timer interrupt you do not reset the values in TMR1H and TMR1L so the next interrupt takes 65536 timer intervals to run before reaching zero again. What clock frequency are you using so I can check the timing?

Brian.
 

OH i just realized my mistake is at.. I set TMR0IF=0, instead of TMR1IF=0 :\ Sorry for the careless error. I will run it again soon. Just realized it.

I'm using 20MHz crystal.

Oh i have to reset those too? I will try that out as well! Thank you for your time betwixt! :)

---------- Post added at 10:46 ---------- Previous post was at 10:18 ----------

@betwixt, i have a question: is it really ok to set TMR1ON=1 at the start of my program? I mean i just want my timer to start running when i select my 6 seconds timer. Won't starting too early cause my counters to not add up properly?
 

It will change the timing but by how much depends on what happens in your code before the counter starts to run. If possible, turn the timer on as late as possible to minimize the error.
Well done spotting the error, I didn't see that myself!
You definitely need to reload the start values in TMR1 each time the interrupt occurs, the timer does not reload itself so after the first time it crosses zero it just assumes a start value of 1 again. I recommend loading TMR1H first as you did in the initialization so there is less chance of a further interrupt while you are still inside the interrupt routine.
I am worried your timing still is wrong though, is your routine "sixtyminutes()" counting minutes or seconds? At the moment, the interrupt rate is 10Hz and you divide it by a further 10 by counting "varinc" to get seconds. If you want to count in minutes you should change "if(varinc==10)" to "if(varinc==600)".

Brian.
 

I did the alteration earlier (with while(1) still in my timer1 initialization function), but it seems to still display a line of black boxes.

I decided to alter my codes a little bit more:

Timer1 settings
Code:
void init_timer1(void)
{
	counter = 0;
	T1CKPS1 = 1;   
	T1CKPS0 = 1;   
	T1OSCEN = 0; 
	T1SYNC = 1;    
	TMR1CS = 0;    
	TMR1H = 11;         
	TMR1L = 220;		
	TMR1IE = 1;       
  	PEIE = 1;          
	GIE = 1;          
	TMR1ON = 0;    
}


ISR
Code:
void interrupt ISR(void)
{
	if(TMR1IF==1)
   {
      //TMR1 Overflow ISR
      varinc++;  //Increment Over Flow Counter

      if(varinc==10)
      {
		counter++;
		varinc = 0;
      }

      //Clear Flag
      TMR1IF=0;
	  TMR1H=11;
	  TMR1L=220;
   }
}


Application section
Code:
void tenseconds(void)

{	
	TMR1ON=1;
	if(counter<1)
{
	lcd_clr();								 				
	lcd_goto(0) ;							
	send_string("Drying In     ");			
	lcd_goto(20);							
	send_string("Process.     ");
}
	else if(counter==1)
{
	counter = 0;
	lcd_clr() ;												
	lcd_goto(0) ;							
	send_string("Drying Is     ");			
	lcd_goto(20);							
	send_string("Complete!     ");
}
}

I removed while(1) loop from the init_timer1, and set TMR1ON=0.
In my application section, i inserted TMR1ON=1, so that the timer will only ON during my option is selected.
This configuration managed to startup, allowed me to select my timer options. Upon selection, it does display 'Drying in Process' but it NEVER jumps to 'Drying is Complete!' even after the time designated is over..

I'm starting to think that:
The TMR1IF is still not incrementing at all, right? Due to setting counter=0, and if (counter<1) {Display 'Drying in Process'} will still take place. I even conducted an experiment earlier: i took out the TMR1ON=1; from my application section, and it still displays 'Drying in Process'.

And it looks like i must have while(1); inside my timer1 initialization, right? Else it won't be constantly checking all the time, isn't it? But this will stall my startup, and display a line of black boxes. I can't figure out why is this happening. Can it be my schematic design? I'm using 3 buttons; 1 for choosing, 1 for selecting, and 1 for reset. I'm also using my PWM function, but it's only job is to initialize and do ntg at the moment.

What should I do? Is there an alternative to set an accurate time for my strings to be displayed? Is set_timer() and get_timer() a good alternative? I'm still unsure about how both of these are being applied.

To answer your question, sorry for the confusion, i purposely set it to be in seconds for the moment. i know that i have to use 600, but i want to make sure my interrupt works first before using that.
 

I don't think the software you are showing has anything to do with the black box problem. The LCD will have it's own microprocessor which needs to be configured before it will display the string you are sending it. Elsewhere in your program you must have code to perform that configuration. The black boxes are a symptom of the LCD receiving your strings but not knowing things like the font or character set to use. The normal procedure is to wait for at least 0.1 seconds after powering up, then send the initialization to the LCD and then wait another 0.1 seconds for it to get itself ready for your program.

You appear to have the interrupts configured correctly and your Interrupt routine looks good but how do you call the "tenseconds() routine?
May I suggest you try this:
1. Make a new global variable, lets call it "UpdateLCD", for example: "unsigned char UpdateLCD = 0;"
2. In the interrupt routine, just after "varinc = 0" add the line "UpdateLCD = 1;"
3. In your main program loop, add:
if(UpdateLCD == 1)
{
UpdateLCD = 0;
tenseconds();
}

Now the tenseconds() routine will only be called when counter has been incremented and there may be a new message to display. You will have to change the check for the counter value in tenseconds() as it will never be called until counter has incremented once so it's value will always be 1 or more.

Brian.
 

I call it like this:

Code:
while(1)					// loop
	{
		if(!sw1)			// if button SW1 is pressed
		{
			while(!sw1);      // wait until button is released
			j++;
			if (j > 5) j = 0;  // if mode is added more than three, set to zero
			lcd_goto(20);	// start display at 20
			send_string(time[j]);	// display string depend on mode
		}
		if (!sw2)			// if button SW2is pressed
		{
			while(!sw2);	// wait until button is released							
			switch(j)
			{
				case 0 :	tenseconds();			
							break;
				case 1 :	twentyseconds();			
							break;
				case 2 :	thirtyseconds();			
							break;
				case 3 :	fortyseconds();			
							break;
				case 4 :	fiftyseconds();			
							break;
				case 5 :	sixtyseconds();			
							break;
				default :	;
			}
		}
			
	}	
}
When sw1 is pressed and released, it will slowly display the time from 10 seconds to 20 seconds and so on. When sw2 is pressed and released, it will jump to its respective functions which i have set time.

I don't really understand how will that suggested method help.. For me, I am not sure where I can place this:
if(UpdateLCD == 1)
{
UpdateLCD = 0;
tenseconds();
}
Because I am calling tenseconds() through button inputs. Is there a faster way we can talk to each other? I have Windows Live Messenger, but I can't pm you my e-mail address. If we can contact each other faster, i hope to solve this problem sooner and not take up your free time too much :)

My LCD configuration is as below:
Code:
	//configure lcd
	send_config(0b00000001);			//clear display at lcd
	send_config(0b00000010);			//lcd return to home 
	send_config(0b00000110);			//entry mode-cursor increase 1
	send_config(0b00001100);			//display on, cursor off and cursor blink off
	send_config(0b00111000);			//function set

Frankly, i took this part from another program having the same schematic configuration as mine. I know little about how to configure LCDs. What do you think of the config above? If you may, please PM me your instant message address? If no, nevermind :)
 

I have a question, did you put a simple test character string on your LCD before making all the timing and logic routines?
 

I believe i did as i startup, first it will normally display:

Select Mode
1.Manual Mode

As I kept pressing SW1, it will navigate to:

Select Mode
2.Auto Mode

But whenever i insert the while(1) loop line in my init_timer1, it will never startup (line of black boxes). When i removed it, everything's normal, but my interrupt never works..

Why do you ask, stan4?
 

But whenever i insert the while(1) loop line in my init_timer1, it will never startup (line of black boxes). When i removed it, everything's normal, but my interrupt never works...

Wait a second, if you insert an infinite loop in a timer initialization routine, it will never execute anything else, not even the interruption because you will keep initializing it.

You should only have one, in fact, only the main execution loop as an while(1) infinite loop.
 

@stan4, you mean i shouldn't use this:

Code:
void init_timer1(void)
{
	counter = 0;
	T1CKPS1 = 1;   
	T1CKPS0 = 1;   
	T1OSCEN = 0; 
	T1SYNC = 1;    
	TMR1CS = 0;    
	TMR1H = 11;         
	TMR1L = 220;		
	TMR1IE = 1;       
  	PEIE = 1;          
	GIE = 1;          
	TMR1ON = 0;
        while(1);    <<<<<<<<<<<<<<<the infinite loop
}

I have seen this guy do it in this link: Introduction to PIC18's Timers - PIC Microcontroller Tutorial | eXtreme Electronics
Why does he include the while(1) loop inside? So the right method is to not have while(1) loop in it at all?

---------- Post added at 07:59 ---------- Previous post was at 07:58 ----------

You should only have one, in fact, only the main execution loop as an while(1) infinite loop.

can you show me an example of this if you could? thank you stan4!
 

I saw the program...

1- if you look at the program carefully, the while(1) is used only once in his program.

2- while(1); //Sit Idle Timer will do every thing! ; this means that he don't want to do anything in the main loop, if you look at the program flow, he initializes and then puts the main execution branch in an infinite loop. thus, not affecting the timer counter and and it's interruption handling routines.

In effect when you write while(1) you put a black hole in your program so nothing else will execute, not before neither after it; you could execute other code only and if only the processor is interrupted (from his endless loop) and brought to the handling routine, and then back to the loop.
 

I guess I should give a summary of what i want to do now:

I am using HI-TECH and MPLAB IDE.

Timer1 Settings. I have applied this in my main function to initialize.
Code:
void init_timer1(void)
{
	TMR1H = 11;            
	TMR1L = 220;		
	counter = 0;
	T1CKPS1 = 1;   // bits 5-4  Prescaler Rate Select bits
	T1CKPS0 = 1;   // bit 4
	T1OSCEN = 0;   // bit 3 Timer1 Oscillator Enable Control bit 1 = on
	T1SYNC = 1;    
	TMR1CS = 0;   
	TMR1IE = 1;         // enable Timer1 interrupts
  	PEIE = 1;          
	GIE = 1;           // bit7 global interrupt enable
	TMR1ON = 0;    // bit 0 enables timer
	while(1);
}

ISR
Code:
void interrupt ISR(void)
{
	if(TMR1IF)
   {
      //TMR1 Overflow ISR
      varinc++;  //Increment Over Flow Counter

      if(varinc==10)   // If 1 second is achieved,
    {
		counter++;
		varinc = 0;
    }
      //Clear Flag
          TMR1IF=0;
	  TMR1H=11;
	  TMR1L=220;
   	}
}

Application section
Code:
void tenseconds(void)
{	TMR1ON=1;
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");

	if(counter==10)
{
	counter = 0;
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}

Right now i am concentrating on just displaying my message for that designated time of 10 seconds, 20 seconds, etc.

Problem is after programming my PIC, my LCD display only a line of black boxes :\ i'm applying my circuit on a breadboard now. I have 2 PICs, 1 contains a confirm working program for troubleshooting, and another is for loading in newly altered programs. I am quite certain my circuit on breadboard is functional.. although i feel encouraged to fabricate a PCB soon to minimize error.

I did an experiment: i took out the while(1); from the timer1 settings, and everything manage to startup! I see most programs uses the while(1); in there with no problems at all, but i feel i am the only one having this problem.

What do you guys think?

---------- Post added at 08:17 ---------- Previous post was at 08:12 ----------

I saw the program...

1- if you look at the program carefully, the while(1) is used only once in his program.

2- while(1); //Sit Idle Timer will do every thing! ; this means that he don't want to do anything in the main loop, if you look at the program flow, he initializes and then puts the main execution branch in an infinite loop. thus, not affecting the timer counter and and it's interruption handling routines.

In effect when you write while(1) you put a black hole in your program so nothing else will execute, not before neither after it; you could execute other code only and if only the processor is interrupted (from his endless loop) and brought to the handling routine, and then back to the loop.

i just posted a summary of my progress.. I believe i am doing the same thing as he is, but just that my timer1 settings are in a function. What do you think is my mistake that i am overlooking?
 

I've revised your code and I don't see where in the main execution branch you call the timer initialize function.

---------- Post added at 01:23 ---------- Previous post was at 01:23 ----------

I'd like to see the whole code.
 
Stan4, thank you! I hope you can find my mistake.

Code:
#include <pic.h>
__CONFIG (0x3F32);
#define rs				RB3
#define rw				RB4
#define e				RB5

#define lcd_data		PORTD
#define sw1				RB0
#define sw2				RB1
#define sw3				RB2

#define motor_1			RC1				// 1st terminal of the motor.
#define motor_speed		CCPR2L			// The PWM value to control motor's speed.

void init_timer1(void);

void init(void);
void delay(unsigned long data);
void send_config(unsigned char data);
void send_char(unsigned char data);
void e_pulse(void);
void lcd_goto(unsigned char data);
void lcd_clr(void);
void send_string(const char *s);

void manualmode(void);
void automode(void);
void tenminutes(void);
void twentyminutes(void);
void thirtyminutes(void);
void fortyminutes(void);
void fiftyminutes(void);
void sixtyminutes(void);

unsigned long varinc;
unsigned long counter; 
unsigned char data[6] = {0};
const unsigned char manual_mode[] = {"1.Manual Mode   "};
const unsigned char auto_mode[] = {"2.Auto Mode     "};
const unsigned char *mode[2] = {&manual_mode[0],&auto_mode[0]};

const unsigned char ten[] = {"10 Minutes      "};
const unsigned char twenty[] = {"20 Minutes      "};
const unsigned char thirty[] = {"30 Minutes      "};
const unsigned char forty[] = {"40 Minutes      "};
const unsigned char fifty[] = {"50 Minutes      "};
const unsigned char sixty[] = {"60 Minutes      "};
const unsigned char *time[6] = {&ten[0], &twenty[0], &thirty[0], &forty[0], &fifty[0], &sixty[0]};

void main(void)
{
	unsigned char m = 0;
	init_timer1();
	init();								//initialize microcontroller
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Select Mode");				// send message to be displayed 
	lcd_goto(20);							// set the position of message to be displayed
	send_string(mode[m]);
	 
while(1)										// loop
	{
		if(!sw1)									// if button SW1 is pressed
		{
			while(!sw1);							// wait until button is released
			m++;
			if ( m > 1) m = 0;						// if mode is added more than three, set to zero
			lcd_goto(20);							// start display at 20
			send_string(mode[m]);					// display string depend on mode
		}
		if (!sw2)									// if button SW2is pressed
		{
			while(!sw2);							// wait until button is released
			switch(m)								// check what is the current mode, execute the mode
			{

				case 0 :	manualmode();			// mode 1 : manual mode
							break;
				case 1 :	automode();			// mode 2 : auto mode
							break;
				default :	;			
			}
		}
	}
}

//============================================================================================================//

void manualmode()
{
	unsigned char j=0;
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Select Time      ");				// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string(time[j]);

while(1)										// loop
	{
		if(!sw1)									// if button SW1 is pressed
		{
			while(!sw1);							// wait until button is released
			j++;
			if (j > 5) j = 0;						// if mode is added more than three, set to zero
			lcd_goto(20);							// start display at 20
			send_string(time[j]);					// display string depend on mode
		}
		if (!sw2)									// if button SW2is pressed
		{
			while(!sw2);							// wait until button is released							
			switch(j)
			{
				case 0 :	tenminutes();			
							break;
				case 1 :	twentyminutes();			
							break;
				case 2 :	thirtyminutes();			
							break;
				case 3 :	fortyminutes();			
							break;
				case 4 :	fiftyminutes();			
							break;
				case 5 :	sixtyminutes();			
							break;
				default :	;
			}
		}
			
	}	
}

void tenminutes(void)
{	TMR1ON=1;
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");

	if(counter==10)
{
	
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}

void twentyminutes(void)	
{	
	TMR1ON=1;
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");

	if (counter==20)
{
	
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}


void thirtyminutes(void)
{	
	TMR1ON=1;
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");
	
	if (counter==30)
{
	
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}


void fortyminutes(void)
{	
	TMR1ON=1;

	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");
	
	if (counter==40)
{
	
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}


void fiftyminutes(void)
{	
	TMR1ON=1;
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");

	if (counter==50)
{
	
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}


void sixtyminutes(void)
{	
	TMR1ON=1;
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying In     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Process.     ");

	if (counter==60)
{
	
	lcd_clr() ;								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("Drying Is     ");			// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("Complete!     ");
}
}


//===================================================================================================//	

void automode()
{
	lcd_clr();								// clear LCD screen 				
	lcd_goto(0) ;							// set the position of message to be displayed
	send_string("2.Auto Mode   ");				// send message to be displayed
	lcd_goto(20);							// set the position of message to be displayed
	send_string("OHYEAHOHYEAH");
}

void init_timer1(void)
{
	TMR1H = 11;             // preset for timer1 MSB register
	TMR1L = 220;		// preset for timer1 LSB register
	counter = 0;
	T1CKPS1 = 1;   // bits 5-4  Prescaler Rate Select bits
	T1CKPS0 = 1;   // bit 4
	T1OSCEN = 0;   // bit 3 Timer1 Oscillator Enable Control bit 1 = on
	T1SYNC = 1;    // bit 2 Timer1 External Clock Input Synchronization Control bit...1 = Do not synchronize external clock input
	TMR1CS = 0;    // bit 1 Timer1 Clock Source Select bit...0 = Internal clock (FOSC/4)
	TMR1IE = 1;         // enable Timer1 interrupts
  	PEIE = 1;          // bit6 Peripheral Interrupt Enable bit...1 = Enables all unmasked peripheral interrupts
	GIE = 1;           // bit7 global interrupt enable
	TMR1ON = 0;    // bit 0 enables timer
	while(1);
}

void interrupt ISR(void)
{
	if(TMR1IF)
   {
      varinc++;  //Increment Over Flow Counter

      if(varinc==10)
    {
		counter++;
		varinc = 0;
    }
      TMR1IF=0;
	  TMR1H=11;
	  TMR1L=220;
   	}
}

void init()
{

	// Setup PWM mode.
	CCP2CON = 0b00001100;				// Set as PWM Mode.
	T2CON = 0b00000101;					// Turn on Timer 2 with prescaler = 4.
	PR2 = 0xFF;							// Set the PWM period.
	motor_1 = 0;
	motor_speed = 0;					// No PWM Duty Cycle during startup.	
	
	//set I/O input output
	TRISB = 0b00000111;					//configure PORTB I/O direction
	TRISD = 0b00000000;					//configure PORTD I/O direction
	TRISC = 0b00000000;
	//setup ADC
	ADCON1 = 0b00000110;				//set ADx pin digital I/O
	
	//configure lcd
	send_config(0b00000001);			//clear display at lcd
	send_config(0b00000010);			//lcd return to home 
	send_config(0b00000110);			//entry mode-cursor increase 1
	send_config(0b00001100);			//display on, cursor off and cursor blink off
	send_config(0b00111000);			//function set
}


void delay(unsigned long data)
{
	for( ;data>0;data-=1);
}

void send_config(unsigned char data)
{
	rs=0;										//clear rs into config mode 
	lcd_data=data;
	delay(500);
	e_pulse();
}

void send_char(unsigned char data)
{
	rs=1;										//set rs into write mode
	lcd_data=data;						 
	delay(500);
	e_pulse();
}

void e_pulse(void)
{
	e=1;
	delay(500);
	e=0;
	delay(500);
}

void lcd_goto(unsigned char data)
{
 	if(data<16)
	{
	 	send_config(0x80+data);
	}
	else
	{
	 	data=data-20;
		send_config(0xc0+data);
	}
}

void lcd_clr(void)
{
 	send_config(0x01);
	delay(500);	
}

void send_string(const char *s)
{          
	unsigned char i=0 ;
  	while (s && *s)send_char (*s++) ;
}
 
Last edited:

don't bother about automode() at the moment, i just put it to display for fun.
sorry, i forgot to add the semicolon at the back of while(1); i was doing some experiments.

---------- Post added at 08:38 ---------- Previous post was at 08:30 ----------

also, don't bother about UpdateLCD=0, i'm not using that one either.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top