Reply by Grene October 6, 20092009-10-06
On Oct 4, 3:44=A0pm, Andrew Smallshaw <andr...@sdf.lonestar.org> wrote:
> On 2009-10-01, Grene <chris_trott...@hotmail.com> wrote: > > > > > > > I?m trying to get some PIC to PC communication going using the 16F688, > > but I am not having much luck. > > I grabbed the code below off the internet somewhere. =A0Nothing hooked > > up to the ADC but that?s fine, I don?t mind it spitting out random > > data, as long as it?s the values in the registers. =A0The code below > > compiles fine, load the chip, and start up hyperterminal. =A0At 9600 > > baud 8 bits, no parity, no flow control I get nothing. =A0 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. =A0I 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 =A08,000,000 / [16 (n + 1)] =3D > > 51.08 =3D [51] > > The code I pulled used 25. =A0I have had no luck with either setting. > > Anyone know what I am missing? > > I agree with you: 51 looks to be the correct value and not 25. =A025 > would be appropriate for 4MHz operation, not 8MHz which is what > you are getting from the internal oscillator. =A0Personally 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. =A0The 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? =A0It would be helpful to > know so we could put it into context. =A0I am guessing it was for a > different chip? =A0Code 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. =A0I'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 > andr...@sdf.lonestar.org- Hide quoted text - > > - Show quoted text -
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 by Andrew Smallshaw October 4, 20092009-10-04
On 2009-10-01, Grene <chris_trottier@hotmail.com> wrote:
> I?m trying to get some PIC to PC communication going using the 16F688, > but I am not having much luck.
> I grabbed the code below off the internet somewhere. Nothing hooked > up to the ADC but that?s fine, I don?t mind it spitting out random > data, as long as it?s 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 = 0, BRG16=1, BRGH=0 I > keep coming up with an SPBRG value of 8,000,000 / [16 (n + 1)] = > 51.08 = [51]
> The code I pulled used 25. I have had no luck with either setting. > Anyone know what I am missing?
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 by ChrisQ October 2, 20092009-10-02
Paul E Bennett wrote:

> 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. >
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 by Paul E Bennett October 2, 20092009-10-02
Frank Buss wrote:

> ChrisQ wrote: > >> 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. > > 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.
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...............<email://Paul_E.Bennett@topmail.co.uk> 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 by Rocky October 2, 20092009-10-02
On Oct 2, 2:11=A0pm, ChrisQ <m...@devnull.com> wrote:
> Frank Buss wrote: > > > That's no problem: Just connect the output and input of the serial shif=
ter
> > for a loopback without the PIC and hit some keys: if the connection wor=
ks,
> > you should see an echo, otherwise no echo of your keystrokes is display=
ed.
> > 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
There might be a hardware problem, or hardware handshaking may be enabled. Always worth doing a loopback if one is having issues.
Reply by ChrisQ October 2, 20092009-10-02
Frank Buss wrote:

> > 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. >
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 by Frank Buss October 1, 20092009-10-01
ChrisQ wrote:

> 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.
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 by ChrisQ October 1, 20092009-10-01
Grene wrote:

> > I grabbed the code below off the internet somewhere. Nothing hooked > up to the ADC but that&#4294967295;s fine, I don&#4294967295;t mind it spitting out random > data, as long as it&#4294967295;s 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. >
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 by Grene October 1, 20092009-10-01
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. (http://www.sparkfun.com/
commerce/product_info.php?products_id=3D133)



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      <P16F688.inc>        ; 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'