EmbeddedRelated.com
Forums
Memfault Beyond the Launch

Serial I/O on the 16F628

Started by jrem November 16, 2004

Guys/Gals:

I can't seem to get the tx i/o to flip. I could spend endless hours
screwing with the hardware (since MPLab doesn't support serial
functions) or I could ask the infinite intellegence (i.e., you the
group) for direction. I choose the latter.

Here is my code, all I want to see is that tx i/o flip on my scope.
The counter just makes the bits change so I know it's alive.

I'm sure it's something stupid, but not having done this before I
could sure use some help.

TIA, John. ;==============================
list pF628
__config h'3d31' ; XT oscillator
radix hex
include <p16f628.inc>

byte equ 1
word equ 2
cblock 0x20
count1 :byte
endc ; end c block

org 0x000 ; program memory at reset vector 0x000
reset
goto setup ; set up ints and port stuff
org 0x004 ; Interrupt vector, int handler code next

;==============================
; setup routine
;==============================

setup
movlw b'00000111' ; turn off analog I/O
movwf CMCON
movlw b'00000000' ; turn off interrupt
movwf INTCON
bcf STATUS, RP1
BSF STATUS, RP0 ; switch bank
MOVLW 0XFF ; set port A to inputs
MOVWF TRISA
movlw b'00000110' ; set port B to outputs, tx/rx on
movwf TRISB
BCF STATUS, RP0
clrf PORTA
clrf PORTB

;==============================
; Main Loop
;==============================

main
bsf RCSTA,7 ; set SPEN
bsf TRISB,2 ; rx/tx output
bsf TRISB,1
bsf TXSTA,3 ; BRGH high
movlw b'00011001' ; dec25
movwf SPBRG ; set baud rate
bcf TXSTA,4 ; clr SYNC
bsf RCSTA,7 ; set SPEN
bsf TXSTA,5 ; set TXEN

incf count1, f
movlw count1
movwf TXREG

main2 btfss PIR1,4
goto main2
goto main

;==============================
; End
;==============================

end




I haven't worked through all the code but at main RP0 = 0 and RP1 = 0 and
you are writing to TRISB which is in bank 1 (I cannot remember where the
other SFRs live off the top of my head), then further down in main you
access count1 which is in bank 0. I think you should go over your code
paying careful attention to which bank each of the registers (and SFRs) are
in and ensure that RP0 and RP1 are set correctly.

Regards
Sergio Masci

http://www.xcprod.com/titan/XCSB - optimising PIC compiler
FREE for personal non-commercial use
----- Original Message -----
From: jrem <>
To: <>
Sent: Tuesday, November 16, 2004 2:13 PM
Subject: [piclist] Serial I/O on the 16F628 >
>
> Guys/Gals:
>
> I can't seem to get the tx i/o to flip. I could spend endless hours
> screwing with the hardware (since MPLab doesn't support serial
> functions) or I could ask the infinite intellegence (i.e., you the
> group) for direction. I choose the latter.
>
> Here is my code, all I want to see is that tx i/o flip on my scope.
> The counter just makes the bits change so I know it's alive.
>
> I'm sure it's something stupid, but not having done this before I
> could sure use some help.
>
> TIA, John. > ;==============================
> list pF628
> __config h'3d31' ; XT oscillator
> radix hex
> include <p16f628.inc>
>
> byte equ 1
> word equ 2
> cblock 0x20
> count1 :byte
> endc ; end c block
>
> org 0x000 ; program memory at reset vector 0x000
> reset
> goto setup ; set up ints and port stuff
> org 0x004 ; Interrupt vector, int handler code next
>
> ;==============================
> ; setup routine
> ;==============================
>
> setup
> movlw b'00000111' ; turn off analog I/O
> movwf CMCON
> movlw b'00000000' ; turn off interrupt
> movwf INTCON
> bcf STATUS, RP1
> BSF STATUS, RP0 ; switch bank
> MOVLW 0XFF ; set port A to inputs
> MOVWF TRISA
> movlw b'00000110' ; set port B to outputs, tx/rx on
> movwf TRISB
> BCF STATUS, RP0
> clrf PORTA
> clrf PORTB
>
> ;==============================
> ; Main Loop
> ;==============================
>
> main
> bsf RCSTA,7 ; set SPEN
> bsf TRISB,2 ; rx/tx output
> bsf TRISB,1
> bsf TXSTA,3 ; BRGH high
> movlw b'00011001' ; dec25
> movwf SPBRG ; set baud rate
> bcf TXSTA,4 ; clr SYNC
> bsf RCSTA,7 ; set SPEN
> bsf TXSTA,5 ; set TXEN
>
> incf count1, f
> movlw count1
> movwf TXREG
>
> main2 btfss PIR1,4
> goto main2
> goto main
>
> ;==============================
> ; End
> ;==============================
>
> end




I was wondering about that, thanks, I knew it was something stupid.
--- In , "sergio masci" <smypl@x> wrote:
> I haven't worked through all the code but at main RP0 = 0 and RP1 =
0 and
> you are writing to TRISB which is in bank 1 (I cannot remember
where the
> other SFRs live off the top of my head), then further down in main
you
> access count1 which is in bank 0. I think you should go over your
code
> paying careful attention to which bank each of the registers (and
SFRs) are
> in and ensure that RP0 and RP1 are set correctly.
>
> Regards
> Sergio Masci
>
> http://www.xcprod.com/titan/XCSB - optimising PIC compiler
> FREE for personal non-commercial use >
> ----- Original Message -----
> From: jrem <jrem123@y...>
> To: <>
> Sent: Tuesday, November 16, 2004 2:13 PM
> Subject: [piclist] Serial I/O on the 16F628 > >
> >
> > Guys/Gals:
> >
> > I can't seem to get the tx i/o to flip. I could spend endless
hours
> > screwing with the hardware (since MPLab doesn't support serial
> > functions) or I could ask the infinite intellegence (i.e., you the
> > group) for direction. I choose the latter.
> >
> > Here is my code, all I want to see is that tx i/o flip on my
scope.
> > The counter just makes the bits change so I know it's alive.
> >
> > I'm sure it's something stupid, but not having done this before I
> > could sure use some help.
> >
> > TIA, John.
> >
> >
> > ;==============================
> > list pF628
> > __config h'3d31' ; XT oscillator
> > radix hex
> > include <p16f628.inc>
> >
> > byte equ 1
> > word equ 2
> > cblock 0x20
> > count1 :byte
> > endc ; end c block
> >
> > org 0x000 ; program memory at reset vector 0x000
> > reset
> > goto setup ; set up ints and port stuff
> > org 0x004 ; Interrupt vector, int handler code next
> >
> > ;==============================
> > ; setup routine
> > ;==============================
> >
> > setup
> > movlw b'00000111' ; turn off analog I/O
> > movwf CMCON
> > movlw b'00000000' ; turn off interrupt
> > movwf INTCON
> > bcf STATUS, RP1
> > BSF STATUS, RP0 ; switch bank
> > MOVLW 0XFF ; set port A to inputs
> > MOVWF TRISA
> > movlw b'00000110' ; set port B to outputs, tx/rx on
> > movwf TRISB
> > BCF STATUS, RP0
> > clrf PORTA
> > clrf PORTB
> >
> > ;==============================
> > ; Main Loop
> > ;==============================
> >
> > main
> > bsf RCSTA,7 ; set SPEN
> > bsf TRISB,2 ; rx/tx output
> > bsf TRISB,1
> > bsf TXSTA,3 ; BRGH high
> > movlw b'00011001' ; dec25
> > movwf SPBRG ; set baud rate
> > bcf TXSTA,4 ; clr SYNC
> > bsf RCSTA,7 ; set SPEN
> > bsf TXSTA,5 ; set TXEN
> >
> > incf count1, f
> > movlw count1
> > movwf TXREG
> >
> > main2 btfss PIR1,4
> > goto main2
> > goto main
> >
> > ;==============================
> > ; End
> > ;==============================
> >
> > end





John,

I made a few changes but didn't rewrite the code. It looks like it
should work but I didn't test it. If it is still a problem, post
back and I'll run it on a proto board. I can't test the XT
oscillator configuration - my board is set for 20 MHz.

Richard

--- In , "jrem" <jrem123@y...> wrote:
>
> Guys/Gals:
>
> I can't seem to get the tx i/o to flip. I could spend endless
hours
> screwing with the hardware (since MPLab doesn't support serial
> functions) or I could ask the infinite intellegence (i.e., you the
> group) for direction. I choose the latter.
>
> Here is my code, all I want to see is that tx i/o flip on my
scope.
> The counter just makes the bits change so I know it's alive.
>
> I'm sure it's something stupid, but not having done this before I
> could sure use some help.
>
> TIA, John. > ;==============================
> list pF628
> __config h'3d31' ; XT oscillator
> radix hex
> include <p16f628.inc>
>
> byte equ 1
> word equ 2
> cblock 0x20
> count1 :byte
> endc ; end c block
>
> org 0x000 ; program memory at reset vector 0x000
> reset

CLRF STATUS ; good place for this if there is room

> goto setup ; set up ints and port stuff
> org 0x004 ; Interrupt vector, int handler code next
>
> ;==============================
> ; setup routine
> ;==============================
>
> setup
> movlw b'00000111' ; turn off analog I/O
> movwf CMCON
> movlw b'00000000' ; turn off interrupt
> movwf INTCON

BANKSEL PORTA
> clrf PORTA ; *** do the port initialization first
> clrf PORTB

BANKSEL TRISA
> MOVLW 0XFF ; set port A to inputs
> MOVWF TRISA
> movlw b'00000110' ; set port B to outputs, tx/rx on
> movwf TRISB

>
> ;==============================
> ; Main Loop
> ;==============================
>
> main
> bsf RCSTA,7 ; set SPEN
BANKSEL TXSTA
> bsf TXSTA,2 ; BRGH high *** changed bit ***
> movlw b'00011001' ; dec25
> movwf SPBRG ; set baud rate
> bcf TXSTA,4 ; clr SYNC
> bsf TXSTA,5 ; set TXEN
BANKSEL RCSTA
> bsf RCSTA,7 ; set SPEN
>
main1
BANKSEL TXREG
> incf count1, f
MOVF count1,W ; *** changed instruction ***
> movwf TXREG

BANKSEL TXSTA
>
> main2 btfss TXSTA,4
> goto main2
> goto main1
>
> ;==============================
> ; End
> ;==============================
>
> end





John,

I went ahead and rewrote the code. It works on my demo board with a
20 MHz resonator at 38400 baud:

list pF628A,r,nH
#include <p16f628a.inc>

errorlevel -302 ;suppress "not in bank 0" message

FALSE EQU 0
TRUE EQU ! FALSE

ifdef __16F877
BootLoader EQU TRUE
else
BootLoader EQU FALSE
endif

if ! BootLoader
__CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON &
_HS_OSC & _LVP_OFF
endif

byte equ 1
word equ 2

cblock 0x20
count1 :byte
endc ; end c block

;This code executes when a reset occurs.
ResetCode:
if ! BootLoader
org 0x0000
clrf STATUS
clrf PCLATH
else
org 0x0003
endif

goto setup ;go to beginning of program

;--------------------------------
--------
;This code executes when an interrupt occurs.

ORG 0x0004 ;place code at interrupt
vector

InterruptCode:

;==============================
; setup code
;==============================
setup
movlw b'00000111'
movwf CMCON
movlw b'00000000'
movwf INTCON

banksel PORTA
clrf PORTA
clrf PORTB

banksel TRISA
movlw 0xFF
movwf TRISA
movlw b'00000110'
movwf TRISB

bsf RCSTA,SPEN ; don't think this is necessary

banksel TXSTA
bsf TXSTA,BRGH
movlw d'31'
movwf SPBRG
bcf TXSTA,SYNC ; don't think this is necessary
bsf TXSTA,TXEN

banksel RCSTA
bsf RCSTA,SPEN

;==============================
; main loop
;==============================
main
banksel TXREG
incf count1,f
movf count1,w
movwf TXREG

banksel TXSTA

main1
btfss TXSTA,TRMT
goto main1
goto main

end Richard





OOPS - there is an extraneous line

--- In , "rtstofer" <rstofer@p...> wrote:
>
> John,
>
> I went ahead and rewrote the code. It works on my demo board with
a
> 20 MHz resonator at 38400 baud:
>
> list pF628A,r,nH
> #include <p16f628a.inc>
>
> errorlevel -302 ;suppress "not in bank 0"
message
>
> FALSE EQU 0
> TRUE EQU ! FALSE
>
> ifdef __16F877
> BootLoader EQU TRUE
> else
> BootLoader EQU FALSE
> endif
>
> if ! BootLoader
> __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON &
> _HS_OSC & _LVP_OFF
> endif
>
> byte equ 1
> word equ 2
>
> cblock 0x20
> count1 :byte
> endc ; end c block
>
> ;This code executes when a reset occurs.
> ResetCode:
> if ! BootLoader
> org 0x0000
> clrf STATUS
> clrf PCLATH
> else
> org 0x0003
> endif
>
> goto setup ;go to beginning of program
>
> ;------------------------------
--
> --------
> ;This code executes when an interrupt occurs.
>
> ORG 0x0004 ;place code at interrupt
> vector
>
> InterruptCode:
>
> ;==============================
> ; setup code
> ;==============================
> setup
> movlw b'00000111'
> movwf CMCON
> movlw b'00000000'
> movwf INTCON
>
> banksel PORTA
> clrf PORTA
> clrf PORTB
>
> banksel TRISA
> movlw 0xFF
> movwf TRISA
> movlw b'00000110'
> movwf TRISB
>
****** REMOVE THE FOLLOWING LINE
> bsf RCSTA,SPEN ; don't think this is necessary
******
>
> banksel TXSTA
> bsf TXSTA,BRGH
> movlw d'31'
> movwf SPBRG
> bcf TXSTA,SYNC ; don't think this is necessary
> bsf TXSTA,TXEN
>
> banksel RCSTA
> bsf RCSTA,SPEN
>
> ;==============================
> ; main loop
> ;==============================
> main
> banksel TXREG
> incf count1,f
> movf count1,w
> movwf TXREG
>
> banksel TXSTA
>
> main1
> btfss TXSTA,TRMT
> goto main1
> goto main
>
> end > Richard





cool, thanks . . . I like that 'banksel' instead of bsf status,rp0
etc.

per 16F62x datasheet (ds40300c) page 75, item #2 "enable the
asynchronous serial port by clearing bit SYNC and setting bit SPEN".

looks like if SPEN is cleared then the usart is disabled, what gives?

thanks . . . John.
--- In , "rtstofer" <rstofer@p...> wrote:
>
>
> OOPS - there is an extraneous line
>
> --- In , "rtstofer" <rstofer@p...> wrote:
> >
> > John,
> >
> > I went ahead and rewrote the code. It works on my demo board
with
> a
> > 20 MHz resonator at 38400 baud:
> >
> > list pF628A,r,nH
> > #include <p16f628a.inc>
> >
> > errorlevel -302 ;suppress "not in bank 0"
> message
> >
> > FALSE EQU 0
> > TRUE EQU ! FALSE
> >
> > ifdef __16F877
> > BootLoader EQU TRUE
> > else
> > BootLoader EQU FALSE
> > endif
> >
> > if ! BootLoader
> > __CONFIG _CP_OFF & _WDT_OFF & _BODEN_OFF & _PWRTE_ON &
> > _HS_OSC & _LVP_OFF
> > endif
> >
> > byte equ 1
> > word equ 2
> >
> > cblock 0x20
> > count1 :byte
> > endc ; end c block
> >
> > ;This code executes when a reset occurs.
> > ResetCode:
> > if ! BootLoader
> > org 0x0000
> > clrf STATUS
> > clrf PCLATH
> > else
> > org 0x0003
> > endif
> >
> > goto setup ;go to beginning of
program
> >
> > ;-----------------------------
-
> --
> > --------
> > ;This code executes when an interrupt occurs.
> >
> > ORG 0x0004 ;place code at interrupt
> > vector
> >
> > InterruptCode:
> >
> > ;==============================
> > ; setup code
> > ;==============================
> > setup
> > movlw b'00000111'
> > movwf CMCON
> > movlw b'00000000'
> > movwf INTCON
> >
> > banksel PORTA
> > clrf PORTA
> > clrf PORTB
> >
> > banksel TRISA
> > movlw 0xFF
> > movwf TRISA
> > movlw b'00000110'
> > movwf TRISB
> >
> ****** REMOVE THE FOLLOWING LINE
> > bsf RCSTA,SPEN ; don't think this is
necessary
> ******
> >
> > banksel TXSTA
> > bsf TXSTA,BRGH
> > movlw d'31'
> > movwf SPBRG
> > bcf TXSTA,SYNC ; don't think this is
necessary
> > bsf TXSTA,TXEN
> >
> > banksel RCSTA
> > bsf RCSTA,SPEN
> >
> > ;==============================
> > ; main loop
> > ;==============================
> > main
> > banksel TXREG
> > incf count1,f
> > movf count1,w
> > movwf TXREG
> >
> > banksel TXSTA
> >
> > main1
> > btfss TXSTA,TRMT
> > goto main1
> > goto main
> >
> > end
> >
> >
> > Richard





----- Original Message -----
From: jrem <>
To: <>
Sent: Tuesday, November 16, 2004 6:37 PM
Subject: [piclist] Re: Serial I/O on the 16F628 >
>
> cool, thanks . . . I like that 'banksel' instead of bsf status,rp0
> etc.

In XCASM you don't have to select the bank explicitly, the assembler inserts
bank select instructions for you when needed - but I digress :-)

>
> per 16F62x datasheet (ds40300c) page 75, item #2 "enable the
> asynchronous serial port by clearing bit SYNC and setting bit SPEN".
>
> looks like if SPEN is cleared then the usart is disabled, what gives?

The Rx and Tx pins on the 628 have multiple functions. To select the Rx and
Tx function you need to set this bit. It is kind of like selecting between
input and output by setting or clearing the bit in the tris register. Look
at Figures 12.5 and 12.8 for pictorial descriptions of the function of SPEN.

Regards
Sergio Masci

http://www.xcprod.com/titan/XCSB - optimising PIC compiler
FREE for personal non-commercial use




Don't know how I missed the bit about SYNC - it is required.
However, it is cleared at RESET and unless set somewhere else, it
shouldn't need to be touched.

I find tables 3-1,2,3 & 4 quite helpful in determining initial
conditions as well as naming and locating register and bits within
registers.

Yes, banksel, pagesel, bankisel are quite useful in that they help
document exactly which bank/page is being selected and, to some
extent, why.

All of the various bits are given names in the include file. I
personally prefer using the bit name to the bit number.





yes, table 3-1 and 3-2 are indispensable

too bad adobe won't let you split a page, I'm forever switching
between indexes and pages, etc., etc., not just for pic's but mysql
and others.

the php manuals are way cool, totally interactive, very easy to work
with online. The pic style manuals are easiest to work with when
printed and bound, IMO. , --- In , "rtstofer" <rstofer@p...> wrote:
>
>
> Don't know how I missed the bit about SYNC - it is required.
> However, it is cleared at RESET and unless set somewhere else, it
> shouldn't need to be touched.
>
> I find tables 3-1,2,3 & 4 quite helpful in determining initial
> conditions as well as naming and locating register and bits within
> registers.
>
> Yes, banksel, pagesel, bankisel are quite useful in that they help
> document exactly which bank/page is being selected and, to some
> extent, why.
>
> All of the various bits are given names in the include file. I
> personally prefer using the bit name to the bit number.




Memfault Beyond the Launch