+ Reply to Thread
Results 1 to 12 of 12

Thread: 8051 microcontroller reading data from serial port

  1. #1
    godatguitar Newbie
    Join Date
    Feb 2004
    Posts
    8

    Default 8051 microcontroller reading data from serial port

    HI All

    I am very new(ish) to 8051's as I have completed some basic work with them in assembler and c, but I am stuck on something now...

    I need to receive some data from the serial port on the 8051. I would prefer to write in C if possible.

    I want to receive some x and y integer (coordinates) from the serial and then move motors to those coordinates. Moving the motors is relatively simple.

    Basically, I do not know if I have to do it character at a time then put them into two seperate variables, like xcoord, ycoord for example.

    main()
    {

    SCON = 0x50; /* mode 1, 8-bit uart, enable receiver */
    TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */
    TH1 = 0xFE; /* reload value for 2400 baud */
    ET0 = 0;
    TR1 = 1; /* start the timer */
    TI = 1; /* clear the buffer */

    ES = 1; /* allow serial interrupts */
    EA = 1; /* enable interrupts */

    P1 = 0; //This is the port for the motors.

    while (1==1)
    {
    int i;
    int j;

    for(i=0; i<xcoord;i++)
    P1 = .......;
    for(j=0;j<ycoord;j++)
    P1 = .......;

    P1 = 0;
    P2 = 0;
    TI = 1; //then transmit a complete signal out of serial
    }


    The code above shows bits of what i have so far (in C). Basically it should set up the 8051 properly.

    Does anyone have any ideas how to read in 2 integers, say 0 to 350, and a end-of-transmission char?

    Please post. or email me at:

    godatguitar@hotmail.com
    Please forgive me if this is totally wrong etc, I am new and learning....


  2. #2
    godatguitar Newbie
    Join Date
    Feb 2004
    Posts
    8

    Default Ignore post above!

    Hey guys,
    My prog now looks like this:


    #include <reg51.h>

    char getCharacter (void);
    void sendCharacter (char);

    main()
    {
    char input; /* variable to hold characters in */

    SCON = 0x50; /* mode 1, 8-bit uart, enable receiver */
    TMOD = 0x20; /* timer 1, mode 2, 8-bit reload */
    TH1 = 0xFE; /* reload value for 2400 baud */
    TR1 = 1;
    TI = 1;

    while (1 == 1) // Do this loop forever.
    {

    input = getCharacter ();
    //Move motors here......
    sendCharacter ('~'); //send complete signal.
    }
    }

    //*********************************
    char getCharacter (void)
    {
    char chr;
    while (RI != 1) {;}

    while(SBUF != '~')
    {
    chr = chr + SBUF;
    }
    RI = 0;
    return(chr);
    }
    //**********************************

    void sendCharacter (char complete)
    {
    while (TI != 1) {;}
    TI = 0;
    SBUF = complete;
    return;
    }

    The bit I am not sure about is the line:

    chr = chr + SBUF;

    Basically, I want to read in an integer that could be up to 3 digits long.
    I am really dumb! (hehe) and not sure how to do this. At the mo I am using char, but should be using int i think, just unsure of how!
    Please help!
    Many thanks

    Paul

  3. #3
    StupidDum Newbie
    Join Date
    Nov 2003
    Location
    Malaysia
    Posts
    242

    Default

    what is the use of "while (TI != 1) {;} "
    in your code, i don't see any change in T1

  4. #4
    Exo
    Exo is offline
    Exo Newbie
    Join Date
    Sep 2003
    Location
    Belgium
    Posts
    1,884

    Default

    A byte (unsigned char) can hold a value between 0 and 255. If these values are good enough for you then you just need to receive 1 byte per coordinate...

    If you need bigger numbers, 16 bit for example (0 - 65535) then you must receive 2 bytes from pc per coordinate and "stick them togheter" again.

  5. #5
    godatguitar Newbie
    Join Date
    Feb 2004
    Posts
    8

    Default

    How do you "stick them back together"?

    If I had two bytes etc, how do i make them one?

    Perhaps (byte1*10) + byte2 ?


    cheers

  6. #6
    Super Moderator Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent
    Join Date
    Nov 2003
    Location
    Derbyshire, UK
    Posts
    29,730

    Default

    Quote Originally Posted by godatguitar
    How do you "stick them back together"?

    If I had two bytes etc, how do i make them one?

    Perhaps (byte1*10) + byte2 ?


    cheers
    If you're sending them as bytes, you would use ByteHigh*256+ByteLow at the PC end to reconstruct the 16 bit value.

    Depending on what you are doing (and how fast it needs to be), it's often easier to send the data as a string of ASCII characters - this way you can simply read it with Hyperterminal and save it to a file, import it directly into a spreadsheet, or anything you want.

  7. #7
    godatguitar Newbie
    Join Date
    Feb 2004
    Posts
    8

    Default

    Ok, I am still having trouble...

    Lets assume I want to read some ascii characters from the serial port, say 4, and convert them into 2 integers where the first 2 received make up the 1st integer, and the 2nd two make up the 2nd integer.
    How do I do that?

    I am reading from SBUF and placing into variables called xcoord1 and xcoord2 (and the same for the y)

    At the moment I just do:

    xcoord1 = SBUF;
    xcoord1 = xcoord1 - 48;

    where 48 from the value in xcoord1 makes the char into the value?

    Is this correct, or am I thinking about it the wrong way.

    many thanks for your help guys...

    Paul

  8. #8
    Super Moderator Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent
    Join Date
    Nov 2003
    Location
    Derbyshire, UK
    Posts
    29,730

    Default

    I can't help you in C, but in Delphi you would use the Val() procedure, simply join the ASCII characters together to make a string and use Val() to convert it to a number. Here's a section of the Delphi helpfile.

    procedure Val(S; var V; var Code: Integer);

    Description

    Val converts the string value S to its numeric representation, as if it were read from a text file with Read.

    S is a string-type expression; it must be a sequence of characters that form a signed real number.

    V is an integer-type or real-type variable. If V is an integer-type variable, S must form a whole number.

    Code is a variable of type Integer.

  9. #9
    godatguitar Newbie
    Join Date
    Feb 2004
    Posts
    8

    Default

    Hey guys....

    Can anyone help me here?

    I am trying to read from SBUF on the 8051 and put it into an integer, so converting ascii to int i suppose...?

    Here is the code that doesnt work atm...

    xcoord1 = (int)SBUF;
    xcoord1 = xcoord1 - 48;

    Am I doing this wrong?
    Cheers

  10. #10
    Super Moderator Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent Nigel Goodwin Excellent
    Join Date
    Nov 2003
    Location
    Derbyshire, UK
    Posts
    29,730

    Default

    Quote Originally Posted by godatguitar
    Hey guys....

    Can anyone help me here?

    I am trying to read from SBUF on the 8051 and put it into an integer, so converting ascii to int i suppose...?

    Here is the code that doesnt work atm...

    xcoord1 = (int)SBUF;
    xcoord1 = xcoord1 - 48;

    Am I doing this wrong?
    Cheers
    I would have thought so!.

    I've told you how to do it in Delphi, surely C has similar string handling facilities?. As I mentioned before, I can't help you with C - but Delphi, Pascal, and BASIC all have this facility - I can't believe C doesn't!.

    How about something like this?, which I just downloaded off a C tutorial, it reads a string then a number from a file directly into the relevent variables - as I understand it you can read the serial port in the same way?.

    Code:
        /* Open file for input */
        ifp = fopen(ifilename,"r");
    
        /* Read data */
        fscanf(ifp,"%s %d",name,&idNum);
    

  11. #11
    bmcculla Newbie
    Join Date
    Sep 2003
    Location
    California, USA
    Posts
    898

    Default

    C does have functions for working with strings (string.h or something similar. function is called atoi I beleive) but its probably better to just write a small section of code to do this yourself.

    Are you sure the value in SBUF is being recieved correctly? Try just echoing the character back through RS232.

    What value ends up in xcoord1? Try using unsiged ints; the 8051 doesn't have any instructions that deal with signed ints so the compiler has to add a bunch of code. This looks like a type issue.

    Try:

    xcoord1 = (unsigned int)(SBUF - 'a');

    You could also try casting the 48: xcoord = xcoord - ((int) 48 ); This will force the compiler to treat the 48 as an int and not as its default.

    You could also try scanf. I have been avoiding it because it wastes a lot of time.


    Brent

  12. #12
    godatguitar Newbie
    Join Date
    Feb 2004
    Posts
    8

    Default Cheers!

    Thanks guys...

    I was right with what I was doing, but the keil software simulation wasnt working correctly for some reason.
    I changed the software for a version i was familiar with, and ran the program and it worked!

    Cheers for all your help...

    Now all i gotta do is try and control some stepper motors! I am going to need a buffer circuit/motor driver for this, if anyone has any good pointers let me know!

+ Reply to Thread

Tags for this Thread