Maker Pro
Maker Pro

PIC18F4550 Serial Programming issue

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
Hii to all the members here at Electronicspoint.
=======================================



//Program to interface GSM Modem with PIC18F4550 Microcontroller
//This code takes four choices as four inputs
//Choice 1 : Test the simple AT Command.
//Choice 2 : Find out the IMEI number of the GSM Modem.
//Choice 3 : Connect a call to a GSM mobile number.
//Choice 4 : Send a text message to a mobile number.

#define FREQ 12000000
#define baud 9600
#define spbrg_value (((FREQ/64)/baud)-1)
#define rs LATA.F0
#define rw LATA.F1
#define en LATA.F2
#define lcdport LATB

void tx_data(unsigned char);
unsigned char rx_data();
void lcd_ini();
void lcdcmd(unsigned char);
void lcddata(unsigned char);
void gsm_cmd(unsigned char *);
void output(void);

unsigned char value=0;
int i=0,j,k,temp,flag,choice;
unsigned char *starting_text="Enter choice=";
unsigned char *dial_text="Dialing...";
unsigned char *at_cmd="AT";
unsigned char *imei_cmd="AT+GSN";
unsigned char *call_cmd="ATD1xxxxxxxxx;"; // Provide a 10-Digit Mobile Number
unsigned char *sms_format="AT+CMGF=1";
unsigned char *sms_write="AT+CMGS=\"xxxxxxxxxx\""; // 10-Digit Mobile Number
unsigned char *sms="Hello";
unsigned char *sms_report="SMS Sent...";
unsigned char sms_terminate=0x1A;
unsigned char enter=0x0D;
unsigned char *data;

void main()
{
TRISB=0; // Set Port B as output port
LATB=0;
TRISA=0;
LATA=0;
TRISD=0xFF;
LATD=0;
SPBRG=spbrg_value; // Fill SPBRG register to set the baud rate
RCSTA.SPEN=1; // To activate serial port (Tx and Rx pins)
TXSTA.TXEN=1; // Activate Transmissiom
RCSTA.CREN=1; // Activate Reception
PIE1.RCIE=1; // Enable Reception interrupt
INTCON.GIE=1; // Enable Global interrupt
INTCON.PEIE=1; // Enable Peripheral interrupt

lcd_ini();
while(1)
{
k=0;
lcdcmd(0x80);
while(starting_text[k]!='\0')
{
lcddata(starting_text[k]);
k++;
}

//Check inputs

//Choice 1
if(PORTD.F0)
{
gsm_cmd(at_cmd);
output();
Delay_ms(1000);
}


//Choice 2
if(PORTD.F1)
{
gsm_cmd(imei_cmd);
output();
Delay_ms(1000);
}

//Choice 3
if(PORTD.F2)
{
gsm_cmd(call_cmd);
output();
Delay_ms(1000);
}

//Choice 4
if(PORTD.F3)
{
gsm_cmd(sms_format);
output();
Delay_ms(1000);

gsm_cmd(sms_write);
output();
Delay_ms(1000);

gsm_cmd(sms);
output();
tx_data(0x1A);
Delay_ms(1000);
}

}

}

void gsm_cmd(unsigned char *string)
{
i=0;j=0;
while(string!='\0')
{
temp=0;
if(string==0x5C) // Not to send '\' cahracter
i++;
tx_data(string); // Send by serial communication
i++;
while(temp!=1);
}
temp=0;
tx_data(enter); // Send ASCII code for 'Enter' key
while(temp!=1);
}

void output(void) // To print data on LCD
{
lcdcmd(0x01);
i=-1;flag=0;
while(i<j)
{
if(flag>1)
{
flag=0;
Delay_ms(500);
lcdcmd(0x01);
lcdcmd(0x80);
}
if(data==0x0A) // This condition is to avoid double Enter

// during execution of a command
{
flag++;
lcdcmd(0xc0);
}
if(data=='>'||data=='"') // Not to print this character
{
i++;
lcdcmd(0xc0);
}
if(data!=0x0D&&data!=0x0A&&data!=0x1A) // Condition to print the data
// except 'Enter','New line' and 'Submit'

{
lcddata(data);
i++;
}
else
i++;
Delay_ms(300);
}
lcdcmd(0x01);
}

void tx_data(unsigned char serial_data) // Transmit data function
{
TXREG=serial_data;
while(PIR1.TXIF==0);
}


void interrupt()
{
data[j]=RCREG; // Store the data into array when Reception interrupt occurs
value=RCREG;
j++;
temp=1;
}

void lcd_ini()
{
lcdcmd(0x38); // Configure the LCD in 8-bit mode, 2 line and 5x7 font
lcdcmd(0x0C); // Display On and Cursor Off
lcdcmd(0x01); // Clear display screen
lcdcmd(0x06); // Increment cursor
lcdcmd(0x80); // Set cursor position to 1st line, 1st column
}

void lcdcmd(unsigned char cmdout)
{
lcdport=cmdout; //Send command to lcdport=PORTB
rs=0;
rw=0;
en=1;
Delay_ms(10);
en=0;
}

void lcddata(unsigned char dataout)
{
lcdport=dataout; //Send data to lcdport=PORTB
rs=1;
rw=0;
en=1;
Delay_ms(10);
en=0;
}







The Program above is doing the following steps :

1. Store all AT commands into strings.
2. Set the baud rate of microcontroller to 9600bps.
3. Enable serial port. (Refer USART with PIC)
4. Enable the global and peripheral interrupt bits of the INTCON register.
5. Configure Port D as input port.
6. Use if condition to detect the pressed switch.
7. As switch is pressed, process the corresponding AT command and transmit via USART.
8. Reception interrupt method is used to store the GSM output data into an array.
9. Display the stored value on the LCD. (Refer displaying text on LCD using PIC)



I want to modify the above program with only 4th choice (i.e. to send the characters to the mobile number) so that i can do the following steps:

1. Store all AT commands into strings.
2. Set the baud rate of microcontroller to 9600bps.
3. Enable serial port. (Refer USART with PIC)
4. Enable the global and peripheral interrupt bits of the INTCON register.
5. Configure Port D as input port.
6. Process the corresponding AT command and transmit via USART.
7. Recieve the characters at USART (rx) one by one into array.
8. Transmit the characters via the USART (tx)


Would really appreciate if someone can suggest me the required modification that is to be done in the code...
 

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
Functionality to be removed has --, added ++, Moded MOD
-- 7. a. As switch is pressed
MOD 8. Reception interrupt method is used to store the GSM output data into an array. // This will help the new requirement 7.
--9. Display the stored value on the LCD. (Refer displaying text on LCD using PIC)

++7. Recieve the characters at USART (rx) one by one into array.
++8. Transmit the characters via the USART (tx)

So my analysis of the change of requirements. No longer need LCD to display what the PIC UART (rx) from the Computer Terminal. Though now you need to send that the UART(tx) to the GSM. A circuit diagram would help. Is the UART (rx) coming from a PC Terminal so that you can type the message?

If my interpretation is correct. You need a charter that signals to the PIC that this is the end of the message and watch for that in your interrupt. and send the SMS to the GSM module
 
Last edited:

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
I have attached the circuit diagram.
Yes the analysis is correct. I dont need the LCD but need to send the data to the GSM.

No, the UART (rx) is not coming from the PC terminal.
It is coming from the TTL UART (tx).

Any suggestions after observing the diagram.

I did not get your exact meaning ....by charter that signals to the PIC that this is the end of the message and watch for that in your interrupt.
 

Attachments

  • pic18f4550.JPG
    pic18f4550.JPG
    29.1 KB · Views: 927

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
I guess the purpose of ttl uart is to connect the board up to rs232 So you could connect it to a pc and type a message out? Unless your typing the message some other way?

The current code seems to store the data in the data array. At the Rx interrupt. You will need to determine when the full message has been received and the pass it on the the gsm module by transmitting the received message.
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
Yes the TTL is recieving 9600 bps 8N1 Serial stream from other Microcontroller via Rs 232.
PC is not there into picture.

could you help me with a example of sample code (or with some theory) which determines that the full code has been recieved and then it passes the recieved message further.

I mean what logic do we require to determine that the full message has been recieved.
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
Thanks a ton....for such a nice code.
I have got the logic required from your code.

Now the concept is quite clear to me.

Moreover i would request you to provide me with some links where i can download the free version of compiler, linker, hex generator for PIC ...I desperately need one...
 

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
no worries

sorry can't help you there. I'm not that familiar with PIC. though its manufacturer has a decent website and there seems to be an lite and evaluation versions of the compiler that may be cheap or free

http://www.microchip.com/
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
Thanks a ton for help...
I'll go through this site...
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
One more thing i would like to ask

i am having a parallel universal usb programmer...
would it work for the serial programming as well or do i have to purchase a new serial programmer...??

Thanks in advance..
 

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
i do not know. i only have used a commercial bdm, and a open source bdm that my univerity has provided for the freescale s12 processor. the PIC programmer i built back in the day never worked. I still got it, with a bit of patients (i never used to have any) i should get back to it and fix any dry joints it may have.

it would be best to look up the manufacturer and make sure your chip is in the list, or at least the standard that the chip uses is on the list of supported devices.
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
Thanks again....
I'll keep in mind the following points...
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
Hii once again...



#include <REGX51.H>
#include <AT89X51.H>

unsigned char *command_AT = "AT\r";
unsigned char *command_CMGF = "AT+CMGF=1\r";
unsigned char *command_CMGS = "AT+CMGS=\"+8189XXXXX\"\r";
unsigned char *message = "Move";
unsigned char CTRLZ = 0x1A;

void puts(unsigned char* ptr);
void putc(unsigned char chr);
void sendsms(void);
void initialize();

main()
{
initialize();
sendsms();
while(1);
}

void initialize()
{
SCON = 0x50; /*SCON: mode 1, 8-bit UART, enable receive */
TMOD |= 0x20; /*TMOD: timer 1, mode 2, 8-bit */
TH1 = 0xFD; /*TH1: for 9600 baud */
TR1 = 1; /*TR1: timer 1 run */
}

void sendsms()
{
puts(command_AT);
puts(command_CMGF);
puts(command_CMGS);
puts(message);
putc(CTRLZ);
}

void puts(char* p)
{
char *temp = p; /*temp pointer so that the actual pointer is not displaced */
while(*temp != 0x00)
{
putc(*temp);
temp++;
}
}

void putc(unsigned char chr)
{
SBUF = chr;
while(TI==0); /*Wait until the character is completely sent */
TI=0; /*Reset the flag */
}



I have the above the code in which i am able to send only the predefined characters "Pieta" to a predefined number....
but my requirement is to send the characters as they come across...
characters might be Moved0123 or Stop0000000. They might be 9 in length or at times be even 15.

Could you suggest me how to make my code dynamic so that i can send the characters as and when they are recieved....

i wasnt able to gather much help from the code that you had pointed me at Serial Data Communication Using Sim 900 gsm module....
 

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
bring back this code in your original code sample. this assumes that the protocol you receive on the UART will have a null character '\0' in ASCII or 0x00 in hex at the end of the message.

void interrupt()
{
data[j]=RCREG; // Store the data into array when Reception interrupt occurs
value=RCREG;
j++;
temp=1;

if(RCREG == 0x00)
{
sendsms(data); // the contents of data is what has been recieved and is your new message.
j = 0; //reset the index. .
}
}

now if the string "Stop\0" was received this will be received character per character by the SCI interrupt, and then when the '\0' is received it know to send the sms using the function supplied know accepting a char array or pointer as input.
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
I am working on the code....:)

In meanwhile
one more thing i am having 0 at my RX and want it to send to TX

as you mentioned

if(RCREG == 0x00)
{
sendsms(data); // the contents of data is what has been recieved and is your new message.
j = 0; //reset the index. .
}

now my issue is....Is this "data" (above in code) equals to 0..???
because i need to send 0 as well along with other characters...

And if not then i would be getting '\0' or 0x00 which would probably be unexpected...
 

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
You are sending characters encoded into ASCII to the gsm modem.

'0' = 0x30 // the number 0 encoded in ASCII
'\0' = 0x00 // the escape character followed by the number 0 is the null character.

See http://www.asciitable.com/.
 

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
ok got it...
so for sending all these zero characters along with others, shall i use '\0' or 0x00...??
 

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
There are 2 protocols here.
1. Receiving messages (rx) From an UART which is being transmitted by another 3rd party micro that you have no control over. I'm assuming you are only receiving a message and the phone number is fixed. Your example had the code indicating it was waiting for the null character 0x00 so I assumed that was the case and part of the established protocol.
2. Sending the at commands (tx). This protocol is using AT commands. Ie. the output should be no different to your static test message except that you replace your message from what is received. Your example finishes with "\r" so that maybe that you should add and not "\0"
 
Last edited:

Pieta

Aug 10, 2012
13
Joined
Aug 10, 2012
Messages
13
Yes you are correct because i need '\r' at last...

also my code is waiting for the null character 0x00

but as per the ascii table 0x00 in hex = 0
now what happens if i recieve 0 in the data that has to be transfferd to gsm...

How will the code be able to distinguish the difference between a 0 (data)
and
0 (as a null character)...

request you to please provide me some knowledge on this...
 

dahhal

Jul 17, 2012
58
Joined
Jul 17, 2012
Messages
58
you don't need to send 0x00 as part of your at phone number. You will send the number 0 in ASCII '0x30' as part of the string. you will see the ASCII to be 0x30 if you were to look at it in binary.

for example when sending your sample message. i filled in the number to illustrate the point.
unsigned char *command_CMGS = "AT+CMGS=\"+8189330222\"\r";

each character of the char array will be sent one at time.
char[0] ='A'
char[1] ='T'
char[2] ='+'
char[3] ='C'
char[4] ='M'
char[5] ='G'
char[6] ='S'
char[7] ='='
char[8] ='"'
char[9] =''"'
char[10] ='+'
char[11] ='8'
char[12] ='1'
char[13] ='8'
char[14] ='9'
char[15] ='3'
char[16] ='3'
char[17] ='0'
char[18] ='2'
char[19] ='2'
char[20] ='2'
char[21] ='\r'
char[22] ='\0'
 
Last edited:
Top