Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

16f628 uart

Status
Not open for further replies.

Pete_UK

New Member
Hey,

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
 
Try this bit of code, taken from Nigel's tutorials, works fine for me.
Code:
HSER_INIT
		BSF	STATUS,RP0	;select bank 1
		MOVLW	d'25'		;9600 baud @ 4 Mhz 
		MOVWF	SPBRG
		MOVLW	b'00100100'	;brgh = 1
		MOVWF	TXSTA		;enable Async Transmission, set brgh
		BCF	STATUS,RP0	;select bank 0
		MOVLW	b'10010000'
		MOVWF	RCSTA		;enable Async Reception
		RETURN

HXMIT_RS232	btfss	PIR1,TXIF	;xmit buffer empty?
		GOTO	HXMIT_RS232	;no, wait
		MOVWF	TXREG		;now send
		RETURN

HRcv_RS232	BTFSS	PIR1,RCIF	; check for received data
		GOTO	HRcv_RS232
		MOVF	RCREG,	W
 
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
 
Well done getting it working.

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.

Not at all, the STOP bit signifies the end of the transmission, that's what it's there for.

Leaving an extra gap is simply sending an extended stop bit.
 
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.
 
If you get a PIC to transmit "0" again and again, it can be seen as something else.

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.
 
Assuming you start at a start bit, as RS232 must, then it resynchronises at every stop bit

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.

Mike.
 
Last edited:
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 :D

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.
 
It is only in test situations, and only if the same data is repeatedly sent, that there can be a problem.

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 would also suggest that you leave a time gap between sending data when testing.

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.
 
Nigel,

How do you account for my problems with hyperterminal when using 1 stop bit? Why didn't it resync?

Mike.
 
Hey again,

Quite a debate going on.. :eek:

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)

Think I'll have to keep on tinkering!

Pete
 
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.

Mike.
 
Hi Pommie,

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?

Peter
 
Last edited:
Choose a newer one like the 16F887, 40 pin with lots of functionality.

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top