Ramche
Newbie level 1
I'm working on a project about remote controlled house (home automation). This is for my capstone project which I'm working on.:smile:
I want to send SMS messages from my mobile phone to a Telit GM862 GSM device and those messages need to pass throw UART to a 8051 microcontroller (Atmel AT89S8253). The microcontroller needs to understand them as commands and it needs to switch on or off some relays.
I have an exaple program which is made by MikroElektronika, and its goal is to display some basic functions of the GSM module like making and answering a call and hanging up. I installed this program on the microcontroller, and it worked.
I have no experience with C, so I need someone to help me for better understanding how works this code, and what I have to modify on this code to reach my goal?:roll:
The code is like:
I want to send SMS messages from my mobile phone to a Telit GM862 GSM device and those messages need to pass throw UART to a 8051 microcontroller (Atmel AT89S8253). The microcontroller needs to understand them as commands and it needs to switch on or off some relays.
I have an exaple program which is made by MikroElektronika, and its goal is to display some basic functions of the GSM module like making and answering a call and hanging up. I installed this program on the microcontroller, and it worked.
I have no experience with C, so I need someone to help me for better understanding how works this code, and what I have to modify on this code to reach my goal?:roll:
The code is like:
Code:
// LCD module connections
sbit LCD_RS at P2_0_bit;
sbit LCD_EN at P2_1_bit;
sbit LCD_D4 at P2_2_bit;
sbit LCD_D5 at P2_3_bit;
sbit LCD_D6 at P2_4_bit;
sbit LCD_D7 at P2_5_bit;
// End LCD module connections
// set of AT commands
const char atc1[] = "ATE0"; // disable echo
const char atc2[] = "AT# CAP= 1"; // enables handsfree external mic/ear audio path
const char atc3[] = "ATD123456789;"; // place a call to phone number 123456789
// instead of 123456789 insert your phone number
const char atc4[] = "ATH"; // hang up
const char atc5[] = "ATA"; // answer a call
const char atc6[] = "AT#HFMICG=4"; // handsfree microphone gain
const char atc7[] = "AT#SHFEC=1"; // handsfree echo canceller
const char atc8[] = "AT+CLVL=12"; // loudspeaker volume level
const char atc9[] = "AT#SRS= 3,0"; // select ringer sound
const char atc10[] = "ATS0=0"; // number of rings to auto answer (auto answer disabled)
// lcd interface messages
const LCD_MESSAGE_LENGTH = 16;
const char lcd1[] = "Initializing...";
const char lcd2[] = "Power-Up GSM!!!";
const char lcd3[] = "P0.3-Continue";
const char lcd4[] = "Ready! P0.0-Dial";
const char lcd5[] = "P0.1-HG P0.2-AW";
const char lcd6[] = "Calling...";
const char lcd7[] = "Hanging Up!";
const char lcd8[] = "Answering!";
const char lcd9[] = "RING!!!";
// responses to parse
const GSM_OK = 0;
const GSM_RING = 1;
char gsm_state = 0;
char response_rcvd = 0;
short responseID = -1, response = -1;
char msg[LCD_MESSAGE_LENGTH+1];
// copy const to ram string
char * CopyConst2Ram(char * dest, const char * src){
char * d ;
d = dest;
for(;*dest++ = *src++;)
;
return d;
}
// uart rx interrupt handler
void interrupt() org IVT_ADDR_ES {
char tmp;
EA_bit = 0; // Clear global interrupt enable flag
if (RI_bit) { // do we have uart rx interrupt request?
tmp = UART1_Read(); // get received byte
// process reception through state machine
// we are parsing only "OK" and "RING" responses
switch (gsm_state) {
case 0: {
response = -1; // clear response
if (tmp == 'O') // we have 'O', it could be "OK"
gsm_state = 1; // expecting 'K'
if (tmp == 'R') // we have 'R', it could be "RING"
gsm_state = 10; // expecting 'I'
break;
}
case 1: {
if (tmp == 'K') { // we have 'K' ->
response = GSM_OK; // we have "OK" response
gsm_state = 50; // expecting CR+LF
}
else
gsm_state = 0; // reset state machine
break;
}
case 10: {
if (tmp == 'I') // we have 'I', it could be "RING"
gsm_state = 11; // expecting 'N'
else
gsm_state = 0; // reset state machine
break;
}
case 11: {
if (tmp == 'N') // we have 'N', it could be "RING"
gsm_state = 12; // expecting 'G'
else
gsm_state = 0; // reset state machine
break;
}
case 12: {
if (tmp == 'G') { // we have 'G' ->
response = GSM_RING; // we have "RING" response
gsm_state = 50; // expecting CR+LF
}
else
gsm_state = 0; // reset state machine
break;
}
case 50: {
if (tmp == 13) // we have 13, it could be CR+LF
gsm_state = 51; // expecting LF
else
gsm_state = 0; // reset state machine
break;
}
case 51: {
if (tmp == 10) { // we have LF, response is complete
response_rcvd = 1; // set reception flag
responseID = response; // set response ID
}
gsm_state = 0; // reset state machine
break;
}
default: { // unwanted character
gsm_state = 0; // reset state machine
break;
}
}
RI_bit = 0; // clear UART interrupt flag
}
EA_bit = 1; // Set global interrupt enable flag
}
// send ATC command
void send_atc(const char *s)
{
// send command string
while(*s) {
UART1_Write(*s++);
}
// terminate command with CR
UART1_Write(0x0D);
}
// get GSM response, if there is any
short get_response() {
if (response_rcvd) {
response_rcvd = 0;
return responseID;
}
else
return -1;
}
// wait for GSM response: OK
void wait_GSM_OK() {
while (get_response() != GSM_OK);
}
// pause
void wait() {
Delay_ms(1000);
}
void main() {
P1_0_bit = 1;
UART1_Init(4800); // initialize UART1 module
Delay_ms(100);
// set RTS pin to zero, we will use only RX i TX
P3_3_bit = 0;
ES_bit = 1; // enable UART interrupt
RI_bit = 0; // clear UART RX interrupt flag
EA_bit = 1; // enable interrupts
// setup lcd module
Lcd_Init();
Lcd_Cmd(_LCD_CURSOR_OFF);
// LCD_Out: power-up gsm
LCD_Out(1,1,CopyConst2Ram(msg,lcd2));
LCD_Out(2,1,CopyConst2Ram(msg,lcd3));
// wait for start
while(P0_3_bit)
;
Lcd_Cmd(_LCD_CLEAR);
// LCD_Out: Initializing...
LCD_Out(1,1,CopyConst2Ram(msg,lcd1));
Delay_ms(2000); // wait for the GSM module to initialize it self
// negotiate baud rate
while(1) {
send_atc("AT"); // send "AT" string until gsm sets up its baud rade
Delay_ms(100); // and gets it correctly
if (get_response() == GSM_OK) // if gsm says "OK" on our baud rate we got it
break;
}
// disable command echo
send_atc(atc1);
wait_GSM_OK();
// change audio path (enables handsfree external mic/ear audio path)
send_atc(atc2);
wait_GSM_OK();
// handsfree microphone gain
send_atc(atc6);
wait_GSM_OK();
// handsfree echo canceller
send_atc(atc7);
wait_GSM_OK();
// loudspeaker volume level
send_atc(atc8);
wait_GSM_OK();
// select ringer sound
send_atc(atc9);
wait_GSM_OK();
// number of rings to auto answer (auto answer disabled)
send_atc(atc10);
wait_GSM_OK();
while(1) {
// LCD_Out: Ready! P0.0-Dial
LCD_Out(1,1,CopyConst2Ram(msg,lcd4));
// LCD_Out: P0.1-HNG P0.2-ASW
LCD_Out(2,1,CopyConst2Ram(msg,lcd5));
if(!P0_0_bit) {
// LCD_Out: Calling...
Lcd_Cmd(_LCD_CLEAR);
LCD_Out(1,1,CopyConst2Ram(msg,lcd6));
// mobile originated call to specified number
send_atc(atc3);
wait_GSM_OK();
}
if(!P0_1_bit) {
// disconnect existing connection
send_atc(atc4);
wait_GSM_OK();
Lcd_Cmd(_LCD_CLEAR);
// LCD_Out: Hanging Up!
LCD_Out(1,1,CopyConst2Ram(msg,lcd7));
wait();
}
if(!P0_2_bit) {
// answer a call
send_atc(atc5);
wait_GSM_OK();
Lcd_Cmd(_LCD_CLEAR);
// LCD_Out: Answering!
LCD_Out(1,1,CopyConst2Ram(msg,lcd8));
wait();
}
// process gsm response
if (response_rcvd) {
response_rcvd = 0; // clear response received flag
switch (responseID) {
case GSM_OK : break; // do nothing
case GSM_RING : {
// LCD_Out:RING!!!
LCD_Out(1,1,CopyConst2Ram(msg,lcd9));
wait();
}
default : {
// process illegal responses
}
}
}
}
}