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.

PIC16F628A USART receiving problem

Status
Not open for further replies.

AWHF

New Member
I'm using VB6 to communicate with PIC via RS-232.
RS-232 -> MAX-232 -> PIC
I have tested the output of the MAX-232 by sending character using VB6. I observed the output through oscilloscope. It works! But when i connected the MAX-232 to the PIC and try a simple program by sending a character and if the character is matched, it will ON the LED. But it is not working.
My VB6 setting is 9600=baud rate N=no parrity 8bits 1 stop bit
Here my code:
Code:
;Test

	LIST	p=16F628A			;tell assembler what chip we are using
	include	"P16F628A.inc"			;include the defaults for the chip
	ERRORLEVEL	0,	-302		;suppress bank selection messages
	__config 0x3D18				;sets the configuration settings (oscillator)

		cblock	0x20			;start of general purpose registers
			count

KM		Equ	0

		org	0x0000			
		movlw	0x07
		movwf	CMCON			;turn comparators off

Initialise	clrf	count
		clrf	PORTA
		clrf	PORTB


SetPorts	bsf 	STATUS,		RP0	;select bank 1
		MOVLW	B'00000110'
		MOVWF	TRISB		      	
		bcf 	STATUS,		RP0	;select bank 0
		call	SER_INIT

CHECK		call 	Rcv_RS232		;check receive data
		xorlw	'B'	
		btfss	STATUS, Z		;is data 'B'?
		goto	CHECK			;if not, goto CHECK
		goto 	KM_ON			;if yes. goto KM_ON


KM_ON		bsf	PORTB, KM		;ON Keypad Message

:Hardware USART Serial Routines
SER_INIT
            	BSF     STATUS, RP0           ;select bank 1
     		MOVLW   d'25'                 ;9600 baud @ 4 Mhz Fosc +0.16% err
     		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

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

Rcv_RS232   	BTFSS   PIR1,	RCIF 	      ;check for received data
     		GOTO    Rcv_RS232
                MOVF    RCREG,	W
                RETURN

;End of serial routines
Do u guys have any idea of what's going on?
Hope to hear from u guys!
Thanks in advance!
 
been a while since I've done assembly, but it looks like you're setting RB1 and RB2 both as inputs, where you want your TX pin to be an output (think that's RB2 on the 628A), this wouldn't cause a problem with what you're trying to do as you're just looking to receive with your PIC but it's all that stuck out at me at a quick glance. Oh, and what terminal are you using to send your characters? I had problems using hyperterm and switched to putty to resolve that, something with hyperterm and CTS/RTS or something.
 
One other thing, like I said been a while, but if it does manage to get the character properly, then it goes to KM_ON turning the port on, but then what? looks like it runs off into memory, don't you still need something like an endless loop to stick your program at that point so it won't head off into unknown program memory? Or is that a C only type of thing?
 
Norlin said:
....but it looks like you're setting RB1 and RB2 both as inputs, where you want your TX pin to be an output (think that's RB2 on the 628A), this wouldn't cause a problem .....
Hi,
These pins are supposed to be configured as input according to the datasheet.
 
Wow, would you look at that! I always set the tx pin as an output and never had a problem but the datasheet does say to set it as an input, how strange.
 
I set tx as output too before knowing that, and it worked too. I set it as input after I know about that. Just follow the datasheet.
 
Your main loop falls through to SER_INIT. You need to add the line in blue.

Mike.

Code:
CHECK		call 	Rcv_RS232		;check receive data
		xorlw	'B'	
		btfss	STATUS, Z		;is data 'B'?
		goto	CHECK			;if not, goto CHECK
		goto 	KM_ON			;if yes. goto KM_ON


KM_ON		bsf	PORTB, KM		;ON Keypad Message
		[COLOR="Blue"]goto	CHECK[/COLOR]

:Hardware USART Serial Routines
SER_INIT
 
Pommie said:
Your main loop falls through to SER_INIT. You need to add the line in blue.

Heh, that's what I was trying to say in post 3, guess I wasn't very clear and you put it better :)
 
Now, i'm able to received data using the USART.
But after i combined with my overall program, the KM_ON couldn't works(the LED does not ON). What is the problem actually occurs? Do u guys have any idea?
Code:
	LIST	p=16F628A			;tell assembler what chip we are using
	include	"P16F628A.inc"			;include the defaults for the chip
	ERRORLEVEL	0,	-302		;suppress bank selection messages
	__config 0x3D18				;sets the configuration settings (oscillator)

		cblock	0x20			;start of general purpose registers
			count
			count1			;used in delay routine
			counta			;used in delay routine
			countb			;used in delay routine
			key
			rows
		endc

