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.

help needed with assembly routine implementation

Status
Not open for further replies.

qtommer

Member
Im doing an assembly routine to send out 'AT' to my GSM handphone, in which i will get the reply 'OK'. When this happens Port B connected to an LED will light up.

I have written the following code and have tested it out in simulation using a Simulated USART Hardware Interface..

However, my code is implemented to only allow the PIC to receive one character only...Hence, if im expecting an incoming string with more than one character , how should I implement the routine to receive more than one character?

the following code is only able to accept the first incoming O. ive tried repeating the SerialRcv routine to capture the K but it doesnt work..
sorry i have to upload my code in a txt file because the columns dont seem to align when i type it here..

thanks
 

Attachments

  • asmcode.txt
    1.1 KB · Views: 141
The obvious problem I can see is that you aren't waiting for the characters to be received. Try changing it to,
Code:
SerialRcv:	
		BANK0
		btfss	PIR1,RCIF
		[COLOR="Red"]goto	SerialRcv[/COLOR]

		MOVF	RCREG,w
		RETURN

To enter your code as shown here you type [code] before it and [/code] after it.

Mike.
 
when trying to transfer a value from the w register to a declared variable (declared in cblock), is the following implementation correct?


Code:
CBLOCK     0X20
		D1
		D2
		D3
		D4
ENDC

main excerpt:

		call   SerialRcv
		movwf	D4


SerialRcv:	
		BANK0
		btfss	PIR1,RCIF
		goto	SerialRcv

		MOVF	RCREG,w
		RETURN

during simulation when i set the Rx pin to receive a '1' and stored the value into D4, the value retrieved from D4 is a '#'..for all values i set the Rx pin to receive, the same thing occurs.
Why is this so?

thanks!
 
You need to post code that can be run and an explanation of what happens.

Mike.
 
sorry...the following is my code to setup AT communication with the handphone to receive an incoming message from the user.

At the point where the microcontroller waits for and receives an incoming message (code highlighted in bold with label 'SMSWAIT'), it will ignore the message characters received until the point where ',' is received from which the character after the comma will need to be stored into a variable for later use. I intend to store this character byte into a variable D4 which i have defined under cblock.

i will then want the byte stored in variable 'D4' to be sent out through the USART during the cmgr routine (refer to cmgr label) . However, from the UART hardware simulation interface, it is shown that the value of D4 sent out is a '#' and not the character received from the message which i have input through simulation as a '1'

Code:
	list	p=16f877a
	#include	"p16f877a.inc"
	
__config 0x3ff1
STATUS	EQU	03h
TRISB	EQU	86h
PORTB	EQU	06h
COUNT1	EQU 0XFF
COUNT2	EQU	0XFF


CBLOCK 0X20
		D1
		D2
		D3
		D4
ENDC
BANK0 MACRO
		BCF STATUS,RP0
		BCF	STATUS,RP1
		ENDM

BANK1 MACRO
		BCF	STATUS,RP1
		BSF	STATUS,RP0
		ENDM


		org		0X00
		BANK1
		MOVLW	0X00
		MOVWF	TRISA
		BANK0

START	CALL	InitSerial
resend	movlw	'A'
		CALL	SerialSend
		movlw	'T'
		CALL	SerialSend
		movlw	0x0D
		CALL 	SerialSend
		CALL	SerialRcv
		xorlw	'O'
		btfss	STATUS,Z
		GOTO	resend
		CALL	SerialRcv
		XORLW	'K'
		btfss	STATUS,Z
		goto	resend

blink1	movlw	0x01
		movwf	PORTA


cmgf	movlw	'A'
		call	SerialSend
		movlw	'T'
		call	SerialSend
		movlw	'+'
		call	SerialSend
		movlw	'C'
		call	SerialSend
		movlw	'M'
		call	SerialSend
		movlw	'G'
		call	SerialSend
		movlw	'F'
		call	SerialSend
		movlw	'='
		call	SerialSend
		movlw	'1'
		call	SerialSend
		movlw	0x0D
		call	SerialSend

		CALL	SerialOK
	

