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,182
    1,728
    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...