Author Topic: using any frequency other than 1MHz prevents the LCD from working  (Read 2716 times)

0 Members and 1 Guest are viewing this topic.

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
with 1MHz speed it worked fine, but when I switch to any other freq, it doesn't work :-//
So, right now i'm testing it with 4MHz


This line is used before and after including <xc.h> , in main, and in the lcd driver, it's everywhere.
Code: [Select]
#define _XTAL_FREQ 4000000
This line to use the internal osc
Code: [Select]
#pragma config FOSC = INTOSC_EC 
This line(kinda) for prescaling the internal clock to reach 4MHz.
Code: [Select]
IRCF2 = 1; IRCF1 = 1; IRCF0 = 0;

Does this have something to do with Start-up time ?  i'm really not sure what i'm missing.
 

Offline Simon

  • Global Moderator
  • *****
  • Posts: 17728
  • Country: gb
  • Did that just blow up? No? might work after all !!
    • Simon's Electronics
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #1 on: June 04, 2016, 06:33:06 pm »
What clock speed at datasheet permit?
 

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #2 on: June 04, 2016, 06:51:40 pm »
What clock speed at datasheet permit?

 :-//

I think it depends on the delay after instructions, i'm not sure though.

but page 52 in the datasheet seems to be relevant https://www.sparkfun.com/datasheets/LCD/HD44780.pdf
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7695
  • Country: de
  • A qualified hobbyist ;)
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #3 on: June 04, 2016, 07:12:39 pm »
There's the signal/bus timing (pages 52 and 58+) and the time required for processing instructions. Both have to be correct and your code needs to adjust the delay loops based on the clock frequency.
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #4 on: June 04, 2016, 07:28:04 pm »
There's the signal/bus timing (pages 52 and 58+) and the time required for processing instructions. Both have to be correct and your code needs to adjust the delay loops based on the clock frequency.

but my chip will give the same delays when working with different frequencies, cuz I set the _XTAL_FREQ accordingly to each different freq, right ?
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7695
  • Country: de
  • A qualified hobbyist ;)
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #5 on: June 04, 2016, 07:42:10 pm »
but my chip will give the same delays when working with different frequencies, cuz I set the _XTAL_FREQ accordingly to each different freq, right ?

Since I don't know your source code I can't answer your question.
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #6 on: June 04, 2016, 07:54:40 pm »
but my chip will give the same delays when working with different frequencies, cuz I set the _XTAL_FREQ accordingly to each different freq, right ?

Since I don't know your source code I can't answer your question.

I don't want to bother you with a big long chunk of code.

here are the most important bits.

this is part of the initialize function:
Code: [Select]
    // Initial delay after power-up
    delay_us(16000);       
    LCD_DATA1_LAT |= _BV(LCD_DATA1_PIN);
    LCD_DATA0_LAT |= _BV(LCD_DATA0_PIN);
    lcd_e_cycle();
    delay_us(4992);                /* delay, busy flag can't be checked here */
    /* repeat last command a second time */
    lcd_e_cycle();     
    delay_us(64);            /* delay, busy flag can't be checked here */
    /* repeat last command a third time */
    lcd_e_cycle();     
    delay_us(64);             /* delay, busy flag can't be checked here */

    /* now configure for 4bit mode */
    LCD_DATA0_LAT &= ~_BV(LCD_DATA0_PIN);
    lcd_e_cycle();
    delay_us(64);             /* some displays need this additional delay */

    // Configure display after power up
    lcd_command(LCD_DISP_OFF);              /* display off                  */
    lcd_clrscr();                           /* display clear                */
    lcd_command(LCD_MODE_DEFAULT);          /* set entry mode               */
    lcd_command(dispAttr);                  /* display/cursor control       */
}



This is the main code
Code: [Select]
#include "lcd.h"
//BEGIN CONFIG
#pragma config FOSC = INTOSC_EC                //High speed external oscillater, with PLL not allowed
//#pragma config CPUDIV = OSC4_PLL6       //postscale divide by 4
#pragma config WDT = OFF                //watch dog off
#pragma config LVP = OFF
#pragma config CPD = OFF 
//END CONFIG

int main()
{
    IRCF2 = 1;IRCF1 = 1;IRCF0 = 0;
    set_output(TRISC,0);
    RBPU    = 0;    // enable internal pullups on PORTB
    ADCON1  =0x0F;  // Make all ADC ANx pins digital
    CMCON   =0x07;  // Make all Comparator CMx pins digital

    delay_ms(30);

    while(1){
        lcd_init(LCD_DISP_ON);
        lcd_clrscr();
        //put something on the screen
        lcd_gotoxy(0 ,1);
        lcd_puts(" soylent green");
        //just wait a couple of seconds, clear screen, and wait again*/
        lcd_gotoxy(0 ,2);
        lcd_puts("  is people");
        delay_10ms(250);
        lcd_clrscr();
        delay_10ms(20);

        toggle(LATC,0);
    }
    return 0;
}

the e delay
Code: [Select]
#define lcd_e_delay() delay_us(4)

the e cycle function
Code: [Select]
static void cycle_e(void)
{
    lcd_e_high();
    lcd_e_delay();
    lcd_e_low();
}

The thoroughly tested delay functions...
Code: [Select]
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#define delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7695
  • Country: de
  • A qualified hobbyist ;)
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #7 on: June 04, 2016, 08:17:22 pm »
The thoroughly tested delay functions...
Code: [Select]
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#define delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))

When _XTAL_FREQ is 4MHz you get (x * 1) for delay_us() and at 1 MHz it's (x * 0). For delay_ms() it's (x * 1000) at 4MHz and (x * 250) at 1 MHz. :-//  What does _delay() and which parameter does it expect?
 
The following users thanked this post: MAD MACRO

Offline MAD MACROTopic starter

  • Regular Contributor
  • *
  • Posts: 56
  • Country: eg
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #8 on: June 04, 2016, 08:22:35 pm »
The thoroughly tested delay functions...
Code: [Select]
#define delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
#define delay_us(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000000.0)))

When _XTAL_FREQ is 4MHz you get (x * 1) for delay_us() and at 1 MHz it's (x * 0). For delay_ms() it's (x * 1000) at 4MHz and (x * 250) at 1 MHz. :-//  What does _delay() and which parameter does it expect?
Good job, I wouldn't have spotted that, this is very strange, why would it work at 1MHz then ?  :-//

it's the native function _delay() from the xc8 compiler, it's most likely a cycle delay.    _delay(1) = one cycle delay
 

Offline madires

  • Super Contributor
  • ***
  • Posts: 7695
  • Country: de
  • A qualified hobbyist ;)
Re: using any frequency other than 1MHz prevents the LCD from working
« Reply #9 on: June 05, 2016, 02:55:37 pm »
For a 1MHz clock one cycle is 1µs. When calling _delay() some registers might be pushed to the stack, the call of the function, the loop inside the _delay() function, returning and popping registers back from the stack all need some MCU cycles. A call of _delay(0) could need 15 cycles (just an estimate), i.e. 15µs. And since delay_us() is _delay(0) any call results in a delay of 15 cycles or 15 µs. As long as you don't need more than 15µs delay everything is fine ;)

With 4 MHz we get 250ns for each clock cycle. So any call of _delay() would need 15 cycles plus the given value times loop logic. Let's say we call delay_us(10). We might burn 15 cycles plus 10 for the loop runs (each loop run might need 3 cycles and the function therefore takes the given value divided by three). 25 cycles are 6.25µs. It's just an example. Based on how _delay() is implemented it could be better or worse.

Proper delay functions can be tricky.
 
The following users thanked this post: MAD MACRO


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf