LCD affecting Timer2 Performance.......

Go To Last Post
28 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

This post is relevent to my previous post of ADC-timer delay problem.

I later realised that the problem is due to LCD.
My configuration:
ATMega8 with Internal 8Mhz osc
Timer 2 async with 32.768 Khz external crystal
16x2LCD and ADC connected.

In the code, i have marked "PROBLEMATIC area".
If i comment the code, i get 1400ms exact delay. (I have corrected the error too in ISR)
But if i write the Problematic area code, then i get 670ms delay instead of 1400ms. I have placed a endless loop in ISR, which Clears PORTC,5 to indicate the delay.
This is my code:

#include 
#include 
#include 
#include "lcd/lcd.h"

#include "calibration.h"

#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif




 //long glb_ms_counter;
 long glb_max_ms;
 long error_corrector;
 
void Init_Timer2_CTC(void);
void CheckCurrentLimit(void);
void Read_and_Print_Current(void);

ISR (TIMER2_COMP_vect, ISR_BLOCK) 
{ 
	//will be called every 1ms
	static long  glb_ms_counter;
	glb_ms_counter ++;	
	error_corrector++;
	if(error_corrector==125)
	{
		error_corrector=0;
		glb_ms_counter=glb_ms_counter+3;
	}		
	if(glb_ms_counter==glb_max_ms) 
	{
		sbi(DDRC,5);
		cbi(PORTC,5);
		while(1){}
	}		
}


void Init_Timer2_CTC(void)
{	
		sbi(ASSR,AS2); // External Crystal of 32.768KHz will be used
		TCNT2=0x00; 		 	
		OCR2=0x20;				
		//OCR2=21;
		TCCR2=0x09; // CTC + 0 presclar
		TIMSK|=0x80; // CTC interrupt
		SREG |= 0x80; //global interrupt	
		while (ASSR & ((1 << TCN2UB) | (1 << TCR2UB) | (1 << OCR2UB))); 

}


int main(void)
{

	_delay_ms(1000);	
	sbi(DDRC,5);
	sbi(PORTC,5);	
	sbi(DDRC,4);
	sbi(PORTC,4);	
	OSCCAL_Calibrate();  
	
	//glb_ms_counter=0;
	glb_max_ms=1400;
	error_corrector=0;	
	
	lcdInit();
	
	ADMUX = _BV(ADLAR) | _BV(REFS1) | _BV(REFS0) | _BV(MUX1) | _BV(MUX0); //avrfreaks		
	ADCSRA=0X86; 
	
		
	ADCSRA |= _BV(ADSC); 		
		while (ADCSRA & (1 << ADSC));	
		
	Init_Timer2_CTC();
	sbi(DDRC,4);
	cbi(PORTC,4);
	
	while(1){
	Read_and_Print_Current();
	CheckCurrentLimit();
	_delay_us(200);	
	}

	return 0;
}

void Read_and_Print_Current(void)
{
	double input_current;
	char val1,val2,val3;
	double a;
	ADCSRA |= _BV(ADSC); 	
	while (ADCSRA & (1 << ADSC)); 		
	a=ADCH;	
	input_current=(a*2.55)/255; 	
	val1=(int)(input_current * 1) + 48;
	val2=(int)(input_current * 10) % 10 + 48;
	val3=(int)(input_current * 100) %10 + 48;	
	
	//*********************
	//Problematic area starts here
	lcdGotoXY(0,0);
	lcdDataWrite(val1);
	lcdPrintData(".",1);	
	lcdDataWrite(val2);	
	lcdDataWrite(val3);	
	lcdPrintData(" ",1);
	lcdPrintData("Amp",3);
	lcdPrintData("        ",8);
	//Problematic area ends here
	//**********************
	_delay_us(500);	
}

void CheckCurrentLimit(void)
{
	
	double current;
	double input_current;
	double	backup_ISet;
	double backup_T; 	
	double Idif;
		
	ADCSRA |= _BV(ADSC); 		
	while (ADCSRA & (1 << ADSC));				 		
	current=ADCH;	
	input_current=(current*2.55)/255; 
}

