I've been working on some code to transmit a single character. I've set up a small circuit using the PicKit 2 programmer and a UM232R USB to Serial converter module and a 16F628 Pic.
I've tested the UM232R by looping back its TX and RX pins to check that it's operating and all is fine. I've also used the UART Tool in the PicKit 2 software to try and receive the transmitted character from the Pic but had no success with this either. I've also wrote and loaded a small program to turn on some LEDs with the same configuration settings that confirms the Pic is operating correctly (this is also verified in the PicKit 2 software).
After ruling out the hardware I've been trying to debug the code but have now totally drawn a blank. Could anyone have a quick check over to see if there is an obvious error that needs correcting? The code has been pasted here.
Thanks for any help that anyone can provide!
Pete
Code:
LIST P=16F628 ;16F628 PROCESSOR
#include <P16F628.INC> ;Include header file
__config _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON & _MCLRE_ON
CBLOCK 0x20 ;Declare variable addresses starting at 0x20
dataL
ENDC
ORG 0x000
movlw 0x07 ;Turn comparators off
movwf CMCON
; INITIALISE PORTS
bsf STATUS,RP0 ;Select Bank 1
movlw b'00000100' ;Set RB2 to Tx
movwf TRISB
; CONFIGURE BAUD RATE AND TX REGISTER
movlw 0x19 ;9600 baud
movwf SPBRG
movlw b'00100100' ;Transmit enable, high baud rate
movwf TXSTA
bcf STATUS,RP0 ;Select Bank 0
; MAIN PROGRAM
loop call message
goto loop
; MESSAGE SUB-ROUTINE
message movlw 'Y'
movwf TXREG
return
END
I've worked it out! It took a few hours, and for anyone who may search the forums in future with an issue...
- RCSTA has to be configured even if you're only wanting to transmit
- RCSTA is not in the same bank as TXSTA (this caused me the most grief. I put these settings in the same block of code that set-up the baud rate so RCSTA was being put in to bank 1)
Sorry for causing you to reply HouseOfWax, but this really seemed to be a case of R.F.M. on my part.
Pete
Updated code
Code:
LIST P=16F628, R=dec ;16F628 PROCESSOR
#include "P16F628.INC" ; Include header file
__config _INTRC_OSC_NOCLKOUT & _LVP_OFF & _WDT_OFF & _PWRTE_ON & _BODEN_ON
CBLOCK 0x20 ; Declare variable addresses starting at 0x20
dataL
ENDC
ORG 0x000 ;Program starts at 0x000
movlw 7 ;Turn comparators off
movwf CMCON
; INITIALISE PORTS
bsf STATUS,RP0 ;Select Bank 1
movlw b'00000110' ;Set RB2 to Tx, RB1 to RX
movwf TRISB
; CONFIGURE BAUD RATE AND TX/RX REGISTER
movlw 0x19 ;9600 baud with 4Mhz Internal Oscillator
movwf SPBRG
movlw b'00100100' ;Transmit enable, high baud rate
movwf TXSTA
bcf STATUS,RP0 ;Select Bank 0
movlw b'10010000'
movwf RCSTA
; MAIN PROGRAM
call message
; MESSAGE SUB-ROUTINE
message movlw 'Y'
movwf TXREG
return
END
You should also check that the buffer isn't full before sending another character. I think that your code is running off the end as there is no "goto main".
I would also suggest that you leave a time gap between sending data when testing. If you send the same character over and over it can look like some other character as the receiver has no way of knowing what is the start. With a gap between characters, the start is clear.
I would also suggest that you leave a time gap between sending data when testing. If you send the same character over and over it can look like some other character as the receiver has no way of knowing what is the start. With a gap between characters, the start is clear.
If you get a PIC to transmit "0" again and again, it can be seen as something else.
"0" is 0x30, transmitted lsb first, with one start bit (0) and one stop bit (1) is 0000011001
If that is repeated it is ......00000110010000011001000001100100000110010000011001...... etc
The problem is that it the same as 0010000011 repeated, which is 0x41 or "A", with the start and stop bits.
You can either send a more complicated sequence or put gaps in. Either will cause the receiver to resynchronise to the correct framing.
Not at all, and no different to any other RS232 system - it can only be seen as something else if you don't start at the beginning of a byte (with a start bit). Assuming you start at a start bit, as RS232 must, then it resynchronises at every stop bit, that's what the stop bit is there for.
That is not a good assumption if you are testing a USART.
The problem is that if you are outputting all "0"s, all you need is a bad connection, or just unplugging and plugging in again, and it sees it as all "A"s. I know that is outside the RS232 protocol, but it can easily happen.
I've had this very problem when writing the code for the DS1820 interface. If I used only 1 stop bit then I got errors. Two stop bits fixed it. See post #19 of previous thread.
That is not a good assumption if you are testing a USART.
The problem is that if you are outputting all "0"s, all you need is a bad connection, or just unplugging and plugging in again, and it sees it as all "A"s. I know that is outside the RS232 protocol, but it can easily happen.
Unfortunately you can't run your life (or RS232) on the basis that nothing is working propelry
Adding an extra stop bit isn't to help in any case - and leaving stop 'gaps' longer than complete words is going to seriously cripple any potential speed. There's no need for it, and it isn't done - the extended stop bit facility in RS232 (1.5 or 2 stop bits) was for mechanical devices (such as teletypes) to have more time to carry out mechanical operations.
It is only in test situations, and only if the same data is repeatedly sent, that there can be a problem.
I'm not suggesting massive gaps all over the place in real situations. Anyhow, there are often gaps in real situations, the data is too complex for the wrong bits to be repeatedly taken as start and stop bits, and there is less chance of connection or disconnection.
Again, it makes no difference - it doesn't matter if the same data is continually sent, which is a perfectly normal scenario. The ONLY time you can get a problem is if the connecting wires become faulty in some mysterious way (pretty difficult to get a spurious start bit, but bits could be lost while the wires are disconnected, and restart at a radom point), and that affects ALL communication, and wouldn't be helped by large gaps in any case.
If you're at all concerned about the possibility, then implement somekind of protocol to guard against it.
I was just trying to warn the OP about the confusion that can be caused if he were to set the PIC sending characters, and then connect to whatever receives it. If there are no gaps, and "A" is being sent, "0" or "A" can appear repeatedly, depending on when the connection is made.
I have another question about configuring USART in a different PIC. The intention of the circuit that I'm designing was to connect PORTA outputs to a group of 3-8 decoders configured to provide 5-32 decoding, but I've fallen in to the assumption that RA4 was an output like the rest of the port (excluding RA5). There are 5 bits to decode and 2 bits reserved for an Enable and latch-reset.
This is a bit of a setback and I'm pretty sure that a different PIC is going to have to be used in order for the end product to work as I intended it. So I've got a query...
What is an ideal PIC to use that could enable me to painlessly transfer my current program with a few minor tweaks (I was looking at an 18F2321)? Would it be a total redesign of the code or is it a case just changing a few existing lines?
One alternative I've thought of is tieing the appropriate enable input on the latch to VDD and just use the Reset on my latches to turn off the output (a 00000 in the decoder circuit turns on relay number 1, so by using a Enable bit I can turn off all output)
The RA4 pin can be set to output and will work. However, it can only drive low and so in your circuit you will need a resistor (1k to 10k) from the pin to Vdd. If you still want to switch chips then the 16F88 should fit and the only thing required would be to switch port A to digital as it defaults to analogue. To switch to an 18 series chip will require major changes to your code.
Thanks for the suggestion. Is there a PIC in the 16F series that has 3 ports instead of 2? I think a pic where I can use the full 8 bits would be better. Something like the 16F73?