[PIC] 16F688 USART ISSUES

I=92m trying to get some PIC to PC communication going using the 16F688, but I am not having much luck.

Hardware setup is just a PIC16F688 with power, and RC4/RC5 connected to an RS232 ShifterBoard Kit from Sparkfun.

formatting link

I grabbed the code below off the internet somewhere. Nothing hooked up to the ADC but that=92s fine, I don=92t mind it spitting out random data, as long as it=92s the values in the registers. The code below compiles fine, load the chip, and start up hyperterminal. At 9600 baud 8 bits, no parity, no flow control I get nothing. If I lower the speed to 2400bps I get gobbledygook periodically at timed intervals corresponding to the RCV light on the serial shifter, so it looks like data is being transmitted. I assume I must just have the baud rate wrong.

In looking at the datasheet, for 9600baud, SYNC =3D 0, BRG16=3D1, BRGH=3D0 = I keep coming up with an SPBRG value of 8,000,000 / [16 (n + 1)] =3D

51.08 =3D [51]

The code I pulled used 25. I have had no luck with either setting. Anyone know what I am missing?

list p=3D16f688 ; list directive to define processor

#include ; processor specific variable definitions

__CONFIG _CP_OFF & _CPD_OFF & _BOD_OFF & _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _FCMEN_OFF & _IESO_OFF

; '__CONFIG' directive is used to embed configuration data within .asm file.

; The labels following the directive are located in the respective .inc file.

; See respective data sheet for additional information on configuration word.

;***** VARIABLE DEFINITIONS

w_temp EQU 0x71 ; variable used for context saving

status_temp EQU 0x72 ; variable used for context saving

pclath_temp EQU 0x73 ; variable used for context saving

ADCH0 EQU B'00000001' ;setup ch 0, Vdd for Vref, and left justified result

ADCH1 EQU B'00000101' ;set to Ch1 same settings as above

ADCH2 EQU B'00001001' ;set to Ch2 same settings as above

ADCH3 EQU B'00001101' ;set to Ch3 same settings as above

COUNTER EQU 0x60 ;counter variable

TXPREBUF EQU 0x61 ;A buffer for the serial transmit buffer (a prebuf)

OCTTOVERT EQU 0x20 ;stores the a/d value when it's being converted to octal

;**********************************************************************

ORG 0x0 ; processor reset vector

goto main ; go to beginning of program

main

;***********************************************************

;Setup For 9600 bps tx serial interface

;***********************************************************

bsf STATUS, RP0 ;bank 1

movlw B'00111111' ;setup RC0-5 as inputs for serial i/ o and A/D

movwf TRISC

bcf STATUS, RP0 ;bank 0

bsf RCSTA, SPEN ;serial port enable

bsf BAUDCTL, BRG16 ;use 16 bit baudrate generator

bcf TXSTA, BRGH ;use low baudrate speed

movlw d'25'

movwf SPBRG ;setup baudrate generator

bcf TXSTA, SYNC ;asynchronous serial i/o

bsf TXSTA, TXEN ;enable transmission

;***********************************************************

;Setup A/D converter

;***********************************************************

bsf STATUS, RP0 ;bank 1

movlw B'00011111' ;Setup all of port A as inputs for A/ D

movwf TRISA

movlw 0xFF

movwf ANSEL ;Enable all available Analog channels

movlw B'01010000'

movwf ADCON1 ;Set 4uS conversion time w/ 4MHz internal clk

bcf STATUS, RP0 ;bank 0

movlw ADCH0

movwf ADCON0 ;AD: right justified result, ch 0, VDD ref. voltage

call WaitForAD

;***********************************************************

;Setup Timer1 for 1/10 second wait period

;***********************************************************

movlw B'00110001'

movwf T1CON ;load timer1 config register

GoAgain:

movlw 0x01 ;set to max for approx 1 sec delay

movwf TMR1L

movlw 0x00

movwf TMR1H

;bsf T1CON, TMR1ON ;start timer

bcf PIR1, TMR1IF ;clear overflow flag

;This is the delay between sample periods from the analog inputs

Wait:

btfss PIR1, TMR1IF ;check if timer has overflowed

goto Wait

call GetADValues

; loop through 4 values here and print them out

movlw 0x4 ;loop 4 times

movwf COUNTER

movlw 0x21 ;point to first a/d value

movwf FSR ;data pointer

OutLoop:

movf INDF, W ;getting indirect data