KEY_PORT	Equ	PORTA			;keypad port
KEY_TRIS	Equ	TRISA
Col1		Equ	4			;pins used for keypad inputs
Col2		Equ	5
Col3		Equ	6
Col4		Equ	7
MA_PORT		Equ	PORTB			;set constant Message Alert = 'PORTB'
IR_PORT		Equ	PORTB			;set constant InfraRed = 'PORTB'
DOOR_PORT	Equ	PORTB
RESET_PORT	Equ	PORTB
KM_PORT		Equ	PORTB
KEYPAD_PORT	Equ	PORTB
OUT_PORT	Equ	PORTB
BARCODE_PORT	Equ	PORTB
IR_TRIS		Equ	TRISB			;set constant for TRIS register
KM		Equ	0
DOOR		Equ	3	
IR		Equ	4
MA		Equ	5
RESET		Equ	6
OUT		Equ	7

;end of defines

		org	0x0000			
		movlw	0x07
		movwf	CMCON			;turn comparators off
		goto	Initialise

Key_Table  	ADDWF   PCL       , f
            	RETLW   0x41			;A
            	RETLW   0x33			;3
            	RETLW   0x32			;2
            	RETLW   0x31			;1
            	RETLW   0x42			;B
            	RETLW   0x36			;6
            	RETLW   0x35			;5
           	RETLW   0x34			;4
            	RETLW   0x43			;C
            	RETLW   0x39			;9
            	RETLW   0x38			;8
            	RETLW   0x37			;7
            	RETLW   0x44			;D
            	RETLW   0x23			;#
            	RETLW   0x30			;0
            	RETLW   0x2A			;*


Initialise	clrf	count
		clrf	PORTA
		clrf	PORTB


SetPorts	bsf 	STATUS,		RP0	;select bank 1
		movlw	0xF0			;set keypad pins
		movwf	KEY_TRIS		;half (RA4 - RA7) in, half (RA0 - RA3) out
		MOVLW	B'11011110'
		MOVWF	TRISB		      	;RB1/RX, RB2/TX, RB3, RB4, RB6 and RB7 as input, RB0 and RB5 as output
		bcf 	STATUS,		RP0	;select bank 0
		call	SER_INIT


;####################### START ####################################

CHECK_BARCODE	call 	Rcv_RS232		;check receive data
		xorlw	'B'	
		btfss	STATUS, Z		;is data 'B'?
		goto	CHECK_BARCODE		;if not, goto CHECK_BARCODE 
		goto 	KM_ON			;if yes. goto KM_ON
		
;######################## NORMAL PROCEDURE #########################

KM_ON		bsf	KM_PORT, KM		;ON Keypad Message

;Check keypad scanning
Main		movlw	0xF0
		movwf	KEY_PORT		;set all (RB0 - RB3) output pins low

		movlw	4
		movwf	count			;4 digits are allowed to press
Loop		call	Chk_Keys		;check keys
		movf	key, w			;restore key pressed
		call	XMIT_RS232		;display as ASCII
		decfsz	count, f
		goto	Loop
		goto 	REPLY_KEYPAD

REPLY_KEYPAD	call 	Rcv_RS232		;check receive data
		xorlw	'A'	
		btfss	STATUS, Z		;is data 'A'?
		goto	Main			;if not, goto Main 
		goto 	KM_OFF			;if yes. goto KM_OFF

KM_OFF		bcf	KM_PORT, KM		;OFF Keypad Message		


CHECK_DOOR	btfss	DOOR_PORT, DOOR		;is door open?
		goto	CHECK_DOOR		;if no, goto CHECK_DOOR
		goto	INFRARED		;if yes, goto INFRARED


INFRARED	btfsc 	IR_PORT, IR		;is infrared block?
		goto	INFRARED		;if no, goto INFRARED
		goto	MA_OFF			;if yes, goto MA_OFF


MA_OFF		call	Delay255		;delay for 3sec
		call 	Delay255
		call 	Delay255
		call 	Delay255
		call 	Delay255
		call 	Delay255
		call 	Delay255
		call 	Delay255
		call 	Delay255
		call 	Delay255		
		call	Delay100
		call 	Delay100		
		call	Delay50			
		goto	INFRARED2		;after 3sec goto INFRARED2


INFRARED2	btfsc 	IR_PORT, IR		;is infrared still block after 3min?
		goto	CHECK_DOOR1		;if no, goto CHECK_DOOR1
		goto	MA_ON			;if yes, goto MA_ON
		
CHECK_DOOR1	btfsc	DOOR_PORT, DOOR		;is door close?
		goto	INFRARED2		;if no, goto INFRARED2
		goto	CHECK_BARCODE		;if yes, goto CHECK_BARCODE, start over again