blink2	movlw	0x03
		movwf	PORTA

		call	DELAY

cpms	movlw	'A'
		call	SerialSend
		movlw	'T'
		call	SerialSend
		movlw	'+'
		call	SerialSend
		movlw	'C'
		call	SerialSend
		movlw	'P'
		call	SerialSend
		movlw	'M'
		call	SerialSend
		movlw	'S'
		call	SerialSend
		movlw	'='
		call	SerialSend
		movlw	'"'
		call	SerialSend
		movlw	'M'
		call	SerialSend
		movlw	'E'
		call	SerialSend
		movlw	'"'
		call	SerialSend		
		movlw	0x0D
		call	SerialSend
		
		call	DELAY

		CALL	SerialOK

blink3	movlw	0x07
		movwf	PORTA

		call	DELAY

cnmi	movlw	'A'
		call	SerialSend
		movlw	'T'
		call	SerialSend
		movlw	'+'
		call	SerialSend
		movlw	'C'
		call	SerialSend
		movlw	'N'
		call	SerialSend
		movlw	'M'
		call	SerialSend
		movlw	'I'
		call	SerialSend
		movlw	'='
		call	SerialSend
		movlw	'2'
		call	SerialSend
		movlw	','
		call	SerialSend
		movlw	'1'
		call	SerialSend
		movlw	','
		call	SerialSend		
		movlw	'0'
		call	SerialSend	
		movlw	','
		call	SerialSend		
		movlw	'0'
		call	SerialSend	
		movlw	','
		call	SerialSend		
		movlw	'0'
		call	SerialSend	
		movlw	0x0D
		call	SerialSend


		call	SerialOK
blink4	movlw	0x0F
		movwf	PORTA



[B]SMSWAIT	call	CMTI
	call	SerialRcv
        movwf	D4

CMGR	movlw	'A'
		call	SerialSend
		movlw	'T'
		call	SerialSend
		movlw	'+'
		call	SerialSend
		movlw	'C'
		call	SerialSend
		movlw	'M'
		call	SerialSend
		movlw	'G'
		call	SerialSend
		movlw	'R'
		call	SerialSend
		movlw	'='
		call	SerialSend
                movlw	D4
		call	SerialSend	
		movlw	0x0D
		call	SerialSend[/B]
		



		
		
		



;;;;;;;;DELAY ROUTINE;;;;;;;;;;;;;;;;;;;
DELAY	MOVLW	D'100'	
		MOVWF	D3	
		MOVLW	D'100'	
		MOVWF	D2
		MOVLW	D'100'	
		MOVWF	D1
LOOP1	DECFSZ	D1
		GOTO	LOOP1
LOOP2	DECFSZ	D2
		GOTO	LOOP2
LOOP3	DECFSZ	D3
		GOTO	LOOP3	
		RETURN	

;;;;;;SERIAL SETUP;;;;;;;;;;;;;;;;;;;;;;;
InitSerial:
		BANK1
		movlw	b'11000000'
		iorwf	TRISC,f
		movlw	D'25'
		movwf	SPBRG
		movlw	0x24
		movwf	TXSTA
		BANK0
		movlw	0x90
		movwf	RCSTA

		Return

;;;;;;SERIAL SEND;;;;;;;;;;;;;;;;;;;;;;;;;;
SerialSend:
		BANK0
busywait:
		btfss	PIR1,TXIF
		goto	busywait
		movwf	TXREG
		return

;;;;;;;;SERIAL RECEIVE;;;;;;;;;;;;;;;;;;;;
SerialRcv:	
		BANK0
		btfss	PIR1,RCIF
		goto	SerialRcv

		MOVF	RCREG,w
		RETURN
		
		
		

