I am trying to communicate between AT89S52 microcontroller and NEOWAY M590E gsm module.I use HTerm to in communicating with the MCU it works perfectly. Whenever i connect the modem to the MCU it does nothing. For each command it sends , i allow it to turn on a the led of different ports. Unfortunately, none of the leds came on. I wonder why that is. KIndly help me out.
#include <reg51.h> void confirmPBready(void); void BYTEwrite( unsigned char VAL, unsigned char buffLEN, unsigned char *buffADDR); void sendAT(unsigned char *buf); bit COMP_buff2buff( unsigned char *BUFF1, unsigned char *BUFF2, unsigned char LEN); void delay(void); bit OKay( unsigned char *BUFF1, unsigned char *BUFF2, unsigned char LEN); void confirmOK(); unsigned char rcx[13]; unsigned char txtMOD[]="AT+CMGF=1\r"; unsigned char TE_com[]="AT+CSCS=\"GSM\"\r"; unsigned char MOBnum[]="AT+CMGS=\"+2349056777712\"\r"; bit RXDcmpt; //this flag is set if end of a string is detected. bit PBflag; //this flag is set when the MCU gets PB ready message. unsigned char i, rxd_cnt = 0; //counts as value are recieved in the serrial ISR. unsigned char SERIALcase ; //switch case in ISR. unsigned char *loc; void main() { //INITIALIZATION SCON = 0x50; TMOD = 0x20; TH1 = 0xFD; TR1 = 1; ES = 1; EA = 1; SERIALcase = 1; //set the default of the serial switch case in ISR. PBflag = rxd_cnt = RXDcmpt = 0; //set flag to default. while(!PBflag) { if(RXDcmpt) //Check if MCU recieved a value { confirmPBready(); //Check if its PBready. if(!PBflag) { rxd_cnt = 0; BYTEwrite(0x00,rxd_cnt,rcx); RXDcmpt = 0; } } } BYTEwrite(0x0,rxd_cnt,rcx); //clear buffer rxd_cnt= PBflag = RXDcmpt = 0; //PBready recievd. Proceed with confirguration. sendAT(txtMOD); while(!PBflag) { if(RXDcmpt && !PBflag) //Check if MCU recieved a value confirmOK(); //Check if its OK. } rxd_cnt = PBflag = RXDcmpt = 0; BYTEwrite(0,sizeof(rcx),rcx); //Command "AT+CMGF=1" receives OK sendAT(TE_com); while(!PBflag) { if(RXDcmpt && !PBflag) //Check if MCU recieved a value confirmOK(); //Check if its OK. } rxd_cnt = PBflag = RXDcmpt = 0; BYTEwrite(0,sizeof(rcx),rcx); //Command AT+CSCS=\"GSM\" receives OK sendAT(MOBnum); for(i = 1; i<30; i++) delay(); sendAT("GSM MODULE TEXT VIA CODING"); for(i = 1; i < 30 ; i++) delay(); sendAT("0x1A"); for(i = 1; i<60; i++) delay(); } void delay(void) { unsigned int i; for(i=0;i<25000;i++); } void BYTEwrite( unsigned char VAL, unsigned char buffLEN, unsigned char *buffADDR) { while(buffLEN) { *buffADDR++ = VAL; //write the value into address. buffLEN--; //decrement the lenght } return; } bit COMP_buff2buff( unsigned char *BUFF1, unsigned char *BUFF2, unsigned char LEN) { while(LEN) { if(*BUFF1++ != *BUFF2++) //Check if both value in address are same. { RXDcmpt = 0; return 0; //One value is different. } LEN--; //Decrement. } //AT Last, all values are the same in both buffers. return 1; } void confirmPBready() { if(COMP_buff2buff(rcx,"+PBREADY", rxd_cnt)) //Check if the value recieved is PBready {PBflag = 1; //YES. So set flag. } return; } void confirmOK() { if( COMP_buff2buff(rcx ,"OK", rxd_cnt))//Check if the value recieved is PBready PBflag = 1; //YES. So set flag. return; } void serial(void) interrupt 4 { unsigned char RXD_VAL; RXD_VAL = SBUF; if(RI) { switch(SERIALcase) { case 1: if(RXD_VAL == 0x0D) {//clear the buffer if the value is 0x0D SERIALcase=2; } break; case 2: if(RXD_VAL == 0x0A) {//clear the buffer if the value is 0x0A SERIALcase = 3; // buffer must receive OD n OA first } break; case 3: if(RXD_VAL == 0x0D) {//the next character should be 0x0A. SERIALcase = 4; //check for 0x0A. } else { rcx[rxd_cnt++] = RXD_VAL; //save the value recieved in rcx buffer } break; case 4: if(RXD_VAL == 0x0A) {//If 0x0A is recieved after 0x0D, then this is the end of recieve frame. RXDcmpt = 1; //set recieve complete flag. } else { rcx[rxd_cnt++] = RXD_VAL; //save the value recieved in rcx buffer } SERIALcase = 1; //its not 0x0A, so go back to keep recieveing till you detect another 0x0D. break; } } RI = 0; } void sendAT(unsigned char *buf) { while(*buf) { SBUF = *buf++; while(!TI); TI=0; } }
Again: have you monitored what the MCU is actually sending, and what is coming back from the modem?
As I said earlier, that should be one of the first things to check!
Yes. The program configures the mcu for serial communication. after which he has to receive +PBREADY before the AT commands can be sent. and yes i do wait for the replies as well.
You didn't answer the question:
Have you monitored, on the wires, what is actually being sent out by the microcontroller, and what is being sent back by the modem?
You need to do this when the microcontroller is connected to the modem.
I have monitored it step by step using keil C debug, is that what yo mean?
Still no response on the multiple comments that you read SBUF before you check RI. You think people are incorrect to mention this?
I wrote codes by myself and all ya be saying codes u got from the net then either you have posted 3 or more times under different names or - by a miracle- two others have written the exact same code,
BTW it is insulting to use things like 'ya' and 'u', we are not teeens playing with smartphones
No!
I said, "on the wire" - that means the physical signals on the physical connections!
AFAIK, the AT89S52 has no on-chip debug facility; so that means you must have been using the Simulator - yes?
http://www.keil.com/forum/62115/
http://www.keil.com/forum/62120/
yes , i have been using the simulator and a vero board in which i designed so whatever is sent out of the modem is seen in the HTerm. the modem does send the information , but the weird thing is the mcu doesnt receive it and when i simulate my laptop as a modem using USBtoSerial cable it works perfectly.
Check connections & baud rates.
You said you're doing this "at work" - do you not have senior colleagues to assist/advise you?
sendAT(txtMOD); while(!PBflag) { if(RXDcmpt && !PBflag) //Check if MCU recieved a value confirmOK(); //Check if its OK. }
Curious: what would happen if confirmOK() never sets the flag? Such as if the modem sends an unsolicited message like "RING"? Or maybe you for some reason gets one corrupt bit in the send or receive of one of the characters. Did you have any plan for how to get out of that loop?
Robust code should have timeouts. And a policy for what to do in case of a timeout.
Why did you start this project with a processor that doesn't allow simple hardware-debugging, so you could debug the program when running the actual chip in the actual circuit? There are work-arounds for old-style 8051 chips but not really workarounds that I would recommend for beginners.
whatever is sent out of the modem is seen in the HTerm
To be clear, what you need to do is to monitor both the Tx and the Rx line simultaneously - something like this:
+----------+ | | | PC | | | +---+---+--+ | | ^ ^ | | | | | | +---------+ | | +---------+ | | | | | | | Tx+->-----------+--------+ | | AT89S52 | | | M590E | | Rx+-<-------+------------+ | | | | | +---------+ +---------+
Then you can be sure that you're seeing everything that's happening between the modem & the MCU.
That design have been a standard tool for embedded developers for a good many years.
There are also nice programs that can record from multiple serial ports while storing exact time stamps just to make it easy to match and combine the send and receive data.
Just one note here is to make sure all parts of the circuit communicates using the same levels. So if 8051 and modem uses TTL levels, then the circuit needs to be wired with two 5V-to-USB serial adapters or use two 5V-to-RS232 converters. Or possibly adapters with 3V3 logic if the modem and processor is running on 3V3.
The modem's voltage levels are compatible with the MCU - aren't they ... ?
And you do have Tx & Rx the correct way around - don't you ?
Note that a modem is a DCE so, strictly, "Tx" should be an input - it is the data to be transmitted over the comms link. But some modem manufacturers try to be "helpful" (sic) and make "Tx" an output...
The skimpy stuff n the net does not tell, is the modem RS232 or TTL?