STM32 - GSM





Здравствуйте.

Пример для работы stm32 с GSM-модулем, который умеет принимать звонки и перезванивать, принимать и отсылать смс, отсылать смс с балансом на модуле, и выполнять какие-либо действия по звонку, смс или DTMF сигналам. В общем может работать как система удалённого управления чем-либо.

Всё тестировалось на стареньком модуле SIM900, думаю и на SIM800 будет работать, но не гарантирую. Пример сделан для платы BluePill (F103C8).



Пример использует два USART'а №1 и №3, к первому нужно подключить модуль, а третий соединить с компьютером через USB to TTL конвертер для вывода отладочных сообщений и отправки команд модулю через терминал (скорость 57600).


Если у вас BluePill, то можно просто прошить пример. Если плата другая, то нужно создать проект (предполагается что он создаётся в Cube), активировать оба USART'а (1 и 3) и включить у них прерывания. В принципе этого достаточно для работы, но у меня сделано ещё так, чтоб раз в секунду запрашивать у модуля время (просто для наглядности), поэтому настройте ещё таймер №4 на ежесекундное переполнение и опять же включите прерывание…



Для 72мГц.


Активируйте какой-нибудь пин как Output и назовите его ER_LED



К этому пину нужно подключить светик, который будет сигнализировать об ошибке. Удобнее всего использовать PC13, но у меня он перегорел, поэтому я задействовал PA7.

Добавьте в проект файлы gsm.c, gsm.h, usart_ring.c и usart_ring.h..

В файле stm32f1xx_it.c измените обработчики прерываний USART'ов как в примере, добавьте инклюд и переменные.

Из main.c примера скопируйте инклюды, дефайн, переменные и функции.

Подключайте все проводочки и прошивайте — после старта, программа выяснит текущую скорость UART'а модуля, выведет её в терминал, и автоматически настроит скорость 57600. То есть никаких подготовительных действий с модулем не требуется.

После этого будет произведена настройка модуля с выводом подтверждения об успешных действиях, и некоторая информация…



Описание команд в файле gsm.h.


В начале программы делается небольшая пауза чтоб модуль успел инициализироваться если он отключается/включается вместе с ресетом платы. В примере указано 5 сек, можно попробовать уменьшить, главное чтоб при старте модуль вернул +CREG: 0,1. Если при ресете платы модуль остаётся включённым, то паузу можно убрать.

Если модуль не вернёт правильного ответа на какую-либо из команд показанных выше, то программа прекратит дальнейшее выполнение, в терминал будет выведена инфа о том, какая команда не отработала, а ER_LED начнёт мигать. Если в файле gsm.c, в функции set_comand(char *buff), расскомментировать строчки…

//if(count_err > 49) HAL_NVIC_SystemReset();

… тогда плата будет ресетиться через 5 сек. А если ещё и модуль запитать через реле, и добавить пин для его управления, тогда и модуль можно будет перегружать вместе с платой. В main.c у меня есть закомментированные строки для этого...

/* USER CODE BEGIN 2 */
//HAL_Delay(1000);
//HAL_GPIO_WritePin(ON_RELAY_GPIO_Port, ON_RELAY_Pin, GPIO_PIN_SET);


про включение модуля
Про то какой у меня модуль, и как он запитан, и про кнопку «Power» смотрите здесь.


Далее инициализируются прерывания USART'ов, проверяется и устанавливается скорость — chek_speed(), и подаются команды настройки — set_comand(...). Функция set_comand(...) отправляет модулю различные АТ-команды, которые прописаны в файле gsm.h. В примере всё прокомментировано, поэтому повторятся не буду. Сейчас там настроено на звонки и смс, но если смс не нужны, то удалите блок «настройки для работы с sms», и блок «различная инфа» тоже не особо то и нужен, так, для красоты. В примере прописаны необходимые для работы команды, если нужно что-то ещё, то смотрите в файле gsm.h и в справочнике по АТ-командам, их там море, и ещё вот тут.

Функция set_comand(...) служит только для начальной настройки (при старте МК), использовать её где-то в других местах программы не нужно. Некоторые команды, которые могут понадобиться в процессе работы, я сделал отдельными функциями…

balance() — отправит команду проверки баланса.

disable_connection() — разорвёт все соединения (звонки).

call() — позвонит на указанный номер (прописать в файле gsm.c).

incoming_call() — принять входящий звонок.