;;;;;;;;SERIAL OK;;;;;;;;;;;;;;;;;;;;;;;;;
SerialOK:
		BANK0
		btfss	PIR1,RCIF
		goto	SerialOK
		MOVF	RCREG,w
		xorlw	'O'
		btfss	STATUS,Z
		goto	SerialOK
		return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

CMTI:
		BANK0
		btfss	PIR1,RCIF
		goto	CMTI
		movf	RCREG,w
		xorlw	','
		btfss	STATUS,Z
		goto	CMTI
		return
		

		END


how do i correctly store a received byte value from USART into a variable?

thanks
 
Last edited:
You need to stop being lazy. Waiting for "O" instead of "OK" and maybe crlf means that the serial is still receiving the previous characters and probably causing overflow errors.

Mike.
 
The following code is programmed to keep polling the UART until a ',' is received. The program will then take the next character after the ',' and store it into a variable which I have set as D4.
This next character expected is a '1' and I have tried it out in simulation (refer to attached picture)

After storing the character ('1') into D4, I intend to append this variable to a string and send out the string through the UART as follows "AT+CMGR = 1"

However, from the UART hardware simulation (as attached) I am sending out "AT+CMGR=#" instead of "AT+CMGR=1"

Code:
	list	p=16f877a
	#include	"p16f877a.inc"
	
__config 0x3ff1
COUNT1	EQU	0XFF
COUNT2	EQU	0XFF


;;;;;;;;VARIABLE BLOCK;;;;;;;;;;;;;;;;;;;;;;;;
CBLOCK 0X20
		D1
		D2
		D3
		D4
ENDC

;;;;;;;BANK SELECTION MACROS;;;;;;;;;;;;;;;;;;
BANK0 MACRO
		BCF STATUS,RP0
		BCF	STATUS,RP1
		ENDM

BANK1 MACRO
		BCF	STATUS,RP1
		BSF	STATUS,RP0
		ENDM

;;;;;;;;;;;;MAIN CODE;;;;;;;;;;;;;;;;;;;;;;;;;;
		org		0X00
		

START	CALL	InitSerial

SMSWAIT	call	CMTI
		[B]movwf	D4[/B]
	

CMGR	movlw	'A'
		call	SerialSend
		movlw	'T'
		call	SerialSend
		movlw	'+'
		call	SerialSend
		movlw	'C'
		call	SerialSend
		movlw	'M'
		call	SerialSend
		movlw	'G'
		call	SerialSend
		movlw	'R'
		call	SerialSend
		movlw	'='
		call	SerialSend
		movlw	D4
		call	SerialSend	
		movlw	0x0D
		call	SerialSend
		goto	CMGR


CMTI:
		BANK0
		btfss	PIR1,RCIF
		goto	CMTI
		movf	RCREG,w
		xorlw	','                                  ;test for comma
		btfss	STATUS,Z
		GOTO	CMTI		
CHK		BTFSS	PIR1,RCIF	            ;get next character after comma
		GOTO	CHK                            
		MOVF	RCREG,w
		return


;;;;;;SERIAL SETUP;;;;;;;;;;;;;;;;;;;;;;;
InitSerial:
		BANK1
		movlw	b'11000000'
		iorwf	TRISC,f
		movlw	D'25'
		movwf	SPBRG
		movlw	0x24
		movwf	TXSTA
		BANK0
		movlw	0x90
		movwf	RCSTA

		Return

;;;;;;SERIAL SEND;;;;;;;;;;;;;;;;;;;;;;;;;;
SerialSend:
		BANK0
busywait:
		btfss	PIR1,TXIF
		goto	busywait
		movwf	TXREG
		return
		
		END

As I have saved the incoming character of '1' into the w register, is my method of transferring the value in the w register to a variable correct?

movwf D4


thanks!
 

Attachments

  • cmti.png
    cmti.png
    11.1 KB · Views: 138
