Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

8051 serial transmission - loosing characters problem

Status
Not open for further replies.

Isuru Senarath

Member level 2
Joined
Apr 10, 2012
Messages
42
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,580
Hi all, I am using 4x4 keypad,16x2 LCD display and 8051 micro controller to send numbers to the serial port. It works fine in ISIS Proteus 7.2, but when I use the same program in my hardware, some of the numbers which I entered from the keypad is missing when transmission. What is the reason for loosing characters when using serial transmission?
 

Code:
lcd_data_string("Serial Tx");
        Delay(40);
        lcdcmd(0x01);  //clear screen
        Delay(10);
        len = strlen(msg);
        for(i=0;i<len;i++)
        {
                lcddata(msg[i]);
                Delay(10);
        }
        lcdcmd(0x0C0);                                                //Move to Second Line of the LCD
        COL =  0x0FF;                                                //Make Port-2 as Input Port
        while(1)                                                                //Infinite Loop
        {
                do
                {
                        ROW = 0x00;                                                //Groud all Row's
                        colLoc = COL;                                        //Read all the Columns
                        colLoc = colLoc & 0x0F;                        //Mask the Unused Bits.
                }while(colLoc != 0x0F);                         //Check until all the Keys are released
                do
                {
                        do
                        {
                                Delay(2);                                        //20msec delay
                                colLoc = COL;                                //Read all the Columns
                                colLoc = colLoc & 0x0F;                //Mask the Unused Bits.
                        }while(colLoc == 0x0F);                         //Keep Checking for Key-press
                        //It may be possible that this key-press may be due to some noise-spikes in the circuit
                        //thats why we will check once again whether the same key is pressed or not.
                        //If not the whole loop will be executed once again
                        Delay(2);
                        colLoc = COL;                                        //read all columns
                        colLoc = colLoc & 0x0F;                        //Mask the Unused Bits.
                }while(colLoc == 0x0F);                                //Wait for the Key-Press

                while(1)
                {
                        ROW = 0x0FE;                                        //Ground First Row
                        colLoc = COL;
                        colLoc = colLoc & 0x0F;                        //Mask the Unused Bits.
                        if(colLoc != 0x0F)                                //1111 Column Detected
                        {
                                rowLoc = 0;                                        //1st Row Selected
                                break;
                        }

                        ROW = 0x0FD;                                        //Ground Second Row
                        colLoc = COL;
                        colLoc = colLoc & 0x0F;                        //Mask the Unused Bits.
                        if(colLoc != 0x0F)                                //Column Detected
                        {
                                rowLoc = 1;                                        //2nd Row Selected                                
                                break;
                        }

                        ROW = 0x0FB;                                        //Ground Third Row
                        colLoc = COL;
                        colLoc = colLoc & 0x0F;                        //Mask the Unused Bits.
                        if(colLoc != 0x0F)                                //Column Detected
                        {
                                rowLoc = 2;                                        //3rd Row Selected
                                break;
                        }

                        ROW = 0x0F7;                                        //Ground Fourth Row
                        colLoc = COL;
                        colLoc = colLoc & 0x0F;                        //Mask the Unused Bits.
                        if(colLoc!= 0x0F)
                        {
                                rowLoc = 3;                                        //4th Row Selected
                                break;
                        }
                }

                if(colLoc == 0x0E)                                  //1110 This means that First column is Selected
                {
                        SerTX(keypad[rowLoc][0]);
                }
                else if(colLoc == 0x0D)                        // 1101         This means that Second column is Selected
                {
                        SerTX(keypad[rowLoc][1]);
                }
                else if(colLoc == 0x0B)                         // 1011 This means that 3rd column is Selected
                {
                        SerTX(keypad[rowLoc][2]);
                }
                else if(colLoc == 0x07)                          // 0111  This means that 4th column is Selected
                {
                        SerTX(keypad[rowLoc][3]);
                }

                //lcdcmd(0xC0);        //Second Row
                
                        //Check Columns and send the Data to the LCD Screen:-
                        if(colLoc == 0x0E)                                  //1110 This means that First column is Selected
                        {
                                lcddata(keypad[rowLoc][0]);
                        }
                        else if(colLoc == 0x0D)                                         // 1101 This means that Second column is Selected
                        {
                                lcddata(keypad[rowLoc][1]);
                        }
                        else if(colLoc == 0x0B)                                         //  1011 This means that 3rd column is Selected
                        {
                                lcddata(keypad[rowLoc][2]);
                        }
                        else if(colLoc == 0x07)                                         //  0111  This means that 4th column is Selected
                        {
                                lcddata(keypad[rowLoc][3]);
                        }

void lcdcmd(unsigned char value)
{
        LcdData = value;
        RS = 0;
        RW = 0;
        EN = 1;
        Delay(1);
        EN = 0;
}
void lcddata(unsigned char value)
{
        LcdData = value;
        RS = 1;
        RW = 0;
        EN = 1;
        Delay(1);
        EN = 0;
}
void Delay(unsigned int itime)                 // void Delay(unsigned int itime)
{
        unsigned int i,j;                                         //unsigned int i,j;
        for(i=0;i<600;i++)                                 //for(i=0;i<1275;i++)
        for(j=0;j<itime;j++);
}
void SerTX(unsigned char x)
{
        SBUF = x;
        while(TI == 0);
        Delay(10);
        TI = 0;
}

void lcd_data(unsigned char item)                // Function to send one byte data to LCD
{
        LcdData = item;
        RS= 1;
        RW=0;
        EN=1;
        Delay(1);
        EN=0;
        return;
}

void lcd_data_string(unsigned char *str)        // Function to send string to LCD
{
        int i=0;
        while(str[i]!='\0')
        {
                lcd_data(str[i]);
                i++;
                Delay(10);
        }
        return; 
}



void SMSString(unsigned char* text) //function to send SMS using GSM modem
{
        while (*text)
        {
                SerTX(*text++);
        }
}
 

What is the delay in seconds for Delay(x), it might be too long. If the code is busy with the TX delay it won't catch the buttons you press on the keypad.
 

10 m.seconds. I reduced the delay, but problem is same as previous
 

I didn't check... In a bit of a hurry. For the 8051 you should write to a port before reading it.
If the cables to your keypad is very long, you should wait a moment between the writing and reading.
 

Cable is not too long, only 5cm. I didn't got what you said, could you please explain it more (For the 8051 you should write to a port before reading it.)
Code:
void SerTX(unsigned char x)
{
        SBUF = x;
        while(TI == 0);
        Delay(10);
        TI = 0;
}
You are telling me to change the delay?
 

In the keypad... For example.

Code:
short column1 = 0x00;   // Place to store values read from the port

// Reading a value.

// Assume your port is configured for inputs
PORT |= 0xFF;   // Write to all
Delay(1); // Delay a very short time (long cables, longer delay)
column1 = PORT; // Read from all.

The above might be in the datasheet, cant remember
Had a similar problem reading from a 8051 at some point.
 

If it's (a) a true 8051 or (b) a variant with ports set in quasi-bidirectional mode then the port needs to have FFh written to it before any reads take place.
 

Also your code is truncated, so hard to see what you do after you've scanned for the first keypress and printed and transmitted it.
Also, not sure why your row scanning has a while(1) loop. You should just test once, since you've already done the debounce. If you find no
row hit, then that means that the button was released just after the debounce (i.e. at the column stage), so don't print or transmit in that case.
Also, Delay(10) may be quite long (I don't know), so if some poor guy presses a key while the your'e delaying after during the serial char tx, then
that key will never get detected no matter how long they press the button, because of the very first do loop that is in the code pasted.
You might want to use an LED to debug - i.e. insert some commands to light up the LED to figure out roughly where in the code you are when buttons
are pressed that are not being transmitted.
 

I can see what I typed from the LCD. LCD will show what I typed using keypad correctly. Problem Is with the serial transmission. Some of the characters which I typed lost when serial transmission, but it will be on display. Can't find the trouble yet, need some guidance with feedback
 

What bitrate are you using, and are you using a crystal? Might need to paste your cct diag.
It may be a problem with your RS232 hardware, or a problem at the other end (I'm assuming your TX routing is fine, since it is so brief - I'm not very familiar with these processors).
 

I am using 4800bps for serial communication, and 11.0592MHz crystal
 

Assuming you've set things up ok regarding bitrate in your microcontroller, then it could be a problem with your RS232 level converter hardware or your remote end - what is it, a PC? What software? Try hyperterm, it is awful but guaranteed to work at least. Also, try a more common speed (9600,8,N,1) in case it is a software issue at the other end.
If all that fails, then you need to use a scope and examine what is going on over the serial lines.
 

My program is to send sms using a keypad, (similar to the operation of the phone) I can't change the bit rate because my GSM modem works on that bit rate. All the setup is ok, when I write a code something like(If I press a key, Tx string of characters Ex: If key 1 is pressed >> Transmit serial port to word "Step 1") it is working fine. But If I a code for an example : If key to is pressed >> Transmit every character which I type from keypad, it will only transmit some of the characters, But LCD display will show what I typed correctly,

If I send a string of characters to serial port, It works fine, When I entered text from keypad, some of the keys what I entered is lost during ONLY serial transmission. But LCD will display what I entered correctly?
 

I think it's still worth checking with a PC first, and then trying with the modem. How do you know that the GSM modem is flushing on a
single char? Maybe it waits for a few chars. (I don't know, I'm guessing, I've never used one). Also, Is the modem connected (i.e. transmitting)
when you're pressing the buttons? Because it may be impacting the signal levels intermittently (e.g. maybe RF pickup).
For these reasons, better to confirm with a PC first, or at least try to see with an oscilloscope. Have you tried that? Sounds like
it's unlikely to be a code issue at this stage...
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top