Будем использовать команды стандарта GSM07.05.
Перед отправкой сообщения необходимо провести подготовку модуля.
Сначала перевести формат передаваемого модулю текста сообщения в текстовый режим командой «AT+CMGF=1\\r».
По умолчанию используется режим PDU, сообщения передаются в HEX-виде, что есть неудобно.
Переключаем кодировку на GSM командой «AT+CSCS=»GSM»\\r».
Кодировка определяет в каком виде будут передаваться номера телефонов, тексты сообщений и USSD-запросы.
Самой удобный является «GSM», где символы представлены в ASCII кодах и их без труда понимает компилятор.
Но есть минусы будет доступна только латиница.
Для кириллицы необходимо использовать режим «UCS2» Unicode. Далее пока рассмотрим вариан с кириллицей

Отправляем СМС-сообщение.
а) Посылаем «AT+CMGS=»+79XXXXXXXXX»\\r», получаем в ответ приглашение набрать текст сообщения — символ ‘>’.
б) Отправляем текст. По окончании нужно отправить код комбинации клавиш Ctrl+Z (код 0x1A), только тогда модуль поймет, что текст набран и можно посылать сообщение адресату.
в)Получаем «OK» — поздравляю, сообщение улетело.

Ниже пример функции отправки:
/**
 * Отправляет SMS-сообщение
 * @param number - номер получателя, строка char
 * @param msg - текст сообщения
 * @return - OK, если сообщение отправлено, иначе ERROR
 */
int8_t Sim900_SendSMS (char * number, char* msg)
{
    /// Перевод модуля в режим работы с тектовыми сообщениями
    if (Sim900_WriteCmdWithCheck("AT+CMGF=1\r"))
	return ERROR;
 
    /// Включаем кодировку GSM
    if (Sim900_WriteCmdWithCheck("AT+CSCS=\"GSM\"\r"))
	return ERROR;
 
    Sim900_WriteCmd("AT+CMGS=\"");	/// Команда отправить SMS
    Sim900_WriteCmd(number); /// Ввод номера абонента
    DelayMs(100); /// Задержка на запись
    Sim900_WriteCmd("\"\r");
 
    /// Ожидаем символ готовности ввода текста
    if (Sim900_CompareStr(">"))
	return ERROR;
 
    Sim900_WriteCmd(msg);
    /// Отправляем комбинацию окончания  ввода Ctrl+Z
    PutCharToSim900(0x1A);	/// Отправка байта кода Ctrl+Z
 
    /// Если нет подтверждения, возвращаем код ошибки
    if (Sim900_CompareStr("OK"))
	return ERROR;
 
    return OK;
}

Общение с модулем при работе с СМС построено на индексах.
Каждому сообщению присваивается индекс, по нему мы указываем, какое сообщение прочитать/удалить.
При получении нового сообщения модуль уведомит отправкой в UART «+CMTI: «SM»,INDEX\\r».
Значит в программе МК надо постоянно проверять приемный буфер на наличие данного сообщения, находить INDEX и сохранять его.

/**
 * Проверяет, принято ли новое собщение, и возвращает его индекс
 * @return - индекс нового SMS-сообщения
 */
uint32_t Sim900_EventNewSMS(void)
{
    struct TBufferUsart *buffer = &BUFFER; /// Указатель на буфер UART
    const int8_t size = 4;
    char ch[size]; /// Массив для хранения принятого индекса
    uint8_t i = 0;
    uint32_t pos;
 
    char cmd[] = "+CMTI: \"SM\",";
    if (buffer->rxflag == RX_COMPLETE)
    {
	if (Sim900_CompareStr(cmd) != NULL)
        {
            pos = sizeof(cmd) - 1;
	    /// Заполнение массива цифрами индекса
	    while (buffer->rxbuf[pos] != '\r'){
		ch[i++] = buffer->rxbuf[pos++];
	    }
	    ch[i] = '\0';
 
	    /// Преобразование строки с индексом в число
	    return ConvertStringToNumber(ch);
	}
    }
 
    return 0;
}

Можно упростить код разбора принятого сообщения с выделением его индекса если использовать библиотечную sscanf. Но дело в том, что sscanf и printf объемны и не всегда уместны во встраиваемых системах.

Зная индекс принятого сообщения, прочитать и удалить его не составит труда.
Прочитать одно сообщение — «AT+CMGR=INDEX,0\\r», второй параметр:
0 — обычный режим (по умолчанию)
1 — не изменять состояние сообщения.
Получим ответ вида:
«+CMGR: “REC UNREAD”,“+79XXXXXXXXX”, «» ,”DATE,TIME”\\r\\nMessage text\\r\\n\\r\\nOK»
REC UNREAD — группа сообщений (см. ниже), DATE – дата формата YY/MM/DD, TIME – время в формате hh:mm:ss±hh.

Удалить одно сообщение по индексу — «AT+CMGD=INDEX\\r».

Удалить сообщения по критерию — «AT+CMGD=INDEX,FLAG\\r», где FLAG:
0 — удалить сообщение по индексу (по умолчанию)
1 — удалить все прочитанные сообщения 2 — удалить прочитанные и отправленные сообщения
3 — удалить прочитанные, отправленные и не отправленные сообщения
4 — удалить все сообщения.
Исходя из вышеуказанного, удалить все сообщения — «AT+CMGD=1,4\\r».

Прочитать группу сообщений — «AT+CMGL=”GROUP”\\r», где параметр GROUP имеет следующие значения, числовое/текстовое:
0/REC UNREAD — все непрочитанные сообщения;
1/REC READ — прочитанные сообщения,
2/STO UNSENT — все не отправленные,
3/STO SENT — все отправленные,
4/ALL – все сообщения.

Cписок комманд при работе с SMS.

AT+CMGF=1 Включение текстового режима данных
AT+CSCS=»GSM» Выбор ASCII кодировки
AT+CMGS=(см. выше) Отправка SMS-сообщения
+CMTI: «SM»,INDEX Получение индекса нового SMS-сообщения
AT+CMGR=INDEX,0 Чтение сообщение по индексу
AT+CMGD=INDEX Удаление одного сообщения по индексу
AT+CMGD=INDEX,FLAG Удаление сообщения по критерию
AT+CMGL=”GROUP” Чтение группы сообщений