I have attached the programming that i did from reference to the Data sheet of PIC16F873A.
I'm not familiar with the PIC's serial port architecture so I don't know whether your other initialisation code is correct or not, but there is an obvious bug here:
Code:
for (i=0;i<2;i++)
{
TXREG=a[i];
}
txreg=0x0D;
Each time you place a character into the USART's transmit register (TXREG), you have to wait until the USART has transferred it to the transmit shift register (TSR) before you place the next character into the transmit register. If you don't wait, it will overwrite the previous value in TXREG and characters will be lost.
Also your code is poorly structured. You should use separate functions to send characters and strings to the serial port, not a whole lot of for() loops and extra code in the mainline. The string transmit function can detect the null ('\0') character at the end of the string, so you don't need to pass an explicit string length to it; it just needs a pointer to the start of the string.
Here's what I suggest:
Code:
void usart_tx_char(char c) // Transmit a single character, c, through the USART.
//** warning: this function could get stuck forever,
//** waiting for TXREG to become empty if the USART
//** transmitter is disabled or the baud rate generator
//** is not working.
{
while (TXIF == 0)
; // Wait while TXREG is full (TXIF is 0)
TXREG = c; // Output character to USART
}//usart_tx_char
void usart_tx_string(char * cp) // Transmit a character string through the USART.
{
auto char c;
while ((c = *cp++) != '\0') // For every character until the final null
usart_tx_char(c); // Transmit the character from the string
}//usart_tx_string
void usart_tx_string_cr(char * cp) // Transmit a character string plus a final carriage return through the USART.
{
usart_tx_string(cp); // Transmit the character from the string
usart_tx_char('\x0D'); // Transmit a carriage return
}//usart_tx_string_cr
void main(void)
{
///// (put your initialisation code here).
usart_tx_string_cr("AT");
usart_tx_string_cr("AT+CMGF=1");
usart_tx_string_cr("AT+CMGF=999999999");
usart_tx_string_cr("HI"); // "Hai" is not a word
usart_tx_string("CMGC=\x1A");
}//main
You can avoid the usart_tx_string_cr() function and just use usart_tx_string() if you put the carriage return into each string you want to transmit. For example, replace usart_tx_string_cr("AT"); with usart_tx_string("AT\x0D");
The character combination \x0D means a character with a hex value of 0x0D (13 decimal), which is a carriage return character in the ASCII character set.
The character '\x1A' is a Ctrl-Z. ASCII number 26. That last string is transmitted without a final carriage return; I'm not sure whether it should have one or not.
You don't need to specify the number of characters in explicitly defined strings inside the square brackets after the variable name; the compiler can figure that out for itself! Each string will be stored as the sequence of characters you specify, plus a final null character ('\0' or '\x00'). This null terminator is used by usart_tx_string() to detect the end of the string.
These simplifications shorten your program by about 30% and make it much more readable.
Edit: You can also use the \r instead of \x0D. Don't use \n (newline); it's actually a line feed (0x0A).