MA_ON		bsf	IR_PORT, MA		;ON Message Alert
		goto	CLOSE_MA		;goto CLOSE_MA
		

CLOSE_MA	btfss	RESET_PORT, RESET	;is the reset button press?
		goto	MA_ON			;if no, go to MA_ON
		call	MA_OFF1			;if yes, go to MA_OFF1
		goto	CHECK_DOOR1		;then go to CHECK_DOOR1 to check the door

MA_OFF1		bcf	IR_PORT, MA		;close Message Alert
		return

;########################## Keypad subroutine ##############################

Chk_Keys	movlw	0x00			;wait until no key pressed
		movwf	KEY_PORT		;set all output pins low
		movf	KEY_PORT,	W
		andlw	0xF0			;mask off high byte
		sublw	0xF0			
		btfsc	STATUS, Z		;test if any key pressed
		goto	Keys			;if none, read keys
		call	Delay20
		goto	Chk_Keys		;else try again

Keys	  	call    Scan_Keys
            	movlw   0x10			;check for no key pressed
            	subwf   key, w
            	btfss   STATUS, Z
            	goto    Key_Found
		call	Delay20
		goto	Keys
Key_Found      	movf    key, w			
		andlw	0x0f
		call	Key_Table		;lookup key in table	
		movwf	key			;save back in key
		return				;key pressed now in W

Scan_Keys  	clrf    key
		movlw	0x0F			;set all (RB0 - RB3) output lines high
            	movwf   KEY_PORT
            	movlw   0x04
            	movwf   rows			;set number of rows
            	bcf     STATUS, C		;put a 0 into carry
Scan	  	rlf     KEY_PORT, f		
            	bsf     STATUS, C		;follow the zero with ones
            	btfss   KEY_PORT, Col4
            	goto    Press
            	incf    key, f
            	btfss   KEY_PORT, Col3
            	goto    Press
            	incf    key, f
            	btfss   KEY_PORT, Col2
            	goto    Press
            	incf    key, f
            	btfss   KEY_PORT, Col1
            	goto    Press
            	incf    key, f
            	decfsz  rows, f
            	goto    Scan
Press	  	return

;end of keypad subroutines.

;######################## Hardware USART Serial routines #######################

SER_INIT
            	BSF     STATUS, RP0           ;select bank 1
     		MOVLW   d'25'                 ;9600 baud @ 4 Mhz Fosc +0.16% err
     		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

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

Rcv_RS232   	BTFSS   PIR1,	RCIF 	      ;check for received data
     		GOTO    Rcv_RS232
                MOVF    RCREG,	W
                RETURN

;End of serial routines


;############################### Delay ###################################

Delay255	movlw	0xff			;delay 255 mS
		goto	d0
Delay100	movlw	d'100'			;delay 100mS
		goto	d0
Delay50		movlw	d'50'			;delay 50mS
		goto	d0
Delay20		movlw	d'20'			;delay 20mS
		goto	d0
Delay5		movlw	0x05			;delay 5.000 ms (4 MHz clock)
d0		movwf	count1
d1		movlw	0xC7			;delay 1mS
		movwf	counta
		movlw	0x01
		movwf	countb
Delay_0
		decfsz	counta, f
		goto	$+2
		decfsz	countb, f
		goto	Delay_0

		decfsz	count1	,f
		goto	d1
		retlw	0x00


		end
 
Last edited:
You can't expect anyone to go through your code and work out whats wrong when they don't know what is connected to what port etc. Chop out the bits that work and reduce it to a bare minimum. Once you work out which bit isn't working, post it here. You'll probably find that the process of working out what is wrong will identify the problem anyway.

Mike.
 
Thanks for your advice!
Actually i had try out part by part individually + the USART RX as i posted previously. All of the parts work well. But once i combined all the parts, its not working. The beginning of the program, it will check whether the Rcv_RS232 is receiving data "B", if yes it will goto KM_ON and ON the LED. But the LED is not ON.
 
AWHF said:
Thanks for your advice!
Actually i had try out part by part individually + the USART RX as i posted previously. All of the parts work well. But once i combined all the parts, its not working. The beginning of the program, it will check whether the Rcv_RS232 is receiving data "B", if yes it will goto KM_ON and ON the LED. But the LED is not ON.
Debugging is half the fun. :p It's a huge part of what being a programmer is. If you have to rely on other people to do it for you then you're missing out.

If you don't have a good programmer that does on-chip debugging (ICD2 or PICkit2 or clones of them, or other) then debugging gets a lot harder, but it still can be done. Persevere! :D
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top