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'
[PIC] 16F688 USART ISSUES
Started by ●October 1, 2009
Reply by ●October 1, 20092009-10-01
Grene wrote:> > 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. >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 ●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 ●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 ●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, > > ChrisThere might be a hardware problem, or hardware handshaking may be enabled. Always worth doing a loopback if one is having issues.
Reply by ●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 ●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 ●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 ●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!