Вот мой код для модема. Актуальность - 2024 год, Март.
Выложил основное тело. Всякие очереди и методы СМСок не будут компилироваться.
Мой код отличается от твоего тем, что у меня в конфигурации заданы параметры порта.
Код:PROGRAM TaskSMS (* Управление модемом ПМ-01 для приёма и отправки СМСок *) VAR (* Внешние переменные для задачи архивации *) bExtCfgError : BOOL; (* Внешний флаг ошибки *) bExtCfgErrorCode : WORD; (* Внешний код ошибки *) (* Конфигурация модема и объекты работы с СМСками *) fbSMSPort : OpenPort; (* Порт модема *) fbSMSConfig : FB_SMS_CFG; (* Настройки модема *) fbSMSObject : FB_SMS_SR; (* Объект приёма и отправки СМСок *) bCfgOK : BOOL := FALSE; (* Флаг того, что модем успешно настроен и готов к работе *) bCfgError : BOOL := FALSE; (* Флаг того, что при настройке модема была ошибка *) wCfgErrCode : WORD := 0; (* Код ошибки модема *) fbCfgErrorPulse : TP; (* Таймер выдержки ошибки настроек модема *) fbCfgErrorExt : TOF; (* Таймер выдержки ошибки настроек модема для задачи Архиваии *) (* Переменные для приёма и отправки СМСок *) fbSMSInbound : R_TRIG; (* Отслеживание фронта новых СМСок *) bReadyToSend : BOOL; (* Флаг того, что мы посылаем СМСку *) bInSendMode : BOOL; (* Флаг того, что мы ждём конца отправки СМСки *) END_VAR VAR_TEMP iPosRcv : WORD := 0; (* Счётчик очереди приёма СМСок *) iPosSnd : WORD := 0; (* Счётчик очереди отправки СМСок *) END_VAR VAR CONSTANT UNMDevNumber : WORD := 0; (* Номер UNM-устройства (с нуля) для порта модема *) CFGErrorDelay : TIME := t#60s; (* Время выдержки ошибки настроек модема *) CFGErrorExtTime : TIME := t#120s; (* Время выдержки ошибки настроек модема для задачи архивации *) END_VARКод:(***************************************************************************************) (* Для начала смотрим на то, включено ли питание модема вообще. Если включено - пробуем его настроить. *) IF (hwCtlPowerPM = TRUE) THEN fbSMSPort(Enable:= TRUE, DeviceNumber:= UNMDevNumber); fbSMSConfig(Enable:= (fbSMSPort.OUT AND NOT bCfgError), Handle:= UNMDevNumber, PortCfg:= TRUE, SaveCfg:= FALSE, ModemART:= FALSE, PortBaudrate:= '9600', PortParity:= 0, PortStopBits:= 1, PortByteSize:= 8, PortFlowCtrl:= 0 ); (* Забираем код ошибки и выставляем флаг ошибки или успеха *) fbCfgErrorPulse(IN:= (fbSMSConfig.ErrCode <> 0), PT:= CFGErrorDelay); IF (fbCfgErrorPulse.IN) THEN (* Сохраняем код последней ошибки *) wCfgErrCode := fbSMSConfig.ErrCode; bExtCfgErrorCode := wCfgErrCode; END_IF bCfgError := fbCfgErrorPulse.Q; bCfgOK := fbSMSConfig.Done AND NOT bCfgError; (* Передаём значения ошибок на внешнюю задачу Архивации *) fbCfgErrorExt(IN := bCfgError, PT := CFGErrorExtTime); bExtCfgError := fbCfgErrorExt.Q; ELSE (* Если модем выключен - закрываем порт и выключаем его, сбрасываем ошибки *) fbSMSPort(Enable:= FALSE, DeviceNumber:= UNMDevNumber); fbSMSConfig(Enable:= FALSE); fbCfgErrorPulse(IN := FALSE, PT := t#0ms); fbCfgErrorExt(IN := FALSE, PT := t#0ms); bCfgOK := FALSE; bCfgError := FALSE; wCfgErrCode := 0; END_IF (* Сброс сигналов ошибок, если модем прошёл конфигурацию *) IF (bCfgOK = TRUE) THEN bExtCfgError := FALSE; bExtCfgErrorCode := 0; END_IF (***************************************************************************************) (* РАБОТА С МОДЕМОМ, ЕСЛИ ОН УСПЕШНО НАСТРОЕН *) fbSMSObject( Enable := bCfgOK, Handle := UNMDevNumber, CsdClose := TRUE, (* Запрет входящих звонков; модем всегда вешает трубку *) CheckNum := SMSSettingsSequreInbound, (* Проверять номер входящих СМСок по списку разрешённых? *) CheckNumList := SMSSettingsSequreNumbers, (* Список разрешённых номеров через ; без + и скобок: 71231234567 *) (* Следующием переменные рапсисаны для наглядности и справки по их назначениям в дальнейшем коде программы *) Busy => , (* Блок занят и что-то делает *) ErrCode => , (* Код ошибки *) SmsSend => , (* СМСка успешно отослана (можно дёргать следующее из очереди) *) SendSms := , (* Команда запуска отправки СМСки (TRUE) *) SendSmsText := , (* Текст СМСки, которую надо отсылать *) SendSmsNum := , (* Номер, куда её надо отсылать *) NewInSms => , (* Найдено новое входящее СМС - его надо обработать *) NewInRing => , (* Есть входящий звонок (плевать на него =)) *) NewInSmsText => , (* Текст новой входящей СМСки *) NewInSmsTime => , (* Время новой входящей СМСки *) NewInSmsNum => (* Номер, с которого отправили входящую СМСку *) ); (***************************************************************************************) (* Этому блоку нужна обёртка из двух фич: а) Очередь исходящих СМСок: массив данных (структур), куда мы пихаем новую СМСку и забываем про неё. Когда блок свободен (.Busy = FALSE) и нет новых входящих СМСок (.NewInSms = FALSE), то мы извлекаем СМСки из очереди по одной и отсылаем их блоку, ожидая его готовности по .SmsSend. б) Очередь входящих СМСок: тоже массив данных (можно тех же структур). Работает по тому же принципу: Как только пришла входящая СМСка, читаенм её из FB и пихаем в эту очередь. Дальше, если очередь не пуста - извлекаем из неё СМСку и обрабатываем её. *) (***************************************************************************************) (* ОБРАБОТКА: Очередь Исходящих СМСок *) IF (fbSMSObject.Busy = FALSE) THEN (* Работаем только если блок НЕ занят операциями *) IF (bReadyToSend = FALSE) THEN fbSMSObject.SendSms := FALSE; (* Скидываем команду отправки СМСки *) SMSOpDoSend(); (* Подготовка первой СМСки в отправке. Если она готова - выставится флаг bReadyToSend *) ELSE (* Работа по отправке СМСки и ожиданию успеха в этом *) (* Здесь логика пизданутая: надо выставить флаг "SendSms" на некоторое время, а потом дожидаться флага SmsSend, после чего выходить из этого блока. Прям просится конечный автомат, но так как тут всего два состояния - делаем на IFах. *) IF (bInSendMode = FALSE) THEN (* Если мы не в режиме отправки СМСки, то входим в него *) bInSendMode := TRUE; (* Входим в режим отправки СМСок *) ELSE (* Мы в режиме отправки СМСки. Выставляем флаг отправки и ждём, когда всё будет ОК *) fbSMSObject.SendSms := TRUE; (* Выставляем флаг отправки СМСки *) IF (fbSMSObject.SmsSend = TRUE) THEN (* Если СМСка отправлена успешно - выходим из режима отправки *) fbSMSObject.SendSms := FALSE; (* Скидываем команду отправки СМСки *) (* Скидываем все флаги отправки СМСок *) bReadyToSend := FALSE; bInSendMode := FALSE; END_IF END_IF END_IF END_IF (* Дополнительная заглушка: если СМСка отправилась в любом режиме (даже если блок Busy) - выходим из режима отправки *) IF (fbSMSObject.SmsSend = TRUE) THEN fbSMSObject.SendSms := FALSE; (* Скидываем команду отправки СМСки *) (* Скидываем все флаги отправки СМСок *) bReadyToSend := FALSE; bInSendMode := FALSE; END_IF (***************************************************************************************) (* ОБРАБОТКА: Очередь Входящих СМСок *) fbSMSInbound(CLK := fbSMSObject.NewInSms); (* Отслеживаем фронт новой СМСки *) IF (fbSMSInbound.Q = TRUE) THEN (* Получили СМСку. Пихнём её в очередь *) SMSOpDoRecieve(); (* Обработка приёма новой СМСки (ставим в очередь) *) ELSE SMSProcessInbound(); (* Обрабатываем очередь входящих СМСок *) END_IF (* Всё *)




Ответить с цитированием