movwf OCTTOVERT ;store a/d value we need to convert

call TO_OCTAL ;convert currently selected A/D Channel to octal

movf 0x30, W ;output all bytes

movwf TXPREBUF

call SENDBYTE

movf 0x31, W

movwf TXPREBUF

call SENDBYTE

movf 0x32, W

movwf TXPREBUF

call SENDBYTE

movlw ',' ;do checking on this one to see if we're at the last byte

movwf TXPREBUF

call SENDBYTE

incf FSR ;goto next a/d value

decfsz COUNTER ;is counter zero yet? if so skip goto

goto OutLoop

; end of above loop

movlw 0x0A ;Line Feed (newline, hopefully)

movwf TXPREBUF

call SENDBYTE

;movlw 0x0D ;carridge return

;movwf TXPREBUF

;call SENDBYTE

goto GoAgain ;Reset the timer for another go around

;***********************************************************

;Subroutines

;***********************************************************

WaitForAD: ;wait 44us to init, 176 instruction cycles

movlw D'176' ;really only need 1/2 this many cycles due to test and set

movwf COUNTER

FourFourWait:

decf COUNTER

bnz FourFourWait ;keep decrementing until we reach 0

return

;get a/d values for 4 ch

GetADValues:

movlw 0x21 ;start of free ram

movwf FSR ;setup indirect addressing register

movlw ADCH0 ;goto channel 0

movwf ADCON0

bsf ADCON0, GO ;start conversion

btfsc ADCON0, GO ;conversion done?

goto $-1 ;keep looping

movf ADRESH, W ;get high byte into acc W

movwf INDF ;store adresh to 21h

incf FSR ;move ptr to 22h

call WaitForAD

movlw ADCH1 ;goto channel 1

movwf ADCON0

bsf ADCON0, GO ;start conversion

btfsc ADCON0, GO ;conversion done?

goto $-1 ;keep looping

movf ADRESH, W ;get high byte into acc W

movwf INDF ;store adresh to 22h

incf FSR ;move ptr to 23h

call WaitForAD

movlw ADCH2 ;goto channel 2

movwf ADCON0

bsf ADCON0, GO ;start conversion

btfsc ADCON0, GO ;conversion done?

goto $-1 ;keep looping

movf ADRESH, W ;get high byte into acc W

movwf INDF ;store adresh to 23h

incf FSR ;move ptr to 24h

call WaitForAD

movlw ADCH3 ;goto channel 3

movwf ADCON0

bsf ADCON0, GO ;start conversion

btfsc ADCON0, GO ;conversion done?

goto $-1 ;keep looping

movf ADRESH, W ;get high byte into acc W

movwf INDF ;store adresh to 24h

return

;convert to 3 octal bytes in ASCII

;stores bytes in 0x30 to 0x32, w/ lsb in 0x32 msb in 0x30

;input value stored in 0x20, ie OCTTOVERT

TO_OCTAL:

clrc ;clear carry

movlw B'00000111' ;bit mask field

andwf OCTTOVERT, W ;and with ADRESH

addlw 0x30 ;make this into an ASCII number

movwf 0x32 ;store result away

;octal byte 2

movlw B'00111000' ;bit mask field

andwf OCTTOVERT, W ;get 2nd set of 3 bits

movwf 0x31 ;place back into file

rrf 0x31 ;rotate to LSB, need 3x

rrf 0x31

rrf 0x31

movf 0x31, W ;now get it back

addlw 0x30 ;and add 30h to make a ascii number

movwf 0x31 ;store again

;octal byte 3

clrc ;clear carry

movlw B'11000000' ;bit mask field

andwf OCTTOVERT, W ;get last 2 bits

movwf 0x30

rrf 0x30

rrf 0x30

rrf 0x30

rrf 0x30

rrf 0x30

rrf 0x30

;btfsc 0x21, 0 ;check the LSB value from the last byte

;bsf 0x31, 2

movf 0x30, W ;get value back

addlw 0x30 ;convert to ASCII

movwf 0x30 ;store it

return

;transmit data on serial port

SENDBYTE:

btfss TXSTA, TRMT ;check tx buffer ready bit

goto SENDBYTE ;try again, keep polling

movf TXPREBUF, W ;get data from pre-buffer

movwf TXREG ;move data to tx register and start transmission

return

ORG 0x2100 ; data EEPROM location