Your code looks fine and I would suggest that the character received after the comma is a '#'.

As a test, to make sure it's not a timing problem, you could change it to,
Code:
CMTI:
		BANK0
		btfss	PIR1,RCIF
		goto	CMTI
		movf	RCREG,w
		xorlw	','                                  ;test for comma
		btfss	STATUS,Z
		GOTO	CMTI		
CHK		BTFSS	PIR1,RCIF	            ;get next character after comma
		GOTO	CHK                            
		MOVF	RCREG,w
		[COLOR="red"]MOVLW	'1'	;ensure W = '1'[/COLOR] 
		return

Mike.
 
i have inserted that line to gauge whether its a timing problem or not but i still get the same results in the simulator..

I guess its the nature of the simulator to do output received bytes as a '#'?
 
i have further developed my code and my pic is able to receive an SMS through the Handphone via the CMTI AT Function. Upon receiving this new message indication , im sending out the command AT + CMGR =1 to retrieve the message from memory location 1 of the handphone. I have inserted an LED indicator when a new message is received (by the lighting up of Port B movlw 0x0F) note that at this point, the message has not been read yet but just indicated as arrived. Oh and all Port B pins are connected to LEDs.

My questions are:
1).I have attached a picture showing the Hyper Terminal Results of the executed command and result codes of this process to retrieve a new SMS .
Back to the PIC, When i am sending out AT+CMGR=1, I would not only get my message but a prepended string of message details in a line above the message that I want. I do not want to store these details so i keep waiting until the ' " ' right at the end of the message detail line followed by waiting for the CR and LF (shown in the code below in bold) before i start reading.


