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.

USART Receiving a String Problem

Status
Not open for further replies.

Suraj143

Active Member
Hi!

I’m receiving a string of 10 digit number & I’m saving each number in 10 GP registers.
After receiving the 10 digit number it will show the number in binary form.

Problem is its working for first round & after no more work.

Code:
		LIST		P=16F628A
		#include 	<P16F628A.INC>
		errorlevel	-302		
		__CONFIG   _CP_OFF & _DATA_CP_OFF & _LVP_OFF & _BOREN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT
			
						
		cblock	20h	
		Read_Count,Enable,d1,d2,d3
		endc	
			
		cblock	30h	
		Data1,Data2,Data3,Data4,Data5,Data6,Data7,Data8,Data9,Data10,Data11
		endc

		org	0x0000			
		clrf	STATUS
		goto	Init_Ports

		org	0x0004
		retfie

;*********************************
;Initialisation & setup the ports
;*********************************	
						
Init_Ports	movlw	07h		;turn off comparators & make pins for GP
		movwf	CMCON
		bsf	STATUS,RP0	;B1
		movlw	b'00000010'	;RB1 = Input & others output
		movwf	TRISB
		movlw	b'00000000'	;make all portA ports outputs		
		movwf	TRISA		
		bcf	STATUS,RP0	;B0
		nop
		nop			
Init_USART	bsf	STATUS,RP0	;B1
		movlw	b'00100100'	;Enable TXEN,High Baud rate
		movwf	TXSTA
		movlw	.25		;set Baud Rate = 9600
		movwf	SPBRG
		bsf	PIE1,RCIE	;enable Recieve Interrupt Enable
		nop
		nop
		bcf	STATUS,RP0	;B0
		nop
		nop
		clrf	RCSTA	
		movlw	b'10010000'	;Enable SPEN,CREN
		movwf	RCSTA
		bcf	PIR1,RCIF	;recieve more reception			
		nop
		nop
Init_INTCON	movlw	b'01000000'	;GIE,PEIE
		movwf	INTCON
		bcf	PIR1,RCIF	;recieve more reception	
		clrf	PORTA
		clrf	PORTB
		clrf	Enable
		call	Data_Clear
		goto	Begin
					
Data_Clear	clrf	Data1	
		clrf	Data2	
		clrf	Data3
		clrf	Data4	
		clrf	Data5	
		clrf	Data6	
		clrf	Data7
		clrf	Data8
		clrf	Data9	
		clrf	Data10
		return	
			
;******************************
;Main program starts from here
;******************************

Begin		movlw	30h
		movwf	FSR
		movlw	.11
		movwf	Read_Count	;load number of characters to be recieved							
Read_Loop	call	Read_CHR	
		movwf	INDF
		incf	FSR,F
		decfsz	Read_Count,F
		goto	Read_Loop
		bsf	Enable,0
		goto	Start
		
Read_CHR	btfss	PIR1,RCIF	;is it a reception?
		goto	Read_CHR
		bcf	PIR1,RCIF
		movf	RCREG,W		;yes,then take a copy of the character
		return		


Start		btfss	Enable,0
		goto	Start
		movf	Data1,W		;display number1
		andlw	b'00001111'
		movwf	PORTA
		call	Delay		
		movf	Data2,W		;display number2
		andlw	b'00001111'
		movwf	PORTA
		call	Delay		
		movf	Data3,W		;display number3
		andlw	b'00001111'
		movwf	PORTA
		call	Delay			
		movf	Data4,W		;display number4
		andlw	b'00001111'
		movwf	PORTA
		call	Delay		
		movf	Data5,W		;display number5	
		andlw	b'00001111'
		movwf	PORTA
		call	Delay			
		movf	Data6,W		;display number6
		andlw	b'00001111'
		movwf	PORTA
		call	Delay		
		movf	Data7,W		;display number7
		andlw	b'00001111'
		movwf	PORTA
		call	Delay		
		movf	Data8,W		;display number8
		andlw	b'00001111'
		movwf	PORTA
		call	Delay			
		movf	Data9,W		;display number9
		andlw	b'00001111'
		movwf	PORTA
		call	Delay		
		movf	Data10,W	;display number10	
		andlw	b'00001111'
		movwf	PORTA
		call	Delay
		bcf	Enable,0
		clrf	PORTA
		call	Data_Clear
		goto	Begin

This is the code that I use in my terminal program to send a string.

Code:
Private Sub Command1_Click()
MSComm1.Output = Text1.Text & vbCr
End Sub
 
Hi,
According to the datasheet page 82,
Follow these steps when setting up an Asynchronous
Reception:
1. TRISB<1> and TRISB<2> should both be set to
‘1’ to configure the RB1/RX/DT and RB2/TX/CK
pins as inputs. Output drive, when required, is
controlled by the peripheral circuitry.
just FYI because you're using only reception. But some people get it working too when tx is set as output for transmission.

From your program code, PEIE is enabled but GIE is not. If it's not entering the ISR when the reception is completed, I think you don't need to do anything to INTCON register. But why not using the ISR upon the reception?
Also, RCIF bit is read only, it's cleared when RCREG is read.
I noticed there're some nop around the codes, which are unnecessary :)

BTW, what do you mean it works for the first round and not after that? Only the first byte of data can be received correctly?
 
I assume you are reading 11 bytes so it includes the carriage return. Apart from that your code looks fine. Are you leaving enough time in VB before sending the next block?

