16F88 RB5 UART

Thread Starter

twister

Joined Mar 31, 2009
15
As depicted in the 16F88 data sheet, port B 5 have the built in hardware UART function which made serial transmission easier.



However I am new to assembly language. To have RB5 send serial data, I am trying to modify the code shown as below:

I declare the variable for settling time for start up:
Rich (BB code):
;----------------------
; DECLARE VARIABLES
;----------------------

cblock         0x20
tmp1
endc
and the serial transmission is called:

Rich (BB code):
Ser_sent:
   banksel      SPBRG
   movlw      2580            ; 9.6kbps
   movwf      SPBRG
   movlw      b'00100000'         ; brgh = high (2)
   movwf      TXSTA            ; enable Async Transmission, set brgh

   ; Provide a settling time for startup
   banksel      tmp1
   clrf       tmp1
   settle
   decfsz       tmp1, f
   goto       settle


   ; Send a character through the UART
loop
   movlw      AmpHours
   call      send
   goto      $

;----------------------
; SEND function
;----------------------
send
   banksel      TXREG
   movwf       TXREG            ; Send data which has been stored in W

trans_wt
   banksel      TXSTA
   btfss       TXSTA, TRMT         ; Loop until data is sent
   goto      trans_wt      
   return

   end
The AmpHour is stored previously as:

Rich (BB code):
store_Ah:
	mov16	dd+2,AmpHours
How about the tem1 timing for a baud rate of 9.6kbps suggested? Thanks
 

t_n_k

Joined Mar 6, 2009
5,455
Apologies if I have not understood the question ...

Are you actually asking whether setting SPBRG = 2580 would be correct for a baud rate of 9.6kbps?

If so you need to know the clock frequency.
 

Thread Starter

twister

Joined Mar 31, 2009
15
Apologies if I have not understood the question ...

Are you actually asking whether setting SPBRG = 2580 would be correct for a baud rate of 9.6kbps?

If so you need to know the clock frequency.
Oh yes..u are right. But i am using 4MHZ internal clock, so for 8 bits, I need to use .25 for it.
However i am much more concern on is the code runable....especially my variable that passing the value...the AmpHour.
 

Thread Starter

twister

Joined Mar 31, 2009
15
Is the command "mov16" in the 16F88 assembly instruction set?
mov16 actually is macro defined as follows:
Rich (BB code):
;====================================================================
;               16 bit macros (Big-Endian)
;
mov16	MACRO	src,dst
	movf	src,w
	movwf	dst
	movf	src+1,w
	movwf	dst+1
	ENDM
I just know how to pass the literal value of AmpHour to the W register... but it is useless as i need my register has the value for AmpHour. Any advice? It is urgent...
 

Thread Starter

twister

Joined Mar 31, 2009
15
I'd stored AmpHour(AH) like this:
Rich (BB code):
store_Ah:
	mov16	dd+2,AmpHours
If I want to move it to the W register for transmission...how am i able to call it? Thanks..
 

t_n_k

Joined Mar 6, 2009
5,455
So it looks like AmpHours is a 16bit value. Presumably the first (high or low) byte is stored at a defined register variable AmpHours and the second byte at AmpHours+1....?

Since you can only send one byte at a time through the serial port you would have to move the AmpHours high and low bytes sequentially into WREG and then call the Send routine to send the current (Hi or Lo) byte value.

But - Maybe you already know this - Is your problem that you don't know how to transfer AmpHours to the WREG?
 

t_n_k

Joined Mar 6, 2009
5,455
Hope this isn't too trivial or blatantly obvious - you can use MOVFF anywhere in the 4096 byte data space to move contents of one register to another.

Would ...

MOVFF AmpHours,W

or

MOVFF AmpHours+1,W

be what you intend? Provided AmpHours+1 is allowed in the command.
 

Thread Starter

twister

Joined Mar 31, 2009
15
OK - Have you declared AmpHours as a variable somewhere?
yes.. i declared it as WORD:

Rich (BB code):
; AmpereHours
    WORD    AmpHours ; Amps * Hours
I called AmpHour displayed as this way:
Rich (BB code):
;--------------------------------------------------------------------
;                  Display Amperes * Hours on LCD
;
Show_AmpHours:
    mov16    AmpHours,Number
    call    bin2dec
    movlw    ' '
    call    Print_Char
    call    ShowDec2    ; display "xx.xx"
    movlw    'A'
    call    Print_Char
    movlw    'h'
    call    Print_Char
    return
