• 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.

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

Status
Not open for further replies.

be80be

Well-Known Member
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:
#define LCD_Cmd( c )                     \
do {                                     \
    LCD_Write( (c & 0xF0) >> 4 );        \
    LCD_Write( c & 0x0F);                \
} while ( false )
 

Pommie

Well-Known Member
Most Helpful Member
That is using bits 0 to 3. And why do you need a do while around it, won't just {} work?

Mike.
 

be80be

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

Pommie

Well-Known Member
Most Helpful Member
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.
 

be80be

Well-Known Member
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:

Pommie

Well-Known Member
Most Helpful Member
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.
 

be80be

Well-Known Member
I switched to en and rs to portb its printing dots just dots
Code:
#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:
//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);
}
 

Pommie

Well-Known Member
Most Helpful Member
Check out my edit above. Looks like RC5 might be an input.

Edit, your LCD_cmd is only writing 4 bits.

Mike.
 

be80be

Well-Known Member
If you all would answer this cause I'm not that up on this.
But
Code:
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.
 

Pommie

Well-Known Member
Most Helpful Member
Burt,
Can you try the following in your code with the connections back on PORTC with OPTION Register set to 0b11011111;
Code:
#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.
 

be80be

Well-Known Member
This works ok but it's not right I think the delays are messed up a bit.
Code:
/*
 * 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);

}
 

Pommie

Well-Known Member
Most Helpful Member
Looks like we posted at the same time.

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

Mike.
 

Pommie

Well-Known Member
Most Helpful Member
Here's the initialization sequence, note the first 3 writes are nibbles only.
LCD init.png

Mike.
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top