Mike.
 
Hi bananasiong first I tested in ISR routine but didn't work so I shifted the whole program to main routine.After doing the code in the main it works for the first round.

First round is if I enter a 10 digit number ex: "1234567893" it will show the number in binary.When I again send this number it wont display & not working.Thats the problem.
 
Last edited:
I assume you are reading 11 bytes so it includes the carriage return. Apart from that your code looks fine. Are you leaving enough time in VB before sending the next block?

Mike.

I changed it to 10 also but still the problem is there.
Code:
Private Sub Command1_Click()
MSComm1.Output = Text1.Text & vbCr
End Sub

This is the code from VB.I'm entering a 10 digit number & clicking the command button.I dont know what is timing mike.The delay used in the program is 1S delay for 10 digits it has 10 seconds.
 
The only thing I can think of is that you are getting an overrun error. What happens if you add,
Code:
Begin		[COLOR="Blue"]clrf	RCSTA
		movlw	b'10010000'	;Enable SPEN,CREN
		movwf	RCSTA
		[/COLOR]movlw	30h
		movwf	FSR
		movlw	.11
		movwf	Read_Count	;load number of characters to be recieved							
Read_Loop	call	Read_CHR

Mike.
BTW, you should be receiving 11 bytes.
 
Last edited:
I added another instruction above. You need to receive 11 characters because your send 10 numbers and then a carriage return (vbCr).

Mike.
 
Hi Mike nice news it worked nicely.Here is the edited ones.

Code:
Begin		clrf	RCSTA	
		movlw	b'10010000'	;Enable SPEN,CREN
		movwf	RCSTA
		movlw	30h
		movwf	FSR
		[COLOR="Red"]movlw	.10[/COLOR]
		movwf	Read_Count	;load number of characters to be recieved							
Read_Loop	call	Read_CHR	
		movwf	INDF
		incf	FSR,F
		decfsz	Read_Count,F
		goto	Read_Loop
		[COLOR="Red"]call	Read_CHR	;check the CR as well
		xorlw	.13
		btfss	STATUS,Z
		goto	Begin[/COLOR]
		bsf	Enable,0
		goto	Start

But got a problem.When I enter a string below 10 characters the program gets stucked.So always I have to enter exact 10 characters,that is bad because if user enter below or above 10 characters the program gets stucked.

So now I'm thinking a method to detect a character or a string without detecting a fix length.

What about adding a small delay to expire the Read_CHR routine?
 
The easiest way to fix this would be to always send 10 characters from your VB program,
Code:
Private Sub Command1_Click()
Dim Temp As String
    Temp = Text1.Text & "00000000000"
    Temp = Left(Temp, 10)
    MSComm1.Output = Temp & vbCr
End Sub
Or,
Code:
Private Sub Command1_Click()
    MSComm1.Output = Left(Text1.Text & "00000000000", 10) & vbCr
End Sub

Alternatively, just wait for a CR but I think the VB method is easier.

Mike.
 
Hi Mike I understood that VB method is easy. Thanks for that.

If I enter 123 & click the command button does it send “1230000000”?

So the PIC software still detects the 10 digit string but the last seven digits it will save as “zeros”
I think this method I can apply to send ASCII characters as well without getting stuck in the program.

But consider I want to detect the string “1230” & save in GP registers for later use. So the balance zeros will add to the last zero in the string? So I miss that zero?
 
In that case the best method would be to detect the CR.

Code:
Begin		clrf	RCSTA	
		movlw	b'10010000'	;Enable SPEN,CREN
		movwf	RCSTA
		movlw	Data1
		movwf	FSR
Read_Loop	call	Read_CHR
		movwf	INDF		;store it
		xorlw	0x0d		;is it CR
		btfsc	STATUS,Z
		goto	GotCR
		incf	FSR,F
		movfw	FSR		;get FSR
		xorlw	Data1+d'11'	;got 11 characters?
		btfsc	STATUS,Z
		decf	FSR,F		;yes so prevent buffer overflow
		goto	Read_Loop
GotCR		bsf	Enable,0
		goto	Start

The above code will wait until a CR is received. If you send 12 characters and then a CR it will only store the first 10 and then the CR.

If you send 1230 then the numbers will be in Data1-Data4 and Data5 will be CR (0x0d).

Mike.
 
Excellent code Mike.A clever thinking.I'm going to use it right now.Why I cant do that like you.mmmmm I must do lots of code stuff to get experience.

I got everything that I expected from you.:)

Thanks again Mike
 
Very nice Mike!

-BaC

In that case the best method would be to detect the CR.

Code:
Begin		clrf	RCSTA	
		movlw	b'10010000'	;Enable SPEN,CREN
		movwf	RCSTA
		movlw	Data1
		movwf	FSR
Read_Loop	call	Read_CHR
		movwf	INDF		;store it
		xorlw	0x0d		;is it CR
		btfsc	STATUS,Z
		goto	GotCR
		incf	FSR,F
		movfw	FSR		;get FSR
		xorlw	Data1+d'11'	;got 11 characters?
		btfsc	STATUS,Z
		decf	FSR,F		;yes so prevent buffer overflow
		goto	Read_Loop
GotCR		bsf	Enable,0
		goto	Start

The above code will wait until a CR is received. If you send 12 characters and then a CR it will only store the first 10 and then the CR.

If you send 1230 then the numbers will be in Data1-Data4 and Data5 will be CR (0x0d).

Mike.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top