Предыдущая версия справа и слева
Предыдущая версия
Следующая версия
|
Предыдущая версия
Следующая версия
Следующая версия справа и слева
|
bb:redbook:202 [2017/08/30 16:39] prospero78 [2.2 Ввод данных] |
bb:redbook:202 [2017/08/30 16:50] prospero78 [2.4 Вывод данных на экран] |
Задача: на вход радиоприёмника поступает ослабленный радиосигнал, вместе с полезным сигналом в приёмник проникает шумовая помеха. Необходимо из массива входных сигналов выделить полезный сигнал. Сигнал поступает в форме [[https://ru.wikipedia.org/wiki/%D0%90%D0%B7%D0%B1%D1%83%D0%BA%D0%B0_%D0%9C%D0%BE%D1%80%D0%B7%D0%B5|азбуки Морзе]]. Дополнительные данные: | Задача: на вход радиоприёмника поступает ослабленный радиосигнал, вместе с полезным сигналом в приёмник проникает шумовая помеха. Необходимо из массива входных сигналов выделить полезный сигнал. Сигнал поступает в форме [[https://ru.wikipedia.org/wiki/%D0%90%D0%B7%D0%B1%D1%83%D0%BA%D0%B0_%D0%9C%D0%BE%D1%80%D0%B7%D0%B5|азбуки Морзе]]. Дополнительные данные: |
| |
* символ "S" — "#.#.#" | * литера "S" — "#.#.#" |
* символ "О" — "###" | * литера "О" — "###" |
* уровень шумового сигнала — ниже 50 единиц. | * уровень шумового сигнала — ниже 50 единиц. |
* уровень помехи создаваемый грозой — выше 1000 единиц. | * уровень помехи создаваемый грозой — выше 1000 единиц. |
</code> | </code> |
| |
Для облегчения контроля ввода данных в тексте были определены две дополнительных переменных, о которых пока не было сказано ни слова. Это константа ''_разм'' и счётчик цикла ''цИтер''. Константа нужна для того, что один раз её определив, не нужно было выискивать её по всему тексту. Если потребуется под массив выделить больше места — в следующий раз будет //достаточно переопределить константу//. Переменная счётчика цикла нам бы потребовалась в любом случае. Также в начале процедуры ввода нам //потребовалось обнулить весь массив//, при этом надо обратить внимание, что в целочисленном цикле константа ''_разм'' уменьшена на ''1''. Это связано только с тем, что диапазон массива сигналов //индексируется// ''от 0 до 255'' (т. е. 256 элементов). Если этого не сделать, то попытка обратиться к элементу массива с номером 256 //закончится крахом//. Это //несколько необычно для людей//, привыкших считать что автобусов, домов и квартир с номером ''0'' не существует. Чуть позже будет показано, как этот несколько странный момент обратить в преимущество. | Для облегчения контроля ввода данных в тексте были определены две дополнительных переменных, о которых пока не было сказано ни слова. Это константа ''разм'' и счётчик цикла ''цИтер''. Константа нужна для того, что один раз её определив, не нужно было выискивать её по всему тексту. Если потребуется под массив выделить больше места — в следующий раз будет //достаточно переопределить константу//. Переменная счётчика цикла нам бы потребовалась в любом случае. Также в начале процедуры ввода нам //потребовалось обнулить весь массив//, при этом надо обратить внимание, что в целочисленном цикле константа ''_разм'' уменьшена на ''1''. Это связано только с тем, что диапазон массива сигналов //индексируется// ''от 0 до 255'' (т. е. 256 элементов). Если этого не сделать, то попытка обратиться к элементу массива с номером 256 //закончится крахом//. Это //несколько необычно для людей//, привыкших считать что автобусов, домов и квартир с номером ''0'' не существует. Чуть позже будет показано, как этот несколько странный момент обратить в преимущество. |
| |
После целочисленного цикла, переменная ''цИтер'' опять получает присвоение, так как после целочисленного цикла она будет равна "255". | После целочисленного цикла, переменная ''цИтер'' опять получает присвоение, так как после целочисленного цикла она будет равна "255". |
Вот пример того, как можно отсеять помехи: | Вот пример того, как можно отсеять помехи: |
<code oberon2> | <code oberon2> |
PROCEDURE LimitSig; | PROCEDURE Сигн_Ограничить; |
BEGIN | BEGIN |
p1 := 50; | цШум_низ := 50; |
p2 := 1000; | цШум_Верх := 1000; |
FOR i := 0 TO _sig_max - 1 DO | FOR цИтер := 0 TO _разм - 1 DO |
IF sig[i] < p1 THEN | IF sig[цИтер ] < цШум_низ THEN |
sig[i] := 0 | sig[цИтер ] := 0 |
ELSIF sig[i] > p2 THEN | ELSIF sig[цИтер ] > цШум_Верх THEN |
sig[i] := 600 | sig[цИтер ] := 600 |
ELSE | ELSE |
sig[i] := 500 | sig[цИтер ] := 500 |
END; | END; |
END; | END; |
END LimitSig; | END Сигн_Ограничить; |
</code> | </code> |
| |
| |
В целом представленная процедура имеет общепринятое название в радиотехнике "восстановление формы цифрового сигнала". | В целом представленная процедура имеет общепринятое название в радиотехнике "восстановление формы цифрового сигнала". |
| |
| Также обратите внимание на то, что переменные ''цШум Низ'' и ''цШум верх'' на самом деле не изменяются и их можно было определить как константы. Это будет несколько лучше, так как константы нельзя изменять (по ошибке вы можете попытаться это сделать). Кроме того, устанавливаемые уровни сигналов -- по сути, тоже константы. И чтобы не искать их по всему коду -- можно тоже вынести в одно место. |
| |
| |
Часть символов ("#" и ".") уже представлено по условию задачи, и они обозначают "есть сигнал" и "нет сигнала" соответственно. Но у нас появился ещё один сигнал, значение которого равно "600". И его надо как-то тоже обозначать. Поскольку он превышает нормальный уровень нужно визуально указать на этот факт. Очень удобно будет использовать символ "^". Ниже примерный вид процедуры, который мог бы это сделать: | Часть символов ("#" и ".") уже представлено по условию задачи, и они обозначают "есть сигнал" и "нет сигнала" соответственно. Но у нас появился ещё один сигнал, значение которого равно "600". И его надо как-то тоже обозначать. Поскольку он превышает нормальный уровень нужно визуально указать на этот факт. Очень удобно будет использовать символ "^". Ниже примерный вид процедуры, который мог бы это сделать: |
<code oberon2> | <code oberon2> |
PROCEDURE OutSig; | PROCEDURE Сиг_Вывести; |
CONST | CONST |
_p = " "; (* пауза в передаче сигнала *) | _п = " "; (* пауза в передаче сигнала *) |
_s = "#"; (* полезный сигнал *) | _s = "#"; (* полезный сигнал *) |
_m = "^"; (* молния? *) | _м = "^"; (* молния? *) |
BEGIN | BEGIN |
Log.String('[Начало приёма]'); Log.Ln; | мЛог.String('[Начало приёма]'); мЛог.Ln; |
FOR i := 0 TO _sig_max - 1 DO | FOR цИтер := 0 TO _разм - 1 DO |
IF sig[i] = 0 THEN | IF мцСигнал[i] = 0 THEN |
Log.String(_p) | мЛог.String(_п) |
ELSIF sig[i] = 500 THEN | ELSIF мцСиг[i] = 500 THEN |
Log.String(_s) | мЛог.String(_s) |
ELSE | ELSE |
Log.String(_m) | мЛог.String(_м) |
END; | END; |
END; | END; |
Log.Ln; Log.String('[Конец приёма]'); Log.Ln | мЛог.Ln; мЛог.String('[Конец приёма]'); мЛог.Ln |
END OutSig; | END Сиг_Вывести; |
</code> | </code> |
| |