I have commented out the waiting of the LF at this point (highlighted in red) because I discovered that when I do not comment them out, the LEDs connected to Port B to determine that a message has arrived will only turn on for an extremely short while and will immediately go off followed by the flickering of other LEDs connected to portA (which I have connected LEDs to as indicators for the AT configurations (Refer 4 posts behind) the pic starts to act wierd at this point..other than that the LED will just turn on nice and fine.

Is my assumption in waiting for a "<CR><LF> correct?

is the end of the message detail line a "<CR><LF> or is it just a "<CR> ?





Code:
	list	p=16f877a
	#include	"p16f877a.inc"
	
__config 0x3ff1
STATUS	EQU	03h
TRISB	EQU	86h
PORTB	EQU	06h
COUNT1	EQU 0XFF
COUNT2	EQU	0XFF

CBLOCK 0X20
		D1
		D2
		D3
		D4
ENDC
BANK0 MACRO
		BCF STATUS,RP0
		BCF	STATUS,RP1
		ENDM

BANK1 MACRO
		BCF	STATUS,RP1
		BSF	STATUS,RP0
		ENDM
		
		org		0X00
		BANK1
		movlw	0X00
		MOVWF	TRISA
		MOVLW	0X00
		MOVWF	TRISB
		BANK0

START	call	DELAY
		call	DELAY
		CALL	InitSerial
		call	DELAY
		CALL	DELAY

;;;;;;;;WAIT FOR SMS ROUTINE;;;;;;;;;

CMTI	CALL	SerialRcv
		xorlw	','
		btfss	STATUS,Z
		goto	CMTI
CMTI2	CALL	SerialRcv
		XORLW	0X0D
		BTFSS	STATUS,Z
		GOTO	CMTI2
		CALL	SerialRcv
		xorlw	0x0A
		btfss	STATUS,Z
		goto	CMTI2

;;;;;;;;;;CMGR ROUTINE;;;;;;;;;;;;;;;;;;
		movlw	0x0F
		movwf	PORTB

CMGR	movlw	'A'
		call	SerialSend
		movlw	'T'
		call	SerialSend
		movlw	'+'
		call	SerialSend
		movlw	'C'
		call	SerialSend
		movlw	'M'
		call	SerialSend
		movlw	'G'
		call	SerialSend
		movlw	'R'
		call	SerialSend
		movlw	'='
		call	SerialSend
		movlw	'1'
		call	SerialSend	
		movlw	0x0D
		call	SerialSend

;;;;;;;;;;READ SMS MESSAGE ROUTINE;;;;;;;;;

[B]read	CALL	SerialRcv
		xorlw	'"'
		btfss	STATUS,Z
		goto	read
		call	SerialRcv
		xorlw	0x0D
		btfss	STATUS,Z
		goto	read
[COLOR="Red"]                call	SerialRcv
;		xorlw	0x0A
;		btfss	STATUS,Z
;		goto	read[/COLOR][/B]
		
		call	SerialRcv	;CHECK IF MESSAGE IS 1
		xorlw	'1'
		btfss	STATUS,Z
		goto	CMTI
		
		movlw	0xFF
		movwf	PORTB
here	call	DELAY
		goto	here
			
;;;;;;;;DELAY ROUTINE;;;;;;;;;;;;;;;;;;;
DELAY	MOVLW	D'50'	
		MOVWF	D3	
		MOVLW	D'50'	
		MOVWF	D2
		MOVLW	D'50'	
		MOVWF	D1
LOOP1	DECFSZ	D1
		GOTO	LOOP1
LOOP2	DECFSZ	D2
		GOTO	LOOP2
LOOP3	DECFSZ	D3
		GOTO	LOOP3	
		RETURN	

;;;;;;SERIAL SETUP;;;;;;;;;;;;;;;;;;;;;;;
InitSerial:
		BANK1
		movlw	b'11000000'
		iorwf	TRISC,f
		movlw	D'25'
		movwf	SPBRG
		movlw	0x24
		movwf	TXSTA
		BANK0
		movlw	0x90
		movwf	RCSTA

		Return

;;;;;;SERIAL SEND;;;;;;;;;;;;;;;;;;;;;;;;;;
SerialSend:
		BANK0
busywait:
		btfss	PIR1,TXIF
		goto	busywait
		movwf	TXREG
		return

;;;;;;;;SERIAL RECEIVE;;;;;;;;;;;;;;;;;;;;
SerialRcv:	
		BANK0
		btfss	PIR1,RCIF
		goto	SerialRcv

		MOVF	RCREG,w
		RETURN


		





;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
		END



thanks alot =)
 

Attachments

  • Untitled picture.png
    Untitled picture.png
    17.1 KB · Views: 127
Last edited:
i've managed to find out the problem above. there was a buffer overflow in the code..

i now have a small question:

if i have a character received through the UART and transferred into the w register. I would like to determine whether this character is a 1,2 or 3. How should I implement the code for this?

I have tried using xorlw but then consecutive usage of xorlw will overwrite the original value stored in the w register.: (seen as follows)

Code:
            call	SerialRcv	           ;character received and stored in w register
check1  xorlw	'1'
            btfss	STATUS,Z
            goto	check2                  ;if 1 is not received, go to check2 else go to next line

next line=[do "1 is received" code]


check2  xorlw    '2'
            btfss      STATUS,Z
            goto       check3                 ;if 2 is not received, go to check 3 , else go to next line

next line=[do "2 is received code"]

check3 [do "3 is received code"]



so i tried using xorwf as follows but still the code did not work:

Code:
            call	SerialRcv	           ;character received and stored in w register
check1  xorwf      REG1,1                  ;content of REG1 is 0x01
            btfss	STATUS,Z
            goto	check2                  ;if 1 is not received, go to check2 else go to next line

next line=[do "1 is received" code]


check2  xorwf      REG2,1                   ;content of REG1 is 0x02
            btfss      STATUS,Z
            goto       check3                 ;if 2 is not received, go to check 3 , else go to next line

next line=[do "2 is received code"]

check3 [do "3 is received code"]


how should I go about implementing the determining of the received character in the w register?


thank you so much
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top