////////////////LCD///////////////////////
void lcdGotoXY(u08 x, u08 y)
{
	register u08 DDRAMAddr;

	// remap lines into proper order
	switch(y)
	{
	case 0: DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
	case 1: DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
	case 2: DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
	case 3: DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
	default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
	}

	// set data address
	lcdControlWrite(1<<LCD_DDRAM | DDRAMAddr);
}


void lcdDataWrite(u08 data) 
{
// write a data byte to the display
#ifdef LCD_PORT_INTERFACE
	lcdBusyWait();							// wait until LCD not busy
	sbi(LCD_CTRL_PORT, LCD_CTRL_RS);		// set RS to "data"
	cbi(LCD_CTRL_PORT, LCD_CTRL_RW);		// set R/W to "write"
	#ifdef LCD_DATA_4BIT
		// 4 bit write
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)|0xF0);	// set data I/O lines to output (4bit)
		outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data&0xF0) );	// output data, high 4 bits
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		outb(LCD_DATA_POUT, (inb(LCD_DATA_POUT)&0x0F) | (data<<4) );	// output data, low 4 bits
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
	#else
		// 8 bit write
		sbi(LCD_CTRL_PORT, LCD_CTRL_E);	// set "E" line
		outb(LCD_DATA_DDR, 0xFF);			// set data I/O lines to output (8bit)
		outb(LCD_DATA_POUT, data);			// output data, 8bits
		LCD_DELAY;								// wait
		LCD_DELAY;								// wait
		cbi(LCD_CTRL_PORT, LCD_CTRL_E);	// clear "E" line
	#endif
	//	leave data lines in input mode so they can be most easily used for other purposes
	#ifdef LCD_DATA_4BIT
		outb(LCD_DATA_DDR, inb(LCD_DATA_DDR)&0x0F);		// set data I/O lines to input (4bit)
		outb(LCD_DATA_POUT, inb(LCD_DATA_POUT)|0xF0);	// set pull-ups to on (4bit)
	#else
		outb(LCD_DATA_DDR, 0x00);			// set data I/O lines to input (8bit)
		outb(LCD_DATA_POUT, 0xFF);			// set pull-ups to on (8bit)
	#endif
#else
	// memory bus write
	//sbi(MCUCR, SRW);			// enable RAM waitstate
	lcdBusyWait();				// wait until LCD not busy
	*((volatile unsigned char *) (LCD_DATA_ADDR)) = data;
	//cbi(MCUCR, SRW);			// disable RAM waitstate
#endif
}

