Need help in GSM Coding (Assembly Language)
Discussion in "8051 Discussion Forum" started by Malik_Umair May 24, 2013.
Mon Jun 24 2013, 10:07 am
I appreciate your thinking and I will look forward for your contribution. Post your current code so I can help you solve issues. and also share SMS format you're sending.
Sat Jun 29 2013, 04:00 pm
Hello Ajay,
I am seriously fed up of this task. I have tried my best but unable to receive any SMS. I am sharing the whole code with you, please arrange it for me. Its been a month and a half that I am working on it. The interrupt routine for sending sms is working fine.
I am seriously fed up of this task. I have tried my best but unable to receive any SMS. I am sharing the whole code with you, please arrange it for me. Its been a month and a half that I am working on it. The interrupt routine for sending sms is working fine.
;*********************************************************************************************** ; Program for Sending SMS through GSM network using ; SIM900D and AT89C51 ;*********************************************************************************************** ; Upon wake-up goto MAIN, avoid using memory space, allocated ; to interrupt vector table ;*********************************************************************************************** ORG 0H LJMP MAIN ;********************************************************************************************** ; ISR for External Interrupt 0 to send Message for ; particular activated input ;********************************************************************************************** ORG 03H LJMP CHECK ;*********************************************************************************************** ; ISR FOR TIMER 0 INTERRUPT ;*********************************************************************************************** ORG 000BH ; TIMER 0 INTERRUPT ;This is your ISR where you will count ;60 interrupts and set timer flag INC R6 ;increment counter CJNE R6, #60,OUT CALL TIMEDOUT OUT: MOV TL0,#0CDH MOV TH0,#0FFH ;Reload timer again for 50ms RETI TIMEDOUT: ; Timeout occured CLR TR0 ;stop timer now SETB TIMEOUT_FLAG RETI ;*********************************************************************************************** ; The MAIN program for initilization ;*********************************************************************************************** ORG 30H ; to define TIMEOUT_FLAG you can use ; bit addressable area TIMEOUT_FLAG equ 0H ;0H means Address:20H[bit0] MAIN: MOV P1,#00H MOV P2,#00H ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 SETB P1.0 START: MOV IE, #83H ACALL SERIAL ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 LCALL CMGF LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL CSMS ; SET t PHASE 1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL CNMI_READ LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL CPMS ; SET THE READ & WRITE STORAGE TO SIM LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL CMGL ; LIST SMS FROM LOCATION (CURRENTLY SET TO "ALL") LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 READ_AGAIN: LCALL INIT_TIMEOUT LCALL CMGR ; READ THE STORED MESSAGE ;LCALL DELAY1 ;LCALL DELAY1 ;LCALL DELAY1 ;LCALL DELAY1 ;********************************************************************************************** WaitForStar: JB RI, CHECK_BYTE JB TIMEOUT_FLAG, READ_AGAIN ;TIMEOUT_FLAG is a bit variable that is set ; In ISR of timer that your initialized earlier SJMP WaitForStar ;if no timeout is not received ;go back and check data received CHECK_BYTE: MOV A, SBUF CLR RI CJNE A, '*', WaitForStar WaitForCode: ;the next char is a command JNB RI,WaitForCode MOV A,SBUF CLR RI CJNE A,'1', ERROR ; If TRUE then make P2.1 HIGH SETB P2.1 Sjmp CommonExit ERROR: SETB P2.2 ; If FALSE then make P2.2 HIGH CommonExit: LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 CLR P2.1 CLR P2.2 CLR A LCALL CMGD ; DELETE THE SMS STORED IN SIM LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LCALL DELAY1 LJMP START ;*********************************************************************************************** ;DELETE: LCALL CMGD ; DELETE THE SMS STORED IN SIM ; LCALL DELAY1 ; LCALL DELAY1 ; LCALL DELAY1 ; LCALL DELAY1 ; LJMP START ;********************************************************************************************** ; ERROR: SETB P2.2 ; LCALL DELAY1 ; LCALL DELAY1 ; LCALL DELAY1 ; LCALL DELAY1 ; CLR P2.2 ; LJMP START ;*********************************************************************************************** ; Sending ISR ;*********************************************************************************************** ORG 200H CHECK: JNB P1.0, CHECK ACALL SERIAL ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL CMGF ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL CNMI ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL CMGS ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL SALAM ACALL THIEF ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 ACALL DELAY1 RETI ;*********************************************************************************************** ; Subroutine for Sending one byte out of serial port ;*********************************************************************************************** TRAIN: MOV SBUF,A HERE: JNB TI,HERE CLR TI RET ;*********************************************************************************************** ; Subroutine for initializing the serial port with 9600BPS ;*********************************************************************************************** SERIAL: MOV TMOD,#20H MOV TH1,#0FDH MOV SCON,#50H SETB TR1 RET ;********************************************************************************************** ; Subroutine for CSMS ;********************************************************************************************** CSMS: MOV DPTR,#TABLE6 MOV R7,#10 LOOP6: MOV A,#0 MOVC A,@A+DPTR INC DPTR LCALL TRAIN DJNZ R7,LOOP6 RET ;********************************************************************************************** ; Subroutine for CPMS ;********************************************************************************************** CPMS: MOV DPTR,#TABLE8 MOV R7,#13 LOOOOP: MOV A,#0 MOVC A,@A+DPTR INC DPTR LCALL TRAIN DJNZ R7,LOOOOP RET ;********************************************************************************************** ; Subroutine for CMGL ;********************************************************************************************** CMGL: MOV DPTR,#TABLE7 MOV R7,#14 LOOP7: MOV A,#0 MOVC A,@A+DPTR INC DPTR LCALL TRAIN DJNZ R7,LOOP7 RET ;*********************************************************************************************** ; Subroutine for CMGR ;*********************************************************************************************** CMGR: MOV DPTR,#TABLE9 MOV R7,#10 BACK: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN DJNZ R7,BACK RET ;*********************************************************************************************** ; Subroutine for CMGD ;*********************************************************************************************** CMGD: MOV DPTR,#TABLE10 MOV R7,#10 BACK1: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN DJNZ R7,BACK1 RET ;*********************************************************************************************** ; Subroutine for CNMI_READ ;*********************************************************************************************** CNMI_READ: MOV DPTR,#TABLE11 MOV R7,#18 BACK2: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN DJNZ R7,BACK2 RET ;*********************************************************************************************** ; Subroutine for CMGF ;*********************************************************************************************** CMGF: MOV DPTR,#TABLE1 MOV R7,#10 LOOP1: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN ; ACALL DELAY DJNZ R7,LOOP1 RET ;*********************************************************************************************** ; Subroutine for CNMI ;*********************************************************************************************** CNMI: MOV DPTR,#TABLE2 MOV R7,#18 LOOP2: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN ; ACALL DELAY DJNZ R7,LOOP2 RET ;*********************************************************************************************** ; Subroutine for CMGS ;*********************************************************************************************** CMGS: MOV DPTR,#TABLE3 MOV R7,#22 LOOP3: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN ; ACALL DELAY DJNZ R7,LOOP3 RET ;*********************************************************************************************** ; Subroutine for SALAM ;*********************************************************************************************** SALAM: MOV DPTR,#TABLE4 MOV R7,#18 LOOP4: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN ; ACALL DELAY DJNZ R7,LOOP4 RET ;*********************************************************************************************** ; Subroutine for THIEF ;*********************************************************************************************** THIEF: MOV DPTR,#TABLE5 MOV R7,#31 LOOP5: MOV A,#0 MOVC A,@A+DPTR INC DPTR ACALL TRAIN ; ACALL DELAY DJNZ R7,LOOP5 RET ;*********************************************************************************************** ; Subroutine for delay ;*********************************************************************************************** DELAY: MOV R0,#50 RELOAD: MOV R1,#50 WAIT: DJNZ R1,WAIT DJNZ R0,RELOAD RET ;*********************************************************************************************** ; Subroutine for LARGE delay ;*********************************************************************************************** DELAY1: MOV R0,#255 RELOAD1: MOV R1,#255 WAIT1: DJNZ R1,WAIT1 DJNZ R0,RELOAD1 RET ;*********************************************************************************************** ; Subroutine for INIT_TIMEOUT ;*********************************************************************************************** INIT_TIMEOUT: CLR TR0 ;make sure timer is stopped CLR TIMEOUT_FLAG MOV R6, #0 ;assuming r6 is used for counting interrupts ;INIT timer for 50ms approx. time period MOV TMOD,#00000001B ; TIMER 0, MODE 1 MOV TL0,#0CDH MOV TH0,#0FFH SETB TR0 ;start timer RET ;*********************************************************************************************** ; Lookup Tables ;*********************************************************************************************** ORG 400H TABLE1: DB "AT+CMGF=1",0Dh TABLE2: DB "AT+CNMI=2,2,0,0,0",0Dh TABLE3: DB 'AT+CMGS="03319018928"',0Dh TABLE4: DB "ASSALAM-O-ALAIKUM",0Dh TABLE5: DB "GSM is working",1Ah TABLE6: DB "AT+CSMS=0",0Dh TABLE7: DB 'AT+CMGL="ALL"',0Dh TABLE8: DB 'AT+CPMS="SM"',0Dh TABLE9: DB "AT+CMGR=1",0Dh TABLE10: DB "AT+CMGD=1",0Dh TABLE11: DB "AT+CNMI=2,2,0,0,0",0Dh END
[ Edited Sat Jun 29 2013, 04:01 pm ]
Sun Jun 30 2013, 02:58 am
My earlier tips were lost in the server hack.
This works on Proteus.
Your main error was in setting TMOD in "INIT_TIMEOUT"
Good luck
This works on Proteus.
Your main error was in setting TMOD in "INIT_TIMEOUT"
Good luck
Malik_Umair like this.
Sun Jun 30 2013, 01:19 pm
Yeah I was also finding our previous few posts. So you have initialized timer 0 and 1 in same instruction in "INIT_TIMEOUT", But I have also initialized the timer in serial communication "ACALL SERIAL". So I want to as will these two separate initialization will not effect the execution? Also please I didn't understand the TMOD 21H. Please esplain it. Have you tested this code? Is this working fine? Because I am totally failed in it
Mon Jul 01 2013, 11:41 am
I do not see any issues in the program that ExperimenterUK shared.
TMOD=21H will not effect anything, as for serial you initialized Timer 1 in mode2 which means TMOD = 0x20
and when you are initializing timer0 for timer we are using mode1 so TMOD should only set timer1 mode bits and should not effect any other bit in that register, so TMOD = 0x21 timer1 mode bits remain same/unmodified. SERIAL subroutine should only be called once in your program, please remove SERIAL call from ISR.
You need to debug your program as follows:
1. Connect your board to PC or somehow tap your controller's TX pin to see if your controller is sending commands properly or not.
2. You must see AT+CMGR=1 continuously after every 3 seconds
What is the format of SMS you are using? It must start from '*'
PS: Electronics project needs lot of patience.
TMOD=21H will not effect anything, as for serial you initialized Timer 1 in mode2 which means TMOD = 0x20
and when you are initializing timer0 for timer we are using mode1 so TMOD should only set timer1 mode bits and should not effect any other bit in that register, so TMOD = 0x21 timer1 mode bits remain same/unmodified. SERIAL subroutine should only be called once in your program, please remove SERIAL call from ISR.
You need to debug your program as follows:
1. Connect your board to PC or somehow tap your controller's TX pin to see if your controller is sending commands properly or not.
2. You must see AT+CMGR=1 continuously after every 3 seconds
What is the format of SMS you are using? It must start from '*'
PS: Electronics project needs lot of patience.
Malik_Umair like this.
Mon Jul 01 2013, 11:00 pm
Thank you to Dear Ajay and ExperimenterUK to help me, I have little modified the ExperimenterUK program because it was giving interrupt and subroutine error but now it is working fine I am receiving SMS perfectly. But I have noticed that when I send message from microcontroller and I feed the number like "03319018928" the message is send correctly but when I feed the number like "+923319018928" I am unable to send message (or message is not sending from the microcontroller). Please help me in this regard.
Also I want to get help in that how can I update the sending number through sending SMS to microcontroller. For-example like currently I have programmed the micro-controller that it will send messages to a number, i-e, 03319018928 and I have burned this program into microcontroller and the system is in function now. Now I want to change the number to which microcontroller send the number, so in order to switch off the system and re-program the microcontroller how can I update the new number by sending message to the system when it is operational?
Also I want to get help in that how can I update the sending number through sending SMS to microcontroller. For-example like currently I have programmed the micro-controller that it will send messages to a number, i-e, 03319018928 and I have burned this program into microcontroller and the system is in function now. Now I want to change the number to which microcontroller send the number, so in order to switch off the system and re-program the microcontroller how can I update the new number by sending message to the system when it is operational?
Tue Jul 02 2013, 12:39 am
Glad to hear it is working at last.
Easy, don't send numbers like "+923319018928"
Seriously, why are you adding "+92 to the number ?
What does your phone manual say about the numbers you can use ?
This will be complicated.
Could you store several alternative numbers and change which one used via SMS ?
that would be much easier.
when I feed the number like "+923319018928" I am unable to send message (or message is not sending from the microcontroller). Please help me in this regard.Malik_Umair
Easy, don't send numbers like "+923319018928"
Seriously, why are you adding "+92 to the number ?
What does your phone manual say about the numbers you can use ?
Now I want to change the number to which microcontroller send the number, so in order to switch off the system and re-program the microcontroller how can I update the new number by sending message to the system when it is operational?Malik_Umair
This will be complicated.
Could you store several alternative numbers and change which one used via SMS ?
that would be much easier.
[ Edited Tue Jul 02 2013, 12:40 am ]
Wed Jul 03 2013, 12:20 am
try to avoid using ORG multiple time in your program. just keep on writing your assembler automatically assign space to code one after the other. anyways.. I think experimenterUK's suggestion is good do not add prefix... But i think problem is the way you have written the code. You might be chaning number but you forgot to change number of characters:
best way is to end strings with 0H or null I will give example later.
Now regarding saving number.. you can define a memory area to store number and simply copy received sms over there.. and use that memory area as your mobile number. Its bit difficult try if you can. In your code if you receive sms starting from * then next byte contains your command if command is a number like 1, 2 etc then process them as you are doing already if your sms has + character then it means new number to set e.g. *+01234567890# read till # and move to memory and use it.
CMGS: MOV DPTR,#TABLE3 MOV R7,#22 ; if you change size of TABLE3 then change value 22 here accordingly
best way is to end strings with 0H or null I will give example later.
Now regarding saving number.. you can define a memory area to store number and simply copy received sms over there.. and use that memory area as your mobile number. Its bit difficult try if you can. In your code if you receive sms starting from * then next byte contains your command if command is a number like 1, 2 etc then process them as you are doing already if your sms has + character then it means new number to set e.g. *+01234567890# read till # and move to memory and use it.
Malik_Umair like this.
Powered by e107 Forum System