1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

How to Change to use lower 4bits chip doesn't have upper 4 bits

Discussion in 'Microcontrollers' started by be80be, Sep 9, 2017.

  1. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    The chip I'm using doesn't have a 8 bit port only 0 to 5 So how can I change this to use lower port bits

    Code (text):

    #define LCD_Cmd( c )                     \
    do {                                     \
        LCD_Write( (c & 0xF0) >> 4 );        \
        LCD_Write( c & 0x0F);                \
    } while ( false )
     
     
  2. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    That is using bits 0 to 3. And why do you need a do while around it, won't just {} work?

    Mike.
     
  3. Nigel Goodwin

    Nigel Goodwin Super Moderator Most Helpful Member

    Joined:
    Nov 17, 2003
    Messages:
    39,331
    Likes:
    653
    Location:
    Derbyshire, UK
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn

    I tried that code it dosen't work on a 16f505 I'm thinking I have to load the port all at once.
     
  6. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    You can write bits in any order, They only get latched when you set Enable high. BTW what are the other control pins commected to? I assume R/W is tied low and C/D and E are other pins.

    Mike.
     
  7. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    I tried it all on portc the code worked fine on a 16f1825 but the 16f505 I get nothing.
    RW tied to ground
    the rest are as listed
    #define _XTAL_FREQ 4000000
    #define RS RC5
    #define EN RC4
    #define D4 RC0
    #define D5 RC1
    #define D6 RC2
    #define D7 RC3
     
    Last edited: Sep 10, 2017
  8. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    That should work fine. Can you post the write command and write data routines?

    Edit, check the option register, RC5 can be set to T0CKI which overrides TRIS.

    Mike.
     
  9. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    I switched to en and rs to portb its printing dots just dots
    Code (text):

    #define _XTAL_FREQ 4000000
    #define RS RB5
    #define EN RB4
    #define D4 RC0  
    #define D5 RC1
    #define D6 RC2
    #define D7 RC3
    // CONFIG
    #pragma config OSC = IntRC_RB4EN// Oscillator Selection bits (Internal RC oscillator/RB4 function on RB4/OSC2/CLKOUT pin)
    #pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled)
    #pragma config CP = OFF         // Code Protection bit (Code protection off)
    #pragma config MCLRE = ON       // RB3/MCLR Pin Function Select bit (RB3/MCLR pin function is MCLR)

    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.


    #include <xc.h>

    #include "lcd.h";




    int main()
    {
       OSCCAL= 0b01111110;
      unsigned int a;
      TRISC = 0x00;
      TRISB = 0x00;
      Lcd_Init();
      while(1)
      {
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("LCD Library for");
        Lcd_Set_Cursor(2,1);
        Lcd_Write_String("MPLAB XC8");
        __delay_ms(2000);
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("For 16F505");
        Lcd_Set_Cursor(2,1);
        Lcd_Write_String("Have fun");
        __delay_ms(2000);
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("be80be");

        for(a=0;a<15;a++)
        {
            __delay_ms(300);
            Lcd_Shift_Left();
        }

        for(a=0;a<15;a++)
        {
            __delay_ms(300);
            Lcd_Shift_Right();
        }

        Lcd_Clear();
        Lcd_Set_Cursor(2,1);
        Lcd_Write_Char('2');
        Lcd_Write_Char('2');
        __delay_ms(2000);
      }
      return 0;
    }
     
    And
    Code (text):

    //lcd//LCD Functions

    void Lcd_Port(char a)
    {
        if(a & 1)
            D4 = 1;
        else
            D4 = 0;

        if(a & 2)
            D5 = 1;
        else
            D5 = 0;

        if(a & 4)
            D6 = 1;
        else
            D6 = 0;

        if(a & 8)
            D7 = 1;
        else
            D7 = 0;
    }
    void Lcd_Cmd(char a)
    {
        RS = 0;             // => RS = 0
        Lcd_Port(a);
        EN  = 1;             // => E = 1
            __delay_ms(4);
            EN  = 0;             // => E = 0
    }

    Lcd_Clear()
    {
        Lcd_Cmd(0);
        Lcd_Cmd(1);
    }

    void Lcd_Set_Cursor(char a, char b)
    {
        char temp,z,y;
        if(a == 1)
        {
         temp = 0x80 + b - 1;
            z = temp>>4;
            y = temp & 0x0F;
            Lcd_Cmd(z);
            Lcd_Cmd(y);
        }
        else if(a == 2)
        {
            temp = 0xC0 + b - 1;
            z = temp>>4;
            y = temp & 0x0F;
            Lcd_Cmd(z);
            Lcd_Cmd(y);
        }
    }

    void Lcd_Init()
    {
      Lcd_Port(0x00);
       __delay_ms(20);
      Lcd_Cmd(0x03);
        __delay_ms(5);
      Lcd_Cmd(0x03);
        __delay_ms(11);
      Lcd_Cmd(0x03);
      /////////////////////////////////////////////////////
      Lcd_Cmd(0x02);
      Lcd_Cmd(0x02);
      Lcd_Cmd(0x08);
      Lcd_Cmd(0x00);
      Lcd_Cmd(0x0C);
      Lcd_Cmd(0x00);
      Lcd_Cmd(0x06);
    }

    void Lcd_Write_Char(char a)
    {
       char temp,y;
       temp = a&0x0F;
       y = a&0xF0;
       RS = 1;             // => RS = 1
       Lcd_Port(y>>4);             //Data transfer
       EN = 1;
       __delay_us(40);
       EN = 0;
       Lcd_Port(temp);
       EN = 1;
       __delay_us(40);
       EN = 0;
    }

    void Lcd_Write_String(char *a)
    {
        int i;
        for(i=0;a[i]!='\0';i++)
          Lcd_Write_Char(a[i]);
    }

    void Lcd_Shift_Right()
    {
        Lcd_Cmd(0x01);
        Lcd_Cmd(0x0C);
    }

    void Lcd_Shift_Left()
    {
        Lcd_Cmd(0x01);
        Lcd_Cmd(0x08);
    }
     
     
  10. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    Check out my edit above. Looks like RC5 might be an input.

    Edit, your LCD_cmd is only writing 4 bits.

    Mike.
     
  11. Ian Rogers

    Ian Rogers Super Moderator Most Helpful Member

    Joined:
    Mar 28, 2011
    Messages:
    9,310
    Likes:
    914
    Location:
    Rochdale UK
    I don't like the way LCD_port is still using the high bits... You really don't need this function!!
     
  12. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    If you all would answer this cause I'm not that up on this.
    But
    Code (text):

    if(a & 1)
            D4 = 1;
        else
            D4 = 0;

        if(a & 2)
            D5 = 1;
        else
            D5 = 0;

        if(a & 4)
            D6 = 1;
        else
            D6 = 0;

        if(a & 8)
            D7 = 1;
        else
            D7 = 0;
     
    I & a with 1 and and if it's 1 I get a 1 else if it's 0 I get a 0
    think thats it but It looks like it's shifting wrong I got a 0 on the lcd and the cmd's work but loading letter's I still get a bunch of dot's not blocks of dot's just dot's everywhere.
     
  13. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    Burt,
    Can you try the following in your code with the connections back on PORTC with OPTION Register set to 0b11011111;
    Code (text):

    #define LCDport PORTC
    #define EN RC4
    #define RS RC5
    #define RSbit 0b00100000
    #define uint8 unsigned char

    WriteNibble(uint8 dat){    // dat also contains RS bit
        LCDport=dat;
        EN=1;
        EN=0;
    }

    WriteData(uint8 dat){
        WriteNibble((dat>>4)|RSbit);
        WriteNibble((dat&0x0f)|RSbit);
    }

    WriteCommand(uint8 dat){
        WriteNibble(dat>>4);
        WriteNibble(dat&0x0f);
    }

    void Lcd_Init(){
        __delay_ms(20);
        WriteNibble(0x03);
        __delay_ms(5);
        WriteNibble(0x03);
        __delay_ms(1);
        WriteNibble(0x03);
        __delay_ms(1);
        WriteNibble(0x02);
        WriteCommand(0x20);             //set to 4 bit interface
        WriteCommand(0x2c);             //set to 4 bit interface, 2 line and 5*10 font
        WriteCommand(0x01);             //clear display
        WriteCommand(0x06);             //move cursor right after write
        WriteCommand(0x0C);             //turn on display
    }
    Mike.
     
  14. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    This works ok but it's not right I think the delays are messed up a bit.
    Code (text):

    /*
     * File:   main.c
     * Author: burt
     *
     * Created on September 12, 2017, 9:41 PM
     */
    #define _XTAL_FREQ 4000000

    // CONFIG
    #pragma config OSC = IntRC_RB4EN// Oscillator Selection bits (Internal RC oscillator/RB4 function on RB4/OSC2/CLKOUT pin)
    #pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled)
    #pragma config CP = OFF         // Code Protection bit (Code protection off)
    #pragma config MCLRE = ON       // RB3/MCLR Pin Function Select bit (RB3/MCLR pin function is MCLR)


    #include <xc.h>

    #define RS_PIN   RB4   /* PORT for RS */
    #define E_PIN    RB5   /* PORT for E  */

    void print(unsigned int);
    void cmd(unsigned int);
    void lcd_init(void);

    void main(void)
    {

        int count=0;

        char output0[] = "  Burt";
        char output1[] = "be80be";

        TRISC=0x00;
        TRISB=0x00;

        PORTC=0x00;
        PORTB=0x00;
        __delay_us(400);

        lcd_init();

        while(output0[count] != '\0')
        {
        print(output0[count]);
        count++;
        }
        __delay_us(400);
        cmd(0b11000000);    //Move 2nd Next Line

        count = 0;
        while(output1[count] != '\0')
        {
        print(output1[count]);
        count++;
        }
        __delay_us(400);
        cmd(0b10000000);
       
        while(1)
        {
        }

    }

    void lcd_init(void)
    {
    E_PIN = 0;
    RS_PIN = 0;
    //RW_PIN = 0;

    cmd(0b00000010);
    __delay_ms(20);
    cmd(0b00101000);
    __delay_ms(20);
    cmd(0b00001100);
    __delay_ms(20);
    cmd(0b00000001);
    __delay_ms(20);
    cmd(0b00000010);
    }


    //4-bit print interface

    void print(unsigned int character)
    {

    PORTC=character >> 4;

    RS_PIN = 1;
    E_PIN = 1;
    E_PIN = 0;
    RS_PIN = 0;

    PORTC=character & 0x0f;

    RS_PIN = 1;
    E_PIN = 1;
    E_PIN = 0;
    RS_PIN = 0;

    __delay_us(20);


    }


    //4-bit  interface

    void cmd(unsigned int cmd)
    {

    PORTC=cmd >> 4;
    E_PIN = 1;
    E_PIN = 0;

    PORTC=cmd &0x0f;
    E_PIN = 1;
    E_PIN = 0;

    __delay_us(20);

    }
     
     
  15. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    Looks like we posted at the same time.

    Edit, the initialization routine can't write commands until it has written several nibbles.

    Mike.
     
  16. Pommie

    Pommie Well-Known Member Most Helpful Member

    Joined:
    Mar 18, 2005
    Messages:
    10,161
    Likes:
    340
    Location:
    Brisbane Australia
    Here's the initialization sequence, note the first 3 writes are nibbles only.
    LCD init.png

    Mike.
     
  17. be80be

    be80be Well-Known Member

    Joined:
    Aug 23, 2008
    Messages:
    4,869
    Likes:
    144
    Location:
    morristown,tn
    I'm going to try mike see how your changes go
     

Share This Page