void lcdPrintData(char* data, u08 nBytes)
{
	register u08 i;

	// check to make sure we have a good pointer
	if (!data) return;

	// print data
	for(i=0; iQuote:
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Have you simulated the code in AVR Studio?
You should put the "_delay_ms" calls in commentary before you start simulation
since the AVR devices are simulated far below real time.

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I dont use AVR Studio.
All readings are directly from my own development board.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Help Help Help me!!!!
My client is eating me like anything...

Timer 2 works fine seperately...
But if integrated with LCD, it fails....

Help Help Help...
abcminuser, buttload, others where you techi guys..... help me...

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yellow,

I'm not sure why you took on such a project with no prior experience. Still, good to see you're trying to correct the issue.

Your code is based on an ANCIENT version of AVRLibC. In the latest versions you don't need all that horrible CBI/SBI junk, nor the "(*((volatile unsigned char *)" casts. Porting the code will do wonders for readability, if not improve the performance. Since you're not including compat.h and since the delay routines are in the avr header folder I must assume you're running a horribly outdated version of WinAVR - that might be contributing to your problems.

I can't see how using the LCD would make the timer delay *shorter*, especially since the timer is asych driven via an external crystal. Normally such issues would lengthen the delay (possibly due to missed interrupts, etc). Perhaps the LCD routines are overwriting your global delay variables glb_max_ms or glb_ms_counter? Stack running into the globals space might be a problem source.

Declare your global variables as volatile.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

Last Edited: Mon. Jul 10, 2006 - 09:34 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I recommend you install AVR Studio:
http://www.atmel.com/dyn/products/tools_card.asp?tool_id=2725

It will enable you to simulate your code.
You can step through your code, set breakpoints, manipulate registers and variables and more.

AVR Studio is easy to handle and well ducumented.
There is even a forum for AVR Studio users at avrfreaks.net

Regards
Sebastian

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Also, the "double" type doesn't exist in GCC - it's an alias to the standard precision float variable type.

In Read_and_Print_Current(), you're typecasting a float result to an int, and then storing it into a signed char.

I'm in the process of converting your code over (I've honestly never seen so many programming styles jammed into one application) to the latest AVRGCC. I suggest you do all your programming on the latest WinAVR distribution.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

Last Edited: Mon. Jul 10, 2006 - 09:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Will volatile variables retain value throughout the program life?

I am using Programmer's Notepad 2.0.6.1
I am using avr-gcc (GCC) 3.4.5
AVRLIBC version cant be found, but i have installed it in april or may 2006.
EDIT: AVR libc version is 20051024

AVR studio fails on my machine. Right now i dont want to switch to anything new.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You should be using the latest WinAVR, even if you can't use the latest/any AVRStudio.

"volatile" just tells the compiler not to optimize variable accesses away. If the compiler sees a variable is loaded somewhere in your program and then doesn't change, it will just load the value from SRAM once and keep the value static in a local register. That's fine for normal variables but if your variable changes in an ISR, such optimizations will cause the program to fail. Using volatile forces the compiler to keep reloading the variable's value each time it is accessed.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you using a 4-bit LCD system, or 8-bit?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

8 bit

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Well bugger, I only converted the code for 4-bit. If that's a problem then just convert the 8-bit code over and replace my converted 4-bit code.

This took a lot longer than I expected. Now it's all in one style and should work with the latest WINAVR. I changed the timer delay code so that rather than counting one value up to reach another, you set an initial value and it counts downwards until it hits zero.

That'll be $98.50, plus tax :D

// Header files
#include 
#include 
#include 

#include "lcd/lcd.h"
#include "calibration.h"

// Global Variables
volatile long error_corrector;
volatile long glb_ms_counter;
 
// Function Prototypes
void Init_Timer2_CTC(void);
void CheckCurrentLimit(void);
void Read_and_Print_Current(void);

ISR(TIMER2_COMP_vect, ISR_BLOCK)
{
   // Will be called every 1ms.
   
   glb_ms_counter--;
   error_corrector++;

   if((error_corrector == 125) && (glb_msrem_counter >= 3))
   {
      error_corrector = 0;
      glb_ms_counter -= 3;
   }

   if(!(glb_msrem_counter))
   {
      DDRC  |= (1 << 5);
      PORTC &= ~(1 << 5);
      while(1) {};
   }
}


void Init_Timer2_CTC(void)
{   
	ASSR |= (1 << AS2); // External Crystal of 32.768KHz will be used
	TCNT2=0x00;
	OCR2=0x20;
	TCCR2=0x09;   // CTC + 0 presclar
	TIMSK|=0x80;  // CTC interrupt
	SREG |= 0x80; // Enable timer global interrupt
	while (ASSR & ((1 << TCN2UB) | (1 << TCR2UB) | (1 << OCR2UB))); // Wait until crystal stabalised
}


int main(void)
{
	DDRC  |= ((1 << 5) | (1 << 4));
	PORTC |= ((1 << 5) | (1 << 4));
	
	OSCCAL_Calibrate(); 

	glb_msrem_counter = 1400;
	error_corrector   = 0;
   
	lcdInit();
   
	ADMUX  = ((1 << ADLAR) | (1 << REFS1) | (1 << REFS0) | (1 << MUX1) | (1 << MUX0));
	ADCSRA = 0x06;
         
	ADCSRA |= (1 << ADSC);       
	while (ADCSRA & (1 << ADSC)) {};
	
	Init_Timer2_CTC();

	DDRC  |= (1 << 4);
	PORTC &= ~(1 << 4);

	while (1)
	{
		Read_and_Print_Current();
		CheckCurrentLimit();
		_delay_us(200);   
	}

	return 0;
}

void Read_and_Print_Current(void)
{
	float input_current;
	unsigned char val1, val2, val3;
	float a;
   
	// NOTE: This block seems to be a carbon copy of CheckCurrentLimit(void)
	ADCSRA |= (1 << ADSC);    
	while (ADCSRA & (1 << ADSC)) {};       
	a = ADCH;
	input_current = ((a * 2.55) / 255);
	// END NOTE
	
	val1 = (input_current * 1) + 48;
	val2 = (input_current * 10) % 10 + 48;
	val3 = (input_current * 100) %10 + 48;   
   
	lcdGotoXY(0,0);
	lcdDataWrite(val1);
	lcdPrintData(".",1);   
	lcdDataWrite(val2);   
	lcdDataWrite(val3);   
	lcdPrintData(" ",1);
	lcdPrintData("Amp",3);
	lcdPrintData("        ",8);

	_delay_us(500);   
}

void CheckCurrentLimit(void)
{
   float current;
   float input_current;
   float backup_ISet;
   float backup_T;    
   float Idif;
      
   ADCSRA |= (1 << ADSC);       
   while (ADCSRA & (1 << ADSC));                   
   current = ADCH;
   input_current = ((current * 2.55) / 255);
}

////////////////LCD///////////////////////
void lcdGotoXY(unsigned char x, unsigned char y)
{
   unsigned char DDRAMAddr;

   // Re-map lines into proper order
   switch(y)
   {
		case 0:  DDRAMAddr = LCD_LINE0_DDRAMADDR+x; break;
		case 1:  DDRAMAddr = LCD_LINE1_DDRAMADDR+x; break;
		case 2:  DDRAMAddr = LCD_LINE2_DDRAMADDR+x; break;
		case 3:  DDRAMAddr = LCD_LINE3_DDRAMADDR+x; break;
		default: DDRAMAddr = LCD_LINE0_DDRAMADDR+x;
   }

   // Set data address
   lcdControlWrite((1 << LCD_DDRAM) | DDRAMAddr);
}


void lcdDataWrite(unsigned char data)
{
	// Write a data byte to the display
	lcdBusyWait();                         // Wait until LCD not busy
	LCD_CTRL_PORT |= ((1 << LCD_CTRL_RS) | (1 << LCD_CTRL_RW)); // Set RS to "data" and Set R/W to "write"

	// 4 bit write
	LCD_CTRL_PORT |= (1 << LCD_CTRL_E);    // Set "E" line
	LCD_DATA_DDR  |= 0xF0;                 // Set data I/O lines to output (4bit)
	LCD_DATA_POUT  = ((LCD_DATA_POUT & 0x0F) | (data & 0xF0));  // Output data, high 4 bits
	LCD_DELAY;                             // Wait
	LCD_DELAY;                             // Wait
	LCD_CTRL_PORT &= ~(1 << LCD_CTRL_E);   // Clear "E" line
	LCD_DELAY;                             // Wait
	LCD_DELAY;                             // Wait
	LCD_CTRL_PORT |= (1 << LCD_CTRL_E);    // Set "E" line
	LCD_DATA_POUT  = ((LCD_DATA_POUT & 0x0F) | (data << 4));    // Output data, low 4 bits
	LCD_DELAY;                             // Wait
	LCD_DELAY;                             // Wait
	LCD_CTRL_PORT &= ~(1 << LCD_CTRL_E);   // Clear "E" line

	LCD_DATA_DDR  &= 0x0F;                 // Set data I/O lines to input (4bit)
	LCD_DATA_POUT |= 0xF0;                 // set pull-ups to on (4bit)
}

void lcdPrintData(char* data, unsigned char nBytes)
{
	unsigned char i;

	// Check to make sure we have a good pointer
	if (data == NULL) return;

	// Print data
	for(i = 0; i < nBytes; i++)
	  lcdDataWrite(data[i]);
}

void lcdInit()
{
   // Initialize hardware
   lcdInitHW();

   // LCD function set
   lcdControlWrite(LCD_FUNCTION_DEFAULT);

   // clear LCD
   lcdControlWrite(1 << LCD_CLR);
   _delay_ms(60);   // Wait 60ms

   // set entry mode
   lcdControlWrite((1 << LCD_ENTRY_MODE) | (1 << LCD_ENTRY_INC));

   // set display to on
   lcdControlWrite((1 << LCD_ON_CTRL) | (1 << LCD_ON_DISPLAY));

   // move cursor to home
   lcdControlWrite((1 << LCD_HOME));

   // Set data address to 0
   lcdControlWrite((1 << LCD_DDRAM));   
}

void lcdInitHW(void)
{
	// initialize I/O ports
	// if I/O interface is in use

	// initialize LCD control lines
	LCD_CTRL_PORT &= ~((1 << LCD_CTRL_RS) | (1 << LCD_CTRL_RW) | (1 << LCD_CTRL_E));

	// initialize LCD control lines to output
	LCD_CTRL_DDR |= ((1 << LCD_CTRL_RS) | (1 << LCD_CTRL_RW) | (1 << LCD_CTRL_E));

	// initialize LCD data port to input
	// initialize LCD data lines to pull-up
	LCD_DATA_DDR  &= 0x0F;   // Set data I/O lines to input (4bit)
	LCD_DATA_POUT |= 0xF0;   // set pull-ups to on (4bit)
}

void lcdControlWrite(u08 data)
{
	// write the control byte to the display controller
	lcdBusyWait();                       // Wait until LCD not busy
	LCD_CTRL_PORT &= ~((1 << LCD_CTRL_RS) | (1 << LCD_CTRL_RW)); // set RS to "control" and set R/W to "write"

	// 4 bit write
	LCD_CTRL_PORT |= (1 << LCD_CTRL_E);  // Set "E" line
	LCD_DATA_DDR  |= 0xF0;               // Set data I/O lines to output (4bit)
	LCD_DATA_POUT  = ((LCD_DATA_POUT & 0x0F) | (data & 0xF0));   // Output data, high 4 bits
	LCD_DELAY;                           // Wait
	LCD_DELAY;                           // Wait
    LCD_CTRL_PORT &= ~(1 << LCD_CTRL_E); // Clear "E" line
	LCD_DELAY;                           // Wait
	LCD_DELAY;                           // Wait
	LCD_CTRL_PORT |= (1 << LCD_CTRL_E);  // Set "E" line
	LCD_DATA_POUT  = ((LCD_DATA_POUT & 0x0F) | (data << 4));     // Output data, low 4 bits
	LCD_DELAY;                           // Wait
	LCD_DELAY;                           // Wait
	LCD_CTRL_PORT &= ~(1 << LCD_CTRL_E); // Clear "E" line

   //   leave data lines in input mode so they can be most easily used for other purposes
	LCD_DATA_DDR  &= 0x0F);              // Set data I/O lines to input (4bit)
	LCD_DATA_POUT |= 0xF0);              // Set pull-ups to on (4bit)
}

