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

SW and HW UART

Hi All!
Any good example for software UART (SW) and retranslate data between SW and hardware (HW) UART on C51 using C - Keil Compiler? Using EXT0 Interrupt as receiver datect for "SW" Uart ?

  • Who cares about good examples of sw UART, when there exists chips with multiple hw UART?

    You need a low baudrate if you want anything else to happen while that sw UART is busy sampling the data line.

  • I've this Software but have a problem with INT0 interrupt or "getc()" function when I send data to SW-UART.

    code:

            //Second SW-ASYNC.UART USING INT0 as detect RX data(start bir)
    
            #include <stdio.h>
            //#include <AT89C51RC2.H>
            #include <at89c51xD2.h>  //AT89c51ED2
            #include "softuart.h"
    
            #define buff_size       16
    
            unsigned char t;
            bit     flag_sw_isr;
            unsigned char xdata test_buff[8]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37};
     ////////////////////////////////////////////////////////////////////////////////////////
              unsigned char xdata  rx_sw_buffer[buff_size];
              unsigned char index_sw = 0;
     /*External ISR Rutine*/
              void ext_int0_isr (void) interrupt 0
              {
                    flag_sw_isr=0;
                    rx_sw_buffer[index_sw]= getc();
                    if(++index_sw==buff_size)
                    {
                            index_sw=0;
                    }
                    flag_sw_isr=1;
              }
     /*Delay n-ms time.----------------------------------*/
              void delay_ms(unsigned char ms)
              {
                    unsigned int x,y;
                    for(x=0;x<ms;x++) for(y=0;y<1275;y++);
              }
    
    void main(void){
    
        delay_ms(50);
            index_sw=0;
     /*EXT_0 ISR Config bits --------------------------------------------------------*/
            IT0 = 1;   // Configure interrupt 0 for falling edge on /INT0 (P3.2)
            EX0 = 1;   // Enable EX0 Interrupt
            EA = 1;    // Enable Global Interrupt Flag
     /*------------------------------------------------------------------------------*/
    
            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;
    
            printf("1-HW UART;2-SW UART DEMO\n\r");
            printf("test_2 UART_0\n\r");
    
            for(t=0;t<8;t++)     //for testing SW putc() func.
            {
                    putc(test_buff[t]);
            }
            flag_sw_isr=1;
        while(1)
            {
                    unsigned char i;
                    delay_ms(100);
                    if(flag_sw_isr)
                    {
                            for(i=0;i<16;i++)
                            {
                                    putchar(rx_sw_buffer[i]);
                            }
                    }
        }
    }
    //==============================softuart.h====================================
    #ifndef __SOFTUART
    
    #define __SOFTUART
    
    void putc(unsigned char);
    unsigned char getc(void);
    
    #endif
    //========================softuart.asm=========================================
    
    ?SU?PUTC SEGMENT CODE
    ?SU?GETC SEGMENT CODE
    
    PUBLIC _putc
    PUBLIC getc
    
    txd_pin EQU     P3.4            ;Transmit on this pin
    rxd_pin EQU     P3.2            ;Receive on this pin
    
    ;Formula to calculate the bit time delay constant
    ;This constant is calculated as: (((crystal/baud)/12) - 5) / 2
    ;crystal is the frequency of crystal in Hz
    ;baud is required baudrate
    ;Please try to keep baudrate below 9600
    ;to get best results :)
    
    BITTIM  EQU     45;             (((11059200/9600)/12) - 5) / 2
    
    ;--------------------------------------------
    ;To send data serially
    ;For C programs
    ;Protype definition:
    ;               void putc(unsigned char);
    ;Usage:
    ;               putc(data);
    ;Return:
    ;               This function returns nothing
    ;
    ;For Assembly Programs:
    ;
    ;Usage:
    ;       data to be send has to be moved to R7
    ;       for example:
    ;               mov R7,#'a'
    ;               lcall _putc
    ;--------------------------------------------
    RSEG ?SU?PUTC
    _putc:
            push ACC
            Push PSW
            mov a,r7
            CLR txd_pin                     ;Drop line for start bit
            MOV R0,#BITTIM          ;Wait full bit-time
            DJNZ R0,$                       ;For START bit
            MOV R1,#8                       ;Send 8 bits
    putc1:
            RRC A                           ;Move next bit into carry
            MOV txd_pin,C           ;Write next bit
            MOV R0,#BITTIM          ;Wait full bit-time
            DJNZ R0,$                       ;For DATA bit
            DJNZ R1,putc1           ;write 8 bits
            SETB txd_pin            ;Set line high
            RRC A                           ;Restore ACC contents
            MOV R0,#BITTIM          ;Wait full bit-time
            DJNZ R0,$                       ;For STOP bit
            POP PSW
            pop ACC
            RET
    
    ;--------------------------------------------
    ;To receive data Serially
    ;If you want to use this routine in your
    ;C program then define function prototype
    ; as:
    ;       unsigned char getc(void);
    ;
    ;       Usage:
    ;               data = getc();
    ;       Return value:
    ;               Returns data received
    ;
    ;
    ;If you are using it in assembly program
    ;       Usage:
    ;               lcall getc
    ;       Return:
    ;               data received is stored in R7
    ;--------------------------------------------
    
    RSEG ?SU?GETC
    getc:
            Push ACC
            Push PSW
            JB rxd_pin,$            ;Wait for start bit
            MOV R0,#BITTIM/2        ;Wait 1/2 bit-time
            DJNZ R0,$               ;To sample in middle
            JB rxd_pin,getc         ;Insure valid
            MOV R1,#8               ;Read 8 bits
    getc1:
            MOV R0,#BITTIM          ;Wait full bit-time
            DJNZ R0,$               ;For DATA bit
            MOV C,rxd_pin           ;Read bit
            RRC A                   ;Shift it into ACC
            DJNZ R1,getc1           ;read 8 bits
            mov r7,a
            POP PSW
            pop ACC
            RET                                     ;go home
                    END
    
    

  • I've some hardware which I want to use it.

  • And what problem, exactly, do you have?

  • When I send data to SW UART (P3.2)INT0 at89c51ed2 "Block" and do nothing until I make RESET or Power OFF -> ON!

  • Agree with Per, HW solutions should be used. However, if possible.
    If it is just for fun and not a commercial product, why not?
    But I do not like those endless discussions on forums, there will
    be always different opinions, so you may send an personal email
    to embedded-world at home dot se. For some questions I do have.
    If it helps, o.k., if not, also o.k.
    Best regards.

  • I've some hardware which I want to use it
    I have a shoe and want to pound a nail into my wall.

    If it is just for fun and not a commercial product, why not?
    because the "learning value" is a big fat ZERO

    But I do not like those endless discussions on forums, there will
    be always different opinions

    well, if there were not "different opinions" why have a "discussion forum"

    Some read the forum title and assume it reads "solution providing place". Where a 'discussion' most likely will provide help, providiong nicely boxed shrink wrapped solutions is not the purpose.

    Erik

  • Not at all!

    Implementing a UART in software requires understanding a lot of things which will be of general use - not least, how a UART actually works!