Continue to Site

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.

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

Help with PORT and Bit change

Status
Not open for further replies.

pnkeir

New Member
Can anyone help me with this.
I need to use " PORTC " and 4 x MSD's( bit7,6,5,4) instead of the LSD(bit,3,2,1,0).

I have also re-defined E, R/W, RS to C,2 C,1, and C,3 as in my circuit. I know it works as i have loaded assm code with the same Pin Cons.
I would be very grateful for help to find my mistake as i am trying to learn and understand 'C' Here is one of the changes i have tried! as well i have changed the order of Nybble(i); -- Nybble(i>>4);

Code:
,6,5,4 
void Nybble(unsigned char dat)//
{
    dat &= 0xf0;             // clear top bits of dat
    LCDdata &= 0xf0;         //  clear bottom bits of port (interested only in DB7-DB4)
    LCDdata |= dat;          //or the two and store at port
    E = 1;
    Delay1TCY();             //enable pulse width >= 300ns (used 4uS)
    E = 0;                       //Clock enable: falling edge
}
 
Last edited:
What does the variable "dat" contain.... You are clearing the bottom nibble of both... If dat contains the information in the top nibble..

ie.. Lets say dat = 0x40..... dat &= 0xf0; now dat contains 0x40....

but you are then clearing c2, c1, and c3 ( rs and rw are always zero )

I think that line should be... LCDdata &= 0x0f;.. to preserve the control bits... and clear the top nibble so you can OR in the data..
 
Thanks !! Much appreciated your reply. I totally missed that i would be clearing my control Pins. I am now getting strange characters on the Display but its closer.
The other change i have made is shown attached and i am swapping the 2nd Nybble . I think this should have been be right. It looks right in the dissembled listing but i am getting P ` p`p P`p`p

Code:
{
	RS =0;
	R_W =0;          //R/W=LOW : Write
	Nybble(i);    //Send upper 4 bits
	Nybble(i>>4);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait at least 2mS (2*1000*4/1e6 = 8ms used)
}
 void write(unsigned char i)
{
	RS =1;
	R_W =0;          //R/W=LOW : Write
	Nybble(i);    //Send upper 4 bits
	Nybble(i>>4);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait 2mS
}
 
Last edited:
Use the "#" tag
Code:
void command(unsigned char i)
   {
   RS =0;
   R_W =0; //R/W=LOW : Write
   Nybble(i); //Send upper 4 bits
   Nybble(i<<4); //Send lower 4 bits (wrong way round)
   Delay1KTCYx(2); //must wait at least 2mS (2*1000*4/1e6 = 8ms used)
}

void write(unsigned char i)
   {
   RS =1;
   R_W =0; //R/W=LOW : Write
   Nybble(i); //Send upper 4 bits
   Nybble(i<<4); //Send lower 4 bits  (wrong way round)
   Delay1KTCYx(2); //must wait 2mS
   }
 
I am sorry about the wrong Tags i used.
Here is the complete code from Pommie and the only change is to use the 4 x MSDs instead of the LSD .
I should be able to find it as now only the LSDs need to be swapped before sending the second Nybble. What i have seems right now but i still must be missing something. Thanks a lot in advance if you can help!

Code:
 //LCD (PortC)
#define  E LATCbits.LATC2
#define  R_W LATCbits.LATC1 
#define  RS  LATCbits.LATC3
#define LCDdata LATC
 
 
void command(unsigned char);
void write(unsigned char);
void Nybble(unsigned char);
void init(void);
void PutMessage(rom char *);
 
void main()
{
	while(!OSCCONbits.IOFS);      //wait for osc stable
   	ADCON1 = 0x0F;                //make RA0 digital
    OSCCON = 0x40;     // 0x70=16 MHz 60=8 MHz  50=4 40=2 30=1  20=500KHz 10=250

    //data direction registers all 0's mean that all pins are set to output
	//all 1's means that all of the pins are set to operate as inputs
	TRISA = 0x00;  
	TRISB = 0x00; 
	TRISC = 0x00;
        init();
 
		while(1)
		{
        	PutMessage("Thanks");
        	command(0xc0);
        	PutMessage("Pommie");
			Delay10KTCYx(50);
 
			command(0x01);      //Clear Display (Added)
 
			PutMessage("Thank");
       		command(0xc0);
        	PutMessage("You");
			Delay10KTCYx(50);
 
			command(0x01);      //Clear Display (Added)
			PutMessage("Electro");
        	command(0xc0);
        	PutMessage("tech");
			Delay10KTCYx(50);
 
			command(0x01);      //Clear Display (Added)
 
			PutMessage("Forum");
        	command(0xc0);
        	PutMessage("members");
			Delay10KTCYx(50);
 
			command(0x01);      //Clear Display (Added)
		}
 
}
 
//Write a string to the LCD
void PutMessage(rom char *Message){
rom char *Pos = Message;
	while(*Pos!=0)
	    write(*Pos++);
}
 