void lcdBusyWait(void)
{
	// wait until LCD busy bit goes to zero
	// do a read from control register
	LCD_CTRL_PORT &= ~(1 << LCD_CTRL_RS);  // set RS to "control"
	LCD_DATA_DDR  &= 0x0F;                 // set data I/O lines to input (4bit)
	LCD_DATA_POUT |= 0xF0;                 // set pull-ups to on (4bit)
	LCD_CTRL_PORT |= ((1 << LCD_CTRL_RW) | (1 << LCD_CTRL_E));  // set R/W to "read" and set "E" line
	LCD_DELAY;                             // Wait
   
	while(LCD_DATA_PIN & (1 << LCD_BUSY))
	{
		LCD_CTRL_PORT &= ~(1 << LCD_CTRL_E);  // clear "E" line
		LCD_DELAY;                            // Wait
		LCD_DELAY;                            // Wait
		LCD_CTRL_PORT |= (1 << LCD_CTRL_E);   // set "E" line
		LCD_DELAY;                            // Wait
		LCD_DELAY;                            // Wait
        LCD_CTRL_PORT &= ~(1 << LCD_CTRL_E);  // clear "E" line
		LCD_DELAY;                            // Wait
		LCD_DELAY;                            // Wait
		LCD_CTRL_PORT |= (1 << LCD_CTRL_E);   // set "E" line
		LCD_DELAY;                            // Wait
	}

	LCD_CTRL_PORT &= ~(1 << LCD_CTRL_E);         // clear "E" line
   //   leave data lines in input mode so they can be most easily used for other purposes
}

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Double post

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

