Serial Communications Demo: Transmitting from the SCI
 
In the SCI overview, we described the basics of how the SCI serial communications port works. In this module, we will follow on from this and create a simple transmit program that transmits the string "El Paso" in an infinite loop from the SCI port. Once the program assembles OK, we will then verify that it works correctly by looking at the output with a logic analyzer. The base code is shown below. You may find it helpful to look at the web page String and Array Addressing to understand how we are using pointers in the code below.
 
      ;****************************************************************
      ;*
      ;* UTEP EE3376
      ;* sci_demo.asm
      ;* 15 July 2005
      ;*
      ;* This program uses the SCI1 serial port to transmit (TX) and
      ;* receive (RX) a string of data at 9600 baud. The program runs
      ;* in an infinite loop, transmitting and receiving characters
      ;* at the same time (with a 2 msec delay between TX and RX frames).
      ;*
      ;* NB: For the Dragon12 board, you MUST set jumper J23 to positions
      ;* 1-2 (URXD1) to connect PS2 header pin to pin P91 of the HCS12.
      ;*
      ;*
      ;* Program can be tested in two modes:
      ;* Single board mode: connect PS3 (TX) to PS2 (RX) with short jumper cable.
      ;* Two board mode: connect VSS2 (grd) of board 1 to VSS2 of board 2
      ;* and then connect PS3 (TX) of board 1 to PS2 (RX) of board 2.
      ;* For either, you can use DBug12 "md 2000" to see the TX and RX strings.
      ;*
      ;* -- only TX code shown, and there is an intentional error in setting up tx_ptr
      ;* -- RX code must be added if needed
      ;*
      ;****************************************************************
 
      ; export symbols
                  XDEF Entry                   ; export 'Entry' symbol
                  ABSENTRY Entry           ;mark this as application entry point
 
 
      PSEUDO_ROM    EQU        $1000    ; absolute address to place code/constant data
      RAM            EQU        $2000    ; absolute address to place variables
      STACK            EQU        $3C00    ; top of stack
 
      ; SCI registers - not all are used in program
      sci1bdh            EQU        $00D0    ; SCI1 Baud Rate Generator, high byte
      sci1bdl            EQU        $00D1    ; SCI1 Baud Rate Generator, low byte
      sci1cr1            EQU        $00D2    ; SCI1 Control Register 1
      sci1cr2            EQU        $00D3    ; SCI1 Control Register 2
      sci1sr1            EQU        $00D4    ; SCI1 Status Register 1
      sci1sr2            EQU        $00D5    ; SCI1 Status Register 2
      sci1drh            EQU        $00D6    ; SCI1 Data Register, high byte
      sci1drl            EQU        $00D7    ; SCI1 Data Register, low byte
 
      ; masks
      enableTX        EQU        $08        ; mask to enable TX
 
      ; constants and mnemonics
      br9600            EQU        $9C        ; BR to set Baud Rate to 9600, 24 MHz clock
      msec            EQU        $1770        ; 6000 (=$1770) loops = 1 msec in startx loop
 
      ;-----------------------------------------------------
      ; variable/data section
          ORG        RAM
 
      tx_string                dc.b    "El Paso"; the string we will output via TX
      tx_ptr             ds.w    1            ; ptr to position in tx_string
 
 
      ;------------------------------------------------------
      ; code section
          ORG            PSEUDO_ROM    ;set PC to $1000
 
      Entry:
 
                    lds        #STACK        ; initialize stack
                    movb    #br9600,sci1bdl        ; set BAUD rate to 9600
                    movb    #enableTX, sci1cr2    ; enable TX
 
              ; loop2 is an infinite loop that resets ptrs and runs loop1        
      loop2:    ldaa           #$07                ; number characters in tx_string
                    movw    tx_string, tx_ptr        ; initialize tx_ptr ->there is an error here!
 
              ; infinitely output tx_string
      loop1:    ldx         tx_ptr
                    jsr        TX_CHAR    ; output char via TX of SCI1
                    jsr        DELAY         ; wait 2 msec between TX
                    inx                               ; update tx_ptr lower byte
                   stx          tx_ptr
                    deca
                    bne        loop1
                    bra        loop2        ; infinite loop
              
                    swi                ; end the program
              
 
      ;------------------------------------------------------
      ; Subroutine TX_CHAR
      ; TX a character from the SCI1 interface
      ; char resides in TX string at address pointed to by X register
      ; the terminology ($2000) refers to the contents of address $2000
      ; so ((X)+0) refers to the contents of address in X + 0, eg ($2000 + 0)
      ; to send contents of an address in X to sci1drl, we must use the 0,x type offset indexed addressing
 
      TX_CHAR:
      spin1:     brclr        sci1sr1, #$80, spin1        ; wait till TDRE set
                      movb        0,x,      sci1drl            ; send ((X)+0) to TX data reg.
                      rts
 
      ;------------------------------------------------------
      ; Subroutine DELAY - y contains number of Delay loops
      ; 1 msec delay per Delay loop    
 
      DELAY:
                      pshy
                      pshx
                      ldy        #$02
      starty:     ldx        #msec
      startx:     dex
                      bne    startx
                      dey        
                      bne    starty
                      pulx
                      puly
                      rts      
 
      ;****************************************************************
 
 
    * Create a new project called "sci_demo" using ee3376 stationery. Cut and paste the code above into a program called "sci_demo.asm" and call the executable "sci_demo.abs.s1".
 
    * Note that there is one subtle mistake in the code concerning how tx_ptr was set up. Look in the "movw tx_string, tx_ptr" statement and think about what value you are really sending to the tx_ptr. Note that tx_string is a synonym for the number $2000, and tx_ptr is a synonym for the number $2007, so the statement is the same as "movw $2000, $2007". Do you want to send the contents of address $2000 or the address $2000 itself to tx_ptr? Correct the mistake and assemble the code.
 
      NOTE: Mistaking the contents of a pointer with a pointer itself (remember, a pointer is an address) is a VERY common error in embedded programming. When you have unusual errors in your programs, try checking that you didn't mistake a pointer for the contents of a pointer or vice versa.
 
    * Hook up a LA2124 logic analyzer to the Dragon12 board. Connect the VSS2 (ground) pin of the Dragon12 to the ground pin of the LA2124, and connect the TX header pin labelled PS3 on the Dragon12 to the channel 0 pin of the logic analyzer. Set the logic analyzer to trigger on Channel 0 logic 0, and set the trigger mode to single. Set the clock to 100 khz (10 usec). Keep the logic analyzer window open. See the logic analyzer demo for a review of how to use the logic analyzer if needed.
 
    * Load the sci_demo.abs.s1 program into the Dragon12 but do NOT start it yet. Go to the logic analyzer window and click on the "Go" description button to start the logic analyzer. Since the TX pin is high and the logic analyzer triggers on a low (logic 0), the logic analyzer will just sit there and wait until the TX pin goes low. Once we start the program on the Dragon12 board and the TXD1 pin goes low, then the logic analyzer will trigger and we will thus capture our first transmission. The trigger is set to "single", so we will only capture this first transmission event.
 
    * Start the sci_demo.abs.s1 program by typing in "g 1000" at the DBug12 prompt. The program will run in an infinite loop until we stop it with the yellow abort button on the Dragon12. Once the program starts, the logic analyzer will trigger and capture the few signals sent out from the TXD1 pin on the Dragon12. Below is a screenshot of what the logic analyzer capture looks like:
 
      
 
      
 
    * Verify that your screenshot looks like that above. You should be able to decode the first few character frames (zoom in if you need to). Note that the actual waveform you see will depend on which string position you captured using the logic analyzer (the string is output in an infinite loop again and again; you may be seeing the "E" or the "a" character of "El Paso", depending on where the string output is when you capture it). In any case, when you decode the waveform, you should get a character which is part of the string "El Paso". If your program did not produce the expected output, go check your code, esp. the tx_ptr setup, and correct it as necessary.
 
    * You can click on the abort button on the Dragon12 to stop the program. To rerun the program from the beginning, hit the reset button of the Dragon12 to reset the program. Hit the "Go" button once on the logic analyzer to arm it for the next capture, and then type in "g 1000" at the DBug2 prompt.
 
    * Your program should run OK if you have followed the above instructions and corrected the pointer mistake noted above. If you are having problems, ask the TA for assistance.
 
 
 
SCI Demo