/**********************************************************/
//4-bit methods for LCD
/**********************************************************/
void command(unsigned char i)
{
	RS =0;
	R_W =0;          //R/W=LOW : Write
	Nybble(i);    //Send upper 4 bits
	Nybble(i>>4);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait at least 2mS (2*1000*4/1e6 = 8ms used)
}
 void write(unsigned char i)
{
	RS =1;
	R_W =0;          //R/W=LOW : Write
	Nybble(i);    //Send upper 4 bits
	Nybble(i>>4);       //Send lower 4 bits
	Delay1KTCYx(2);  //must wait 2mS
}
/**********************************************************/
void Nybble(unsigned char dat)//------------------------------------------------------------mm
{
    dat &= 0xf0;             // 0x0f //clear top bits of dat
    LCDdata &= 0x0f;         //  0xf0 //clear bottom bits of port (interested only in DB7-DB4)
    LCDdata |= dat;          //or the two and store at port
    E = 1;
    Delay1TCY();             //enable pulse width >= 300ns (used 4uS)
    E = 0;                   //Clock enable: falling edge
}
 /**********************************************************/
void init(void)
{
    LCDdata=0x00; 
    Delay1KTCYx(15);    //Wait >15 msec after power is applied (used 20mS)
    Nybble(0x3); 	//command 0x30 = Wake up
    Delay1KTCYx(5);     //must wait 160us, busy flag not available (used 160uS)
    Nybble(0x3); 	//command 0x30 = Wake up #2
    Delay1KTCYx(5); 	//must wait 160us, busy flag not available (used 160uS) 
 
    command(0x20);      //Function set: 4-bit/2-line
    command(0x2c);      //Function set: 4-bit/2-line
    command(0x10);      //Set cursor
    command(0x01);      //Clear Display (Added)
    command(0x06);      //Entry Mode set
    command(0x0c);
}
/**********************************************************/
//End methods for LCD
/**********************************************************/
 
Last edited:
Peter (pnkeir),

If you have the LCD D4..D7 pins connected to RC4..RC7, then please check your code. During the Hitachi HD44780 "initialize by instruction" procedure (4-bit mode), you want to write the high nibble of the 0x30 (8-bit) and the 0x20 (4-bit) commands. Your code is not doing that.

If it helps, I posted an LCD example program here (BoostC).

Regards, Mike

<added>
It seems you're also shifting your data byte the wrong way. Since you're sending the upper four bits of a byte when you write each nibble, you need to shift your data byte four bits to the left after sending the high nibble in order to send the lower nibble.
 
Last edited:
Hi again Mike!!
Thanks again for your help. Last time it was with my DS18B20(Im still working on it . I am working hard on C as ive been stuck on asm forever and realize i must change. Is this init Function at the end of my code not correct.
Code:
void init(void)
{
    LCDdata=0x00; 
    Delay1KTCYx(15);    //Wait >15 msec after power is applied (used 20mS)
    Nybble(0x3); 	//command 0x30 = Wake up
    Delay1KTCYx(5);     //must wait 160us, busy flag not available (used 160uS)
    Nybble(0x3); 	//command 0x30 = Wake up #2
    Delay1KTCYx(5); 	//must wait 160us, busy flag not available (used 160uS) 
 
    command(0x20);      //Function set: 4-bit/2-line
    command(0x2c);      //Function set: 4-bit/2-line
    command(0x10);      //Set cursor
    command(0x01);      //Clear Display (Added)
    command(0x06);      //Entry Mode set
    command(0x0c);
}
 
Use the "#" tag
Code:
void command(unsigned char i)
   {
   RS =0;
   R_W =0; //R/W=LOW : Write
   Nybble(i); //Send upper 4 bits
   Nybble(i<<4); //Send lower 4 bits (wrong way round)
   Delay1KTCYx(2); //must wait at least 2mS (2*1000*4/1e6 = 8ms used)
}

void write(unsigned char i)
   {
   RS =1;
   R_W =0; //R/W=LOW : Write
   Nybble(i); //Send upper 4 bits
   Nybble(i<<4); //Send lower 4 bits  (wrong way round)
   Delay1KTCYx(2); //must wait 2mS
   }

Sorry you missed the point..... The code needed changing.. The new code has been pasted
Code:
 Nybble(i<<4); //Send lower 4 bits  (wrong way round)

The shift >> 4... should be << 4... as I have made it.....

Mike has also spotted this error..
 
Last edited:
ohhh :D Thank you so much!!! . My brains have been stuck in asm for so many years. I am so used of rrcf or rlcf .
 
What you have originally written is trying to modify port pins directly. C will try and implemt a "read/modifiy/write" function that will..
1. Not always be possible to read from a port what you have just written. On some micros, there is no read memory element of the output latch.
2. Create race hazards as your data is being presented at the same time as control signals.

You need to send control signals separately. I had this problem on a 68HC11 & ended up using a different port for control signals. I am sure there are better ways to do it now, but I was up against a deadline to finalise a PCB layout.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top