Last Edited: Mon. Jul 10, 2006 - 10:39 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I will meet you and have party as I drop in to Australia.

LCD is blank, not displaying any thing.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That's probably a good thing. I can't say I really care for the LCD code anyway :). I'd suggest grabbing hold of a more modern LCD library and using that instead. I think there's a version of the Fleury LCD library floating around which is a heck of a lot more modern than your original cbi/sbi monstrocity :).

I'll go over the code and see if I made any transposing errors.

EDIT: No problems I can see. It's either a timing issue brought on by my code (compiling to smaller code than the original) or the 4-bit code is a problem.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser
So you say that if i change my LCD code to 4 bit and with new version of LCD library, then things will be perfect.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If you use a newer LCD library in 8-BIT mode, it should work. My code should be a direct translation of the 4-bit mode of your original code, so the fact that it is not working either means that the original code was extreamly timing-dependant or uses some sort of 4-bit specific wiring which is incompatible with your 8-bit wiring. Using a new version of a known, proven 8-bit library will keep your code neat, readable and working.

I'd suggest keeping the LCD library code in its own C/H files so your main C code file doesn't get all cluttered up.

- Dean :twisted:

PS: As a disclaimer, keep in mind my age and my lack of professional experience when taking my advice.

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

abcminiuser:
I know man, you are very young. But atlast you have spent more time on AVR than me.
I got Flurey's LCD library of 4 bit. LCD is working fine with the code, BUT the main problem remains the same. Timer 2 is pre-ponded if I mix LCD code with Timer 2.
Man this is the biggest problem i have faced till now in my 8 yrs of development time.

YB

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yellow,

That's really bizzare if the problem is continuing! The LCD controller is nothing more than port toggling, so there should be no interactions whatsoever. Could you email me your entire code so I can simulate it (or JTAG/dW if I have the appropriate AVR)?

If nothing else, at least your code is now neat to allow for easier debugging (in theory :?).

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Ok.. abcminiuser i am emailing you the code..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Same Result........ no good news with your code........ :(

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Say, yellowboy--

Do you have capacitors to Gnd on that 32k crystal? Have you tried fussing with the values?

A similar situation was reported in
https://www.avrfreaks.net/index.p...

A couple of excerpts:

Quote:
...Atmel’s datasheet for the ’8535 advises you to merely connect
the 32,768-Hz watch crystal between the TOSC pins 1 and 2 with no
capacitors to ground. [1]
...
I found that
the crystal oscillator waveform contained serious glitches coinciding with LCD
screen refreshes.
At that point, I was using the port pin adjacent to TOSC1 to drive the LCD
ENABLE pin. Moving the LCD ENABLE pin over to port A eliminated the glitches,
but the clock was still slow.
...
which made me think that capacitance to
ground was probably needed (contrary to the datasheet). It turns out that my
oscilloscope was providing the necessary capacitance, but only when it was
hooked up. Adding 22-pF capacitors to ground cured the problem, at least with
the particular crystal I was using.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Holy moley, I think you have something there! I've been racking my brains as to why the LCD routines (which do nothing but toggles port pins) would affect the timer! If the pins could induce noise on the external timer2 clock input pins (since the main AVR clock is so much faster) you would end up with a shorter timer duration. Since all the LCD routines toggle the pins, they all would mess with the timer clock.

Yellowboy, please test this so I can have closure. I'll have to add that to my memory bank 'o' knowlege.

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

:) :) :) :) :) :) :) :) :)
Its working................
I am very very happy................
abcminiuser, theusch....................
i feel to call you both.........i am dancing now............
Mission successful..............

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
A request to Forum manager, I will put the whole issue in short and sweet words again, if you can make these words STICKY in forum. This is the MOST FLUSTRATING experience i had in my 8 to 10 years of programming experience on more than 25 Software technologies

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Care to enlighten us on what you did to solve the problem?

- Dean :twisted:

Make Atmel Studio better with my free extensions. Open source and feedback welcome!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Two 22pf Disc capacitor connected to 32.768 khz crystal and grounded

22pf
TOSC1 Pin ----||---------------------GND
|
------
= 32.768khz
------
|
TOSC2 Pin ----||-------------------GND
22pf

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

> If you can make these words STICKY in forum.

It's already sticky where it belongs to: in the "inofficial errata list"
in the general AVR forum.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.