This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Serial Communication w/ AT89C51 or AT89C52

I want to have a simple program to print something out using hyperterminal. Also it would be nice to receive a character and echo it back. I have been able to do this in assembly but I can't get it to work in C. Here is the latest code I have tried:

#include <AT89X51.H> 
#include <CTYPE.H>
#include <STDIO.H>

int i;

void main()
{
SCON = 0x50; //SCON: mode 1, 8-bit UART, enable rcvr
TMOD = 0x20; //TMOD: timer 1, mode 2, 8-bit reload 
TH1 = 0xFD; //TH1: reload value for 9600 baud @ 11.0592MHz 
TR1 = 1; //TR1: timer 1 run 
TI = 1; //TI: set TI to send first char of UART 

while (1) 
{
P1 ^= 0x01; 
printf ("\n\nHello World\n\n"); 
i = _getkey();
putchar('$');
putchar(i); 
}
}

Is there anything wrong with my code? Or is there something in how I am compiling? I am confident my hardware is fine because I can get it to work in assembly. Any help would be appreciated. Thank you.

Parents Reply Children
  • Thanks for the suggestion. The 'standard' SBUF is fine with me, and I'm not trying to do anything with interrupts yet. Do I need to include any header files or link with some source files when I compile?

  • These are the signatures of putchar and getkey;

    char putchar (char c);
    char _getkey ();

    neither Function returns, unless the character is read/written

    You might use your assembler routines wihtin these Templates:

    ?PR?PUTCHAR?PUTCHAR SEGMENT CODE
       RSEG ?PR?PUTCHAR?PUTCHAR
    PUBLIC (_PUTCHAR)
    _PUTCHAR:
      ;; output a Character and don't return, until the character
      ;; is output.
      ;; when invoked from C, the 
      ;; character will be passed in Register R7
    
      ;; Your Assembly Code here
    
      MOV R7,#<the caharcter you actually wrote> ;; return value
    RET
    

    ?PR?_GETKEY?GETKEY SEGMENT CODE
       RSEG ?PR?_GETKEY?GETKEY
    PUBLIC (_GETKEY)
    _GETKEY:
      ;; get a Character and don't return, until the character
      ;; is input.
      ;; when invoked from C, the 
      ;; character will be expected in Register R7
    
      ;; Your Assembly Code here
    
      MOV R7,#<the caharcter you actually wrote> ;; return value
    RET
    


    BEWARE!! 1st: I din't test it
    BEWARE!! 2nd: Applies to my Dinosaur C51 COMPILER V5.10's
    Argument passing conventions

    Good Luck

    Norbert

  • ... something:

    of course include these Declarations:

    extern char putchar (char c);
    extern char _getkey ();
    

    either via a header file or directly into your c-File.

    I'm also not sure about the underscore-Character in
    _getkey:

    The name of a function (i.e. it's assembly-label),
    that passes values via Registers is prefixed by an
    underscore character.

    _putchar is correct, but I guess
    _getkey must be labelled __getkey
    with two underscores:
    one for the name and
    one for the non void-void-signature property.

    If I remember well, then - let
    T
    be a
    non-void type specifier -
    T function (void);
    must also be labelled
    _function:

    I'm at home now, so I cannot look it up in the manual.

    Norbert

  • I included <stdio.h> in my code. I found the declarations in that header file. Will this take care of that problem. Also do I need to add the header files I use to my source group or another group on the left of the window? Thanks for the help.
    Jake

  • "...do I need to add the header files..."

    No, you don't need to add them.
    However, you might find it useful to add them; eg, to give quick access to open a frequently-used header. In that case, you'd need to clear the 'Include in Build' option - otherwise uVision will try to separately compile your header(s)!!

  • stdio.h will do.

    You can understand the #include - control as a substitute of
    pasting the Text of the included File into the including module.

    The preprocessor of C doesn't anything else.

    If you costumize the functions, you must add your
    custom object file(s) to the list of objects to be linked.

    You're maybe talking about the "left window" of your IDE.
    I don't use an IDE for 8051 Projects. I just hack the text into
    files, using a text editor. Then invoke compiler and linker directly
    via Windows-Explorer and entries in the Registry:

    [HKEY_CLASSES_ROOT\c_auto_file\shell\C51-Compiler_Emulator\command]
    @="C:\\C51\\BIN\\C51.EXE  %1 DEFINE ( TEST_CODE = 1 ) OE PP"
    

    Norbert

  • I reviewed the messages and am not sure whether you tried stepping into your C program using the simulator. I have found this a good tool for both the asynch serial comm and the clocks. The simulator will show you how you have set the baud and will display sbuf.

    Run the simulator with your assy code and record the ports' setup bits. Run again with your C code and compare the ports' setup bits. This may allow you to confirm if you are setting up the ports properly.