And AmpHours is calculated as follows:
Rich (BB code):
calc_Ah:
    add1632    Amps,AmpSum    ; AmpSum = accumulated Amps
    mov32    AmpSum,dd
    movi16    3600*3,aa    ; 3 reads per second, 3600 seconds per hour
    call    Div32        ; AmpHours = AmpSum  / (reads per hour)
store_Ah:
    mov16    dd+2,AmpHours

Macros to create variables in RAM

Rich (BB code):
ByteAddr	SET 32     ; user RAM starts here

BYTE		MACRO	ByteName
ByteName	EQU	ByteAddr
ByteAddr	SET	ByteAddr+1
		ENDM

WORD		MACRO	WordName
WordName	EQU	ByteAddr
ByteAddr	SET	ByteAddr+2
		ENDM

LONG		MACRO	LongName
LongName	EQU	ByteAddr
ByteAddr	SET	ByteAddr+4
		ENDM
 

t_n_k

Joined Mar 6, 2009
5,455
Hi twister,

This is getting more complex - I'm no longer sure I can be of any help. Perhaps I don't have a clear understanding of what your question is.

Hopefully someone else might be able to better assist you.

:(
 

Thread Starter

twister

Joined Mar 31, 2009
15
Hi twister,

This is getting more complex - I'm no longer sure I can be of any help. Perhaps I don't have a clear understanding of what your question is.

Hopefully someone else might be able to better assist you.

:(
Sorry....what I want to do is:
Having 16 bits WORDS of AmpHour move to TXREG so that it can transmit serially.
I really need your help as i juz leaving this minor part which i used to figure out for 1 week ady. Thanks and i appreciate ur help.
 

t_n_k

Joined Mar 6, 2009
5,455
I'm not sure whether this will work but try something like ...

1. Add a user variable

cblock 0x20
.
.
.
tx_Bytes ; place of starting byte for 2-byte transmission
endc

2. When AmpHours is evaluated add a line of code

mov16 AmpHours, tx_Bytes ; store the AmpHours value

3. Then to transmit 2 bytes of data

movf tx_Bytes,0 ;transmit high byte valuemoved to WREG
call send
;send the high byte via UART

movf tx_Bytes+1,0
;transmit low byte value moved to WREG
call send ;send the low byte via UART

what I'm not sure about is whether the AmpHours value is the actual 2-byte value you want to send - you mentioned the literal AmpHours passed value in an earlier post as being a problem for you.

If so ...for what it's worth....?

I have found a literal unpacking macro for a 32-bit literal as follows. Here "Var" is the 32 bit literal to be unpacked as four bytes beginning at address location "Address". You could modify the code to a 16-bit unpack macro [Unpack16] with AmpHours assigned to Var and tx_Bytes assigned to Address. Might be useful.

Unpack32 MACRO Var, Address ;Var = 32 bit literal to be unpacked
BANKSEL Address ;Address specifies the LSB start
movlw Address ;Use FSR and INDF for indirect
movwf FSR ;access to desired address
movlw Var & H'FF' ;Mask to get LSB
movwf INDF ;Put in first location
movlw Var >>D'08' & H'FF';Mask to get next byte of literal
incf FSR,F ;Point to next byte
movwf INDF ;Write data to next byte
movlw Var >>D'16' & H'FF';Mask to get next byte of literal
incf FSR,F ;Point to next byte
movwf INDF ;Write data to next byte
movlw Var >>D'24' & H'FF';Mask to get last byte of literal
incf FSR,F ;Point to last byte
movwf INDF ;Write data to last byte
ENDM ;End of the Macro Definition
 

Thread Starter

twister

Joined Mar 31, 2009
15
OK t_n_k, I am gonna do something like this:

I am now having a register called AmpHours, it is a 16-bits binary variable. I am planning to send the content of this via serial transmission to another module. Here, I want to use pin B5 as it is hardware UART built, which is simpler. However I tried the my method but in vain. Hereby I attach the code which I'd implemented. I'd highlighted the part where I added for the serial routine. Hopefully I can get help from you guys as soon as possible. Thanks.

P/S: Until this stage, if i use the code that i attached, it just manage to display the sign on message, and it halts there.
 

Attachments

Top