DE 1,2,3,4 ; define first four EEPROM locations as 1, 2, 3, and 4

END ; directive 'end of program'

Reply to
Grene
Loading thread data ...

Don't want to appear obtuse, but the first mistake is to use hyperterminal if you're trying to debug serial comms. You can never be sure if it's really connected, or if it's locked up or whatever.

Have a look on the web for (windows) tera term. It's been around for years and is imho, the best free terminal package around. As well as being a rock solid terminal emulator, it also supports telnet sessions and the sources are free in C or pascal.

One less variable etc...

Regards,

Chris

Reply to
ChrisQ

That's no problem: Just connect the output and input of the serial shifter for a loopback without the PIC and hit some keys: if the connection works, you should see an echo, otherwise no echo of your keystrokes is displayed.

--
Frank Buss, fb@frank-buss.de
http://www.frank-buss.de, http://www.it4-systems.de
Reply to
Frank Buss

Agreed, you can do that, but who has the time, especially if there's something around that just works out of the box ?.

No disrespect, but you need a hair shirt to want to use that piece of win 3.1 generation stuff...

Regards,

Chris

Reply to
ChrisQ

ter

ks,

ed.

There might be a hardware problem, or hardware handshaking may be enabled. Always worth doing a loopback if one is having issues.

Reply to
Rocky

Whatever terminal emulation programme you end up using the best peice of equipment to hang into a comms link is a break-out box. This will allow you to play with the connections, see what is and what isn't toggling when it should and gives you an easy point on which to hang a scope to check things out. Buy one or make one a very useful peice of kit for serial RS232 comms.

--
********************************************************************
Paul E. Bennett...............
Forth based HIDECS Consultancy
Mob: +44 (0)7811-639972
Tel: +44 (0)1235-510979
Going Forth Safely ..... EBA. www.electric-boat-association.org.uk..
********************************************************************
Reply to
Paul E Bennett

Agreed, essential piece of kit. The work i've been doing for the past couple of years has a lot of serial comms at 9.6k (graphical road signs) and one of the most usefull bits of kit i've found has been the old HP protocol analyser series. Started with a blown power supply (fixed)

4955a which even has the hp basic option. Moved on to 4953, slightly smaller and eventually stopped at 4952's and a 4957a, all floppy drive. Now have 3 of the things courtesy of ebay at not much more the 10-20 ukp each, mine being the only bid. Have to tell myself to stop collecting every time another one appears :-).

You can monitor lines and program them to build just about any test pattern, wiggle rts dtr etc as well. Brilliant bit of kit and can't understand why hp dropped them from the catalog...

Regards,

Chris

Reply to
ChrisQ

I agree with you: 51 looks to be the correct value and not 25. 25 would be appropriate for 4MHz operation, not 8MHz which is what you are getting from the internal oscillator. Personally I wouldn't be too inclined to trust the internal oscillator anyway when RS-232 is involved but we will assume it is OK since I have no experience of that particular chip. The rest of your basic serial port set up also looks fine but I haven't gone right through the code listing

However, that incorrect value sets alarm bells ringing for me, as does another comment I noticed in the source abotu 4MHz operation. Where did you get this code listing from? It would be helpful to know so we could put it into context. I am guessing it was for a different chip? Code compatibility between different devices is generally poor in the PIC range and this may be causing issues. For example, since A/D is involved it is possible that you are not allowing sufficent time for conversions at the faster clock rate which may cause all kinds of strange behaviour. I'm not saying this is what is happening - as I said, I haven't been through the code in full, but if we know more about the origins of the code it would help to narrow down the issues.

--
Andrew Smallshaw
andrews@sdf.lonestar.org
Reply to
Andrew Smallshaw

=3D0 I

Got the code right off the internet as is, it was orignally for the

16f688, which is why i grabbed it. I wanted to start with somthing I knew worked....only it didn't. Not sure if the original coder had problems with the int osc, but that is how they had it set up. 25 is the right value, 4MHz is the default clock speed for internal osc, unless configured to be 8MHz. I thought it was the other way around, but ended up catching it in the datasheet after a few glances at OSCON details. I ended up solving the problem by using a 4Mhz external crystal, and a value for SPBRG of 25. I didn't think there would be an issue with using the internal OSC, but apparently its worth it to go with somthing a little/lot more stable. Also using Tera Term Web, thanks for the suggestion ChrisQ. Much easier to work with than Hyperterminal for sure!
Reply to
Grene

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.