Skip to content

High speed RS232 for PIC

Table 2 . Timing errors

  4 MHz 10 MHz
equal aligned UART equal aligned UART
57600 19% 2.7% 8.5% 8% 1.0% 1.4%
115200 33% 5.1% 8.5% 12% 2.3% 8.5%
230400 71% 8.8% 8.5% 12% 4.1% 9.6%
460800 71% 23% 71% 8.3%
921600 95% 16%

Considering 10% error in bit timing as acceptable we may make conclusion that the bit alignment is required starting from baud rate 57600 @ 4 MHz and 115200 @ 10 MHz.

Slowly emerging

Now let us try to apply this approach to lower speeds. With 115200 we get cycle lengths 9 8 9 9 8 9 9 8 9. So, sending the start bit may be the very first instruction and all preparation may be done while expiring the start bit.

bcf port, 0 ; 0: sending start bit
movwf data ; 1: put data to rotation buffer
rrf data, W ; 2: prepare data for output:
xorwf data, F ; 3: '1' in DATA means toggle port
movlw 1 ; 4: load port-toggling mask
delay 3 ; 5, 6, 7
skpnc ; 8: first bit is already in C
xorwf port, F ; 9: send bit 0
delay 6 ; 10, 11, 12, 13, 14, 15
btfsc data, 0 ; 16: test data
xorwf port, F ; 17: send bit 1
delay 7 ; 18, 19, 20, 21, 22, 23, 24
...
xorwf port, F ; 78: send bit  7
delay 8 ;
bsf port, 0 ; 87: sending stop bit
return ; Routine length 30 words

Four delay intervals are needed: 3, 6, 7 and 8. We still cannot use a counter for measuring delays because loading the counter would discard the port-toggling mask. Call to a subroutine takes at least 4 IC, so we may declare a subroutine with three entrees that, along with calls to d8, d7, d6, will implement these delays:

d8 nop    
d7 nop    
d6 goto $+1  
  return   ; Routine length 4 words

Next in the list is 57600 with cycle lengths 17 18 17 17 18 17 18 17 17. The bit length is already long enough to use loop. However, this loop should also use some kind of aligning. What code may give us desired results? The following sequence is executed in 3 or 4 IC, depending on the content of align file:

  rrf align, F ; 1: rotate align bits
  skpnc   ; 2: align if indicated by C
  goto $+1 ; 3: this instruction alings the cycle

Thereby, if we make a loop of 17 IC long and put B’001010010′ into align, we get bit lengths as required. We also have to change the way we test data bit. Previously used btfsc data,<i> will not work in the loop, so data should be rolled bit by bit into C. This requires changing data preparation. In previous examples our code places bit 0 into carry, now all bits must be in the file register. Considering all this, the routine will look like:

  bcf port, 0 ; 0: sending start bit
  movwf data ; 1: put data to rotation buffer
  clrc   ; 2: C will be rolled in, so clear it
  rlf data, W ; 3: prepare data for output
  xorwf data, F ; 4: '1' in DATA means toggle port
  movlw .8 ; 5: load bit count
  movwf count ; 6: into counter
  movlw B'00101001' ; 7: load alignment bits, not including start bit
  movwf align ; 8: load to alignment rotation file
  delay 5 ; 9, 10, 11, 12, 13
_bit movlw ; 14: load port-toggling mask
  rrf data, F ; 15: put data bit into C
  skpnc   ; 16: test data bit
  xorwf port, F        ; 17: send bit
  rrf aling, F ; 1: rotate align bits
  skpnc   ; 2: align if indicated
  goto $+1 ; 3: this instruction alings the cycle
  delay 7 ; 4, 5, 6, 7, 8, 9, 10
  decfsz count,F  ; 11: counting bits
  goto _bit ; 12:
stop delay 4 ; 13, 14, 15, 16
  bsf port, 0 ; 17: sending stop bit
  return   ; Routine length 23 words

The shortest bit length we may achieve with this loop is 10 instruction cycles. One may notice, that movlw 1, being placed out of the loop, would make it even shorter: 9 cycles. However there is a reason to keep it inside of the loop, which I’ll tell in the next chapter.

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*

*

This blog is protected by dr Dave\'s Spam Karma 2: 203 Spams eaten and counting...