1. We will be in Read Only mode (no new threads, replies, registration) starting at 9:00 EDT for a number of hours as we migrate the forums to upgraded software.

LCD and real clock timer

Discussion in 'Programmer's Corner' started by apiz88, Sep 14, 2008.

  1. apiz88

    Thread Starter New Member

    Sep 14, 2008
    1
    0
    i have a problem with my programming.the output did not appear at the LCD but consist of rubbish character.what should i do???


    // Industrial project -- "seat reserving" ticketing machine
    #include <p18f452.h>
    #include <delays.h>
    #include <string.h>
    #include <math.h>
    #pragma config OSC = XT // use crystal oscillator
    #define LCD_RS PORTAbits.RA3 // Assigning RA3 for Register Select on LCD
    #define LCD_EN PORTAbits.RA1 // Assigning RA1 for Enable on LCD controller
    #define LCD_WR PORTAbits.RA2 // Assigning RA2 for Write on LCD controller
    #define set_dd_line1_pos1 0x80 // The address of line 1, pos1 on the module -- was 8F
    #define set_dd_line2_pos1 0xC0 // The address of line 2, pos1 on the module -- was CF
    // Function prototypes
    void lcd_strobe(void);
    void lcd_write(unsigned char c);
    void lcd_clear(void);
    void lcd_putch(char c);
    void lcd_goto(unsigned char LCD_POS);
    void lcd_init(void);
    void T2ISR(void);
    char int_2_char (unsigned char int1);
    // ========================================================================================
    // Function to strobe the LCD
    void lcd_strobe(void) // This function provides the high to low transition needed
    // to initiate the actual transfer of commands or data to the module
    {
    LCD_EN = 1;
    Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "1"
    LCD_EN = 0;
    Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "0"
    }
    // Function to write a command byte to the LCD in 4 bit mode
    void lcd_write(unsigned char c)
    {
    unsigned char temp1;
    LCD_RS = 0; // Select LCD for command mode
    Delay10TCYx(4); // 40us delay for LCD to settle down at commmand mode
    temp1 = c;
    temp1 = temp1 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
    PORTD = temp1 & 0x0F; // Output to PORTD which is connected to LCD
    Delay1KTCYx(1); // Delay at least 1 ms before strobing
    lcd_strobe();
    Delay1KTCYx(1); // Delay at least 1 ms after strobing

    temp1 = c ; // Re-initialise temp2
    PORTD = temp1 & 0x0F; // Mask out upper 4 bits
    Delay1KTCYx(1); // Delay at least 1 ms before strobing
    lcd_strobe();
    Delay1KTCYx(1); // Delay at least 1 ms before strobing
    }
    // Function to initialise the LCD
    void lcd_init(void)
    {
    LCD_RS = 0; // Select LCD for command mode
    LCD_WR = 0; // Select LCD for write mode for only writing of commands
    // and data (ie does not read eg the status of the LCD)
    Delay10KTCYx(100); // Delay a total of 1 s for LCD module to

    // ... after power is applied, a command sequence of 3 bytes of 30h is sent to the module to ensure that the module is in
    // 8-bit mode and properly initialised. Following this, the LCD module can be switched to 4-bit mode. */
    PORTD = 0x03; // Note that PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
    // Thus, PORTD = 0x03 is 0x30 at DB7-0
    lcd_strobe();
    Delay1KTCYx(250); // 250 ms power on delay
    PORTD = 0x03;
    lcd_strobe();
    Delay1KTCYx(250); // 250 ms power on delay
    PORTD = 0x03;
    lcd_strobe();
    Delay1KTCYx(250); // 250 ms power on delay
    PORTD = 0x02; // Set to 4-bit mode
    lcd_strobe();
    Delay10KTCYx(50); // 500 ms power on delay
    lcd_write(0x28); // Send a command to set 4 bit mode, 2 line(5x7 font)
    Delay1KTCYx(20); // 20 ms power on delay
    lcd_write(0x01); // Send a command to clear display
    Delay1KTCYx(40); // 40 ms power on delay
    lcd_write(0x0F); // Send command to on display and cursor
    Delay1KTCYx(20); // 20 ms power on delay
    lcd_write(0x06); // Send command to put LCD in char entry mode
    Delay1KTCYx(20); // 20 ms power on delay
    }
    // Clear and home the LCD ie put the cursor at line1, pos1
    void lcd_clear(void) // Function to clear LCD display
    {
    LCD_RS = 0; // Select LCD for command mode
    Delay10TCYx(4); // 40us delay for LCD to settle down
    lcd_write(0x01); // LCD command 0f 0x01 clears the display
    Delay1KTCYx(2); // Delay at least 2 ms after writing the CLEAR LCD command
    }
    // Function to put cursor at a specified position
    void lcd_goto(unsigned char LCD_POS)
    {
    LCD_RS = 0; // Select LCD for command mode
    Delay10TCYx(4); // 40us delay for LCD to settle down at command mode
    lcd_write(LCD_POS); // Send the cursor position
    }
    // Function to write a character to the LCD in 4 bit mode
    void lcd_putch(char c)
    {
    char temp2;
    LCD_RS = 1; // Select LCD for data mode
    Delay10TCYx(4); // 40us delay for LCD to settle down at data mode
    temp2 = c;
    temp2 = temp2 >> 4;
    PORTD = temp2 & 0x0F;
    Delay1KTCYx(1);
    lcd_strobe();
    Delay1KTCYx(1);
    temp2 = c ;
    PORTD = temp2 & 0x0F;
    Delay1KTCYx(1);
    lcd_strobe();
    Delay1KTCYx(1);
    }
    // ==============================================================================================
    char outchar; //-- character to send to the LCD
    unsigned char hour, minute, second, hour10, hour1, minute10, minute1, second10, second1;
    unsigned int tick_count;
    void main(void)
    {
    // RTC code
    hour = 12;
    minute = 34;
    second = 56;
    tick_count = 0;
    T2CON = 0x04; // posS=1, preS=1, Timer 2 ON.
    PR2 = 199; // Period = 200 x 1us = 0.2 ms with 4-MHz crystal
    RCONbits.IPEN = 1; // Enable Priority Features
    IPR1bits.TMR2IP = 1; // Timer 2 is High Priority
    PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag.
    PIE1bits.TMR2IE = 1; // Enable Timer 2 Interrupt.
    INTCONbits.GIEH = 1; // Enable Global Interrupt, High.
    // LCD code
    ADCON1 = 0x07; // configure PORTA to be digital I/O
    TRISA = 0x00; // set Port A as output
    TRISAbits.TRISA4 = 1; // set RA4 as input pin -- button to Up Hour
    TRISBbits.TRISB0 = 1; // set RB0 as input pin -- button to Up Minute
    TRISD = 0x00; // set Port D as output
    LCD_EN = 0;
    LCD_RS = 0;
    LCD_WR = 0;
    PORTD = 0x00;
    Delay1KTCYx(1); // 1 ms power on delay
    lcd_init();
    LCD_RS = 1; // Select LCD for data mode
    Delay1KTCYx(1); // 1 ms power on delay
    lcd_clear();
    // wait forever
    while(1)
    {
    }
    }
    // RTC code
    #pragma code
    #pragma interrupt T2ISR // Timer2 -- interrupt service routine
    void T2ISR(void)
    {
    PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag.
    tick_count++;
    if (tick_count >= 5000)
    { // one second's up, (1) check RA4 to update hour (2) check RB0 to update minute (3) update second (4) update display
    tick_count = 0;
    // (1)
    if (!PORTAbits.RA4) // "RA4 pressed", PIC read 0, increment hour
    {
    hour = hour + 1; // increment hour
    if ( hour > 23 )
    hour = 0; // roll over hour
    }
    // (2)
    else if (!PORTBbits.RB0) // "RB0 pressed", PIC read 0, increment minute
    {
    minute = minute + 1; // increment minute
    if ( minute > 59 )
    {
    minute = 0; // roll over minute
    hour = hour + 1; // increment hour
    if ( hour > 23 )
    hour = 0; // roll over hour
    }
    }
    // (3)
    else // increment second
    {
    second = second + 1; // increment second
    if ( second > 59 )
    {
    second = 0; // roll over second
    minute = minute + 1; // increment minute
    if ( minute > 59 )
    {
    minute = 0; // roll over minute
    hour = hour + 1; // increment hour
    if ( hour > 23 )
    hour = 0; // roll over hour
    }
    }
    }
    hour10 = hour / 10;
    hour1 = hour - hour10 * 10;
    minute10 = minute / 10;
    minute1 = minute - minute10 * 10;
    second10 = second / 10;
    second1 = second - second10 * 10;
    // send "time = hh:mm:ss" to LCD display
    lcd_goto(set_dd_line1_pos1);
    lcd_putch('t');
    lcd_putch('i');
    lcd_putch('m');
    lcd_putch('e');
    lcd_putch(' ');
    lcd_putch('=');
    lcd_putch(' ');
    outchar = int_2_char (hour10);
    lcd_putch(outchar);
    outchar = int_2_char (hour1);
    lcd_putch(outchar);
    lcd_putch(':');
    outchar = int_2_char (minute10);
    lcd_putch(outchar);
    outchar = int_2_char (minute1);
    lcd_putch(outchar);
    lcd_putch(':');
    outchar = int_2_char (second10);
    lcd_putch(outchar);
    outchar = int_2_char (second1);
    lcd_putch(outchar);
    // send "enter #seats: _" to LCD display
    lcd_goto(set_dd_line2_pos1);
    lcd_putch('e');
    lcd_putch('n');
    lcd_putch('t');
    lcd_putch('e');
    lcd_putch('r');
    lcd_putch(' ');
    lcd_putch('#');
    lcd_putch('s');
    lcd_putch('e');
    lcd_putch('a');
    lcd_putch('t');
    lcd_putch('s');
    lcd_putch(':');
    lcd_putch(' ');
    // cursor waiting at set_dd_line2_pos1 + 14. If keypad pressed, show no of seats required....
    // lcd_putch('9'); -- example
    }
    return;
    }
    // =====================================================================
    // function to convert unsigned char to char (for display)
    char int_2_char (unsigned char int1)
    {
    char char1;
    switch (int1)
    {
    case 0 : char1 = '0' ; break;
    case 1 : char1 = '1' ; break;
    case 2 : char1 = '2' ; break;
    case 3 : char1 = '3' ; break;
    case 4 : char1 = '4' ; break;
    case 5 : char1 = '5' ; break;
    case 6 : char1 = '6' ; break;
    case 7 : char1 = '7' ; break;
    case 8 : char1 = '8' ; break;
    case 9 : char1 = '9' ; break;
    default : char1 = '?' ;
    }
    return(char1);
    }
    #pragma code IVH = 0x08 // Interrupt HIGH vector location.
    void IVH(void){ _asm goto T2ISR _endasm }
    #pragma code IVL = 0x18 // Interrupt LOW vector location.
    void IVL(void){ _asm goto T2ISR _endasm }
     
  2. SgtWookie

    Expert

    Jul 17, 2007
    22,201
    1,809
    I have not changed your program; merely re-indented it. If you do not use the CODE tags, the original indenting of your source code is lost.

    Code ( (Unknown Language)):
    1. // Industrial project -- "seat reserving" ticketing machine
    2. #include <p18f452.h>
    3. #include <delays.h>
    4. #include <string.h>
    5. #include <math.h>
    6. #pragma config OSC = XT // use crystal oscillator
    7. #define LCD_RS PORTAbits.RA3 // Assigning RA3 for Register Select on LCD
    8. #define LCD_EN PORTAbits.RA1 // Assigning RA1 for Enable on LCD controller
    9. #define LCD_WR PORTAbits.RA2 // Assigning RA2 for Write on LCD controller
    10. #define set_dd_line1_pos1 0x80 // The address of line 1, pos1 on the module -- was 8F
    11. #define set_dd_line2_pos1 0xC0 // The address of line 2, pos1 on the module -- was CF
    12. // Function prototypes
    13. void lcd_strobe(void);
    14. void lcd_write(unsigned char c);
    15. void lcd_clear(void);
    16. void lcd_putch(char c);
    17. void lcd_goto(unsigned char LCD_POS);
    18. void lcd_init(void);
    19. void T2ISR(void);
    20. char int_2_char (unsigned char int1);
    21. // ================================================== ======================================
    22. // Function to strobe the LCD
    23. void lcd_strobe(void) // This function provides the high to low transition needed
    24. // to initiate the actual transfer of commands or data to the module
    25. {
    26.     LCD_EN = 1;
    27.     Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "1"
    28.     LCD_EN = 0;
    29.     Delay10TCYx(4); // 40us delay for LCD_EN to settle at logic "0"
    30. }
    31. // Function to write a command byte to the LCD in 4 bit mode
    32. void lcd_write(unsigned char c)
    33. {
    34.     unsigned char temp1;
    35.     LCD_RS = 0; // Select LCD for command mode
    36.     Delay10TCYx(4); // 40us delay for LCD to settle down at commmand mode
    37.     temp1 = c;
    38.     temp1 = temp1 >> 4; // Output upper 4 bits, by shifting out lower 4 bits
    39.     PORTD = temp1 & 0x0F; // Output to PORTD which is connected to LCD
    40.     Delay1KTCYx(1); // Delay at least 1 ms before strobing
    41.     lcd_strobe();
    42.     Delay1KTCYx(1); // Delay at least 1 ms after strobing
    43.  
    44.     temp1 = c ; // Re-initialise temp2
    45.     PORTD = temp1 & 0x0F; // Mask out upper 4 bits
    46.     Delay1KTCYx(1); // Delay at least 1 ms before strobing
    47.     lcd_strobe();
    48.     Delay1KTCYx(1); // Delay at least 1 ms before strobing
    49. }
    50. // Function to initialise the LCD
    51. void lcd_init(void)
    52. {
    53.     LCD_RS = 0; // Select LCD for command mode
    54.     LCD_WR = 0; // Select LCD for write mode for only writing of commands
    55.     // and data (ie does not read eg the status of the LCD)
    56.     Delay10KTCYx(100); // Delay a total of 1 s for LCD module to
    57.  
    58.     // ... after power is applied, a command sequence of 3 bytes of 30h is sent to the module to ensure that the module is in
    59.     // 8-bit mode and properly initialised. Following this, the LCD module can be switched to 4-bit mode. */
    60.     PORTD = 0x03; // Note that PORTD bits 0-3 are connected to the LCD data bits 4-7 (high nibble)
    61.     // Thus, PORTD = 0x03 is 0x30 at DB7-0
    62.     lcd_strobe();
    63.     Delay1KTCYx(250); // 250 ms power on delay
    64.     PORTD = 0x03;
    65.     lcd_strobe();
    66.     Delay1KTCYx(250); // 250 ms power on delay
    67.     PORTD = 0x03;
    68.     lcd_strobe();
    69.     Delay1KTCYx(250); // 250 ms power on delay
    70.     PORTD = 0x02; // Set to 4-bit mode
    71.     lcd_strobe();
    72.     Delay10KTCYx(50); // 500 ms power on delay
    73.     lcd_write(0x28); // Send a command to set 4 bit mode, 2 line(5x7 font)
    74.     Delay1KTCYx(20); // 20 ms power on delay
    75.     lcd_write(0x01); // Send a command to clear display
    76.     Delay1KTCYx(40); // 40 ms power on delay
    77.     lcd_write(0x0F); // Send command to on display and cursor
    78.     Delay1KTCYx(20); // 20 ms power on delay
    79.     lcd_write(0x06); // Send command to put LCD in char entry mode
    80.     Delay1KTCYx(20); // 20 ms power on delay
    81. }
    82. // Clear and home the LCD ie put the cursor at line1, pos1
    83. void lcd_clear(void) // Function to clear LCD display
    84. {
    85.     LCD_RS = 0; // Select LCD for command mode
    86.     Delay10TCYx(4); // 40us delay for LCD to settle down
    87.     lcd_write(0x01); // LCD command 0f 0x01 clears the display
    88.     Delay1KTCYx(2); // Delay at least 2 ms after writing the CLEAR LCD command
    89. }
    90. // Function to put cursor at a specified position
    91. void lcd_goto(unsigned char LCD_POS)
    92. {
    93.     LCD_RS = 0; // Select LCD for command mode
    94.     Delay10TCYx(4); // 40us delay for LCD to settle down at command mode
    95.     lcd_write(LCD_POS); // Send the cursor position
    96. }
    97. // Function to write a character to the LCD in 4 bit mode
    98. void lcd_putch(char c)
    99. {
    100.     char temp2;
    101.     LCD_RS = 1; // Select LCD for data mode
    102.     Delay10TCYx(4); // 40us delay for LCD to settle down at data mode
    103.     temp2 = c;
    104.     temp2 = temp2 >> 4;
    105.     PORTD = temp2 & 0x0F;
    106.     Delay1KTCYx(1);
    107.     lcd_strobe();
    108.     Delay1KTCYx(1);
    109.     temp2 = c ;
    110.     PORTD = temp2 & 0x0F;
    111.     Delay1KTCYx(1);
    112.     lcd_strobe();
    113.     Delay1KTCYx(1);
    114. }
    115. // ================================================== ============================================
    116. char outchar; //-- character to send to the LCD
    117. unsigned char hour, minute, second, hour10, hour1, minute10, minute1, second10, second1;
    118. unsigned int tick_count;
    119. void main(void)
    120. {
    121.     // RTC code
    122.     hour = 12;
    123.     minute = 34;
    124.     second = 56;
    125.     tick_count = 0;
    126.     T2CON = 0x04; // posS=1, preS=1, Timer 2 ON.
    127.     PR2 = 199; // Period = 200 x 1us = 0.2 ms with 4-MHz crystal
    128.     RCONbits.IPEN = 1; // Enable Priority Features
    129.     IPR1bits.TMR2IP = 1; // Timer 2 is High Priority
    130.     PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag.
    131.     PIE1bits.TMR2IE = 1; // Enable Timer 2 Interrupt.
    132.     INTCONbits.GIEH = 1; // Enable Global Interrupt, High.
    133.     // LCD code
    134.     ADCON1 = 0x07; // configure PORTA to be digital I/O
    135.     TRISA = 0x00; // set Port A as output
    136.     TRISAbits.TRISA4 = 1; // set RA4 as input pin -- button to Up Hour
    137.     TRISBbits.TRISB0 = 1; // set RB0 as input pin -- button to Up Minute
    138.     TRISD = 0x00; // set Port D as output
    139.     LCD_EN = 0;
    140.     LCD_RS = 0;
    141.     LCD_WR = 0;
    142.     PORTD = 0x00;
    143.     Delay1KTCYx(1); // 1 ms power on delay
    144.     lcd_init();
    145.     LCD_RS = 1; // Select LCD for data mode
    146.     Delay1KTCYx(1); // 1 ms power on delay
    147.     lcd_clear();
    148.     // wait forever
    149.     while(1)
    150.     {
    151.     }
    152. }
    153. // RTC code
    154. #pragma code
    155. #pragma interrupt T2ISR // Timer2 -- interrupt service routine
    156. void T2ISR(void)
    157. {
    158.     PIR1bits.TMR2IF = 0; // Clear Timer 2 Flag.
    159.     tick_count++;
    160.     if (tick_count >= 5000)
    161.     { // one second's up, (1) check RA4 to update hour (2) check RB0 to update minute (3) update second (4) update display
    162.         tick_count = 0;
    163.         // (1)
    164.         if (!PORTAbits.RA4) // "RA4 pressed", PIC read 0, increment hour
    165.         {
    166.             hour = hour + 1; // increment hour
    167.             if ( hour > 23 )
    168.             hour = 0; // roll over hour
    169.         }
    170.         // (2)
    171.         else if (!PORTBbits.RB0) // "RB0 pressed", PIC read 0, increment minute
    172.         {
    173.             minute = minute + 1; // increment minute
    174.             if ( minute > 59 )
    175.             {
    176.                 minute = 0; // roll over minute
    177.                 hour = hour + 1; // increment hour
    178.                 if ( hour > 23 )
    179.                 hour = 0; // roll over hour
    180.             }
    181.         }
    182.         // (3)
    183.         else // increment second
    184.         {
    185.             second = second + 1; // increment second
    186.             if ( second > 59 )
    187.             {
    188.                 second = 0; // roll over second
    189.                 minute = minute + 1; // increment minute
    190.                 if ( minute > 59 )
    191.                 {
    192.                     minute = 0; // roll over minute
    193.                     hour = hour + 1; // increment hour
    194.                     if ( hour > 23 )
    195.                     hour = 0; // roll over hour
    196.                 }
    197.             }
    198.         }
    199.         hour10 = hour / 10;
    200.         hour1 = hour - hour10 * 10;
    201.         minute10 = minute / 10;
    202.         minute1 = minute - minute10 * 10;
    203.         second10 = second / 10;
    204.         second1 = second - second10 * 10;
    205.         // send "time = hh:mm:ss" to LCD display
    206.         lcd_goto(set_dd_line1_pos1);
    207.         lcd_putch('t');
    208.         lcd_putch('i');
    209.         lcd_putch('m');
    210.         lcd_putch('e');
    211.         lcd_putch(' ');
    212.         lcd_putch('=');
    213.         lcd_putch(' ');
    214.         outchar = int_2_char (hour10);
    215.         lcd_putch(outchar);
    216.         outchar = int_2_char (hour1);
    217.         lcd_putch(outchar);
    218.         lcd_putch(':');
    219.         outchar = int_2_char (minute10);
    220.         lcd_putch(outchar);
    221.         outchar = int_2_char (minute1);
    222.         lcd_putch(outchar);
    223.         lcd_putch(':');
    224.         outchar = int_2_char (second10);
    225.         lcd_putch(outchar);
    226.         outchar = int_2_char (second1);
    227.         lcd_putch(outchar);
    228.         // send "enter #seats: _" to LCD display
    229.         lcd_goto(set_dd_line2_pos1);
    230.         lcd_putch('e');
    231.         lcd_putch('n');
    232.         lcd_putch('t');
    233.         lcd_putch('e');
    234.         lcd_putch('r');
    235.         lcd_putch(' ');
    236.         lcd_putch('#');
    237.         lcd_putch('s');
    238.         lcd_putch('e');
    239.         lcd_putch('a');
    240.         lcd_putch('t');
    241.         lcd_putch('s');
    242.         lcd_putch(':');
    243.         lcd_putch(' ');
    244.         // cursor waiting at set_dd_line2_pos1 + 14. If keypad pressed, show no of seats required....
    245.         // lcd_putch('9'); -- example
    246.     }
    247.     return;
    248. }
    249. // ================================================== ===================
    250. // function to convert unsigned char to char (for display)
    251. char int_2_char (unsigned char int1)
    252. {
    253.     char char1;
    254.     switch (int1)
    255.     {
    256.     case 0 : char1 = '0' ; break;
    257.     case 1 : char1 = '1' ; break;
    258.     case 2 : char1 = '2' ; break;
    259.     case 3 : char1 = '3' ; break;
    260.     case 4 : char1 = '4' ; break;
    261.     case 5 : char1 = '5' ; break;
    262.     case 6 : char1 = '6' ; break;
    263.     case 7 : char1 = '7' ; break;
    264.     case 8 : char1 = '8' ; break;
    265.     case 9 : char1 = '9' ; break;
    266.         default : char1 = '?' ;
    267.     }
    268.     return(char1);
    269. }
    270. #pragma code IVH = 0x08 // Interrupt HIGH vector location.
    271. void IVH(void){ _asm goto T2ISR _endasm }
    272. #pragma code IVL = 0x18 // Interrupt LOW vector location.
    273. void IVL(void){ _asm goto T2ISR _endasm }
     
  3. nanovate

    Distinguished Member

    May 7, 2007
    665
    1
    maybe your timing is off
     
  4. Lucysmith

    New Member

    Oct 3, 2008
    3
    0
    well let me check it in details, well you did not mention what types of character you got as output as if it is non-stop, it means you have problem in some of your loop otherwise let me know your exact problem
     
Loading...