get_date_time() — узнать дату/время на модуле.

Работа этих функций продемонстрирована в примере, а посмотреть их и добавить что-то своё можно в файле gsm.c. Помимо этого, АТ-команды можно отправлять модулю вручную, через терминал…




Файлы usart_ring.c и usart_ring.h отвечают за кольцевые буферы USART'ов, если вывод отладочной инфы и ввод команд в терминал не нужен, то можно выпилить USART №3 (DEBUG). Однако не спешите это делать пока всё не отладите


Теперь о коде.

if(flag == 1)
{
    flag = 0;
    //get_date_time(); 
}

Выполнение чего-нибудь раз в секунду, в частности запрос времени на модуле, как писалось выше — сделано просто для наглядности.


Далее в цикле крутится проверка — if(gsm_available()) прилетело ли что-то от модуля. Всё что происходит в модуле, он «выплёвывает» в USART1, а мы это ловим и смотрим что за строка (всё это выводится в терминал). Например модуль посылает слово «RING» — это значит что кто-то звонит, мы проверяем что за номер и выполняем соответствующее действия. В общем в коде всё прокомментировано — не знаю что добавить. Единственный момент — МТС при проверке баланса присылает слово «Balance», а вот что шлют другие операторы я не знаю. Проверить можно послав в терминал команду ATD#100#; (в конце точка с запятой)


Надо немножко подождать.

Блок с балансом закомментирован специально, чтоб модуль не слал смски пока вы тестируете программу.


DTMF — очень удобная штука. Звоните на модем, он определяет что это ваш номер и «поднимает трубку» — incoming_call(), после этого можно посылать DTMF-сигналы нажимая кнопки на телефоне. Таким образом можно послать 12 различных команд-сигналов (0-9, *, #).

Сечас команда включения DTMF подаётся так — AT+DDET=1, а если добавить ещё один параметр — AT+DDET=1,1, то будет показывать длительность нажатия кнопки. То есть можно нажать и удерживать кнопку, а модем покажет время в миллисекундах…



Чтоб использовать длительность, надо для этого дописать код (в примере нету), поэтому отключите — AT+DDET=1,0.


В самом конце, функция if(dbg_available()) ловит всё что вы пошлёте в терминал, и отправляет модулю.


Если нужно забирать с модуля какие-то данные, допустим температуру с датчиков подключённых к микроконтроллеру, то можно отправлять их смсками, собственно другого способа то и нет. Например, звоним на модуль, посылаем DTMF-сигнал кнопки 1, а модуль в ответ на это отправляет смс с температурой датчика №1.


Всякий свой функционал просто добавляйте в бесконечный цикл, работе с модулем это не помешает.


GPIO
У моего модуля выведены несколько GPIO, подавать HIGH или LOW, и считывать состояние можно так…



Чтоб управлять светиком подключённым к GPIO №3 нужно сделать так:

AT+SGPIO=0,3,1,1 — включаем.

AT+SGPIO=0,3,1,0 — отключаем.

Чтобы читать состояние на GPIO №3 нужно вначале перевести пин в состояние input:

AT+SGPIO=0,3,0,0

А потом читать состояние:

AT+SGPIO=1,3

Чтение ADC:

AT+CADC=? — инфа.

AT+CADC? — читать значение.

Управление PWM смотрите в справочнике (ссылка выше) — команда AT+SPWM.

Keypad — можно настроить и подключить кнопки — получится телефон, только экран нужно ещё подключить по SPI (имеется в виду к SPI самого модуля).


Если в ответ на те или иные команды прилетает ERROR, тогда можно дать команду AT+CMEE=2, и ошибки будут приходить с расшифровкой. Отключить — AT+CMEE=0. Если дать команду AT+CMEE=1, то вместо расшифровки будет приходить цифровой код ошибки.


В общем разбирайтесь с либой (хотя чего там разбираться то), настраивайте действия на звонки и смс, прописывайте смс-команды, а когда всё отладите можете удалить USART3 и пользоваться, или не удалять, никому он не мешает.

Работа с интернетом в следующей части, на этом всё.

Пример

И ещё удобный справочник по AT-командам



Всем спасибо


Телеграм-чат istarik

Телеграм-чат STM32


  • 0
  • 20937
Поддержать автора


Telegram-чат istarik

Задать вопрос по статье
Telegram-канал istarik

Известит Вас о новых публикациях






Комментарии (0)

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.