Подпрограммы предназначены для выполнения определённых действий над внутренними устройствами микроконтроллера, внешними устройствами подключёнными к выводам микроконтроллера или числами, хранящимися в памяти этой микросхемы. В любом случае, с точки зрения программы, операции производятся над переменными. Переменные могут быть локальными или глобальными.
Подпрограммы процедуры
Если подпрограмма только осуществляет действия над глобальными переменными, то такая подпрограмма называется процедурой. Эта подпрограмма может осуществлять управление какими-то устройствами или осуществлять какие-либо вычисления. Если производятся вычисления, то результат помещается в глобальную переменную для того, чтобы этим результатом могла воспользоваться другая подпрограмма или основная программа. Пример управления последовательным портом:
Листинг 1. Пример подпрограммы - процедуры
... G_Per=56; PeredatByte(); ... G_Per=37; PeredatByte(); ... /********************************************** Подпрограмма передачи байта через последовательный порт **********************************************/ void PeredatByte(void) {do;while(TI==0)//Если предыдущий байт передан SBUF=G_Per //то передать очередной байт }
Часто подпрограмма должна выполнять действия над каким то числом, значение которого неизвестно в момент написания программы. Это число можно передать через глобальную переменную как показано на рисунке 1. Однако намного удобнее использовать подпрограмму с параметрами. На языке высокого уровня вызов такой подпрограммы будет выглядеть следующим образом:
Листинг 2. Пример подпрограммы - процедуры с передачей данных через параметр подпрограммы
... PeredatByte(56); ... PeredatByte(57); ... /******************************************************* Подпрограмма передачи байта через последовательный порт ********************************************************/ void PeredatByte(char byte) {do;while(TI==0) //Если предыдущий байт передан SBUF=byte; //то передать очередной байт }
Сравните с программой, приведённой в листинге 1. Как по вашему, какая из программ более наглядная? В подпрограмму можно передавать и значительные объёмы данных, как например:
PeredatStroky("Напечатать строку");
Естественно, что в этом случае сама вызываемая подпрограмма должна быть написана несколько иначе по сравнению с предыдущим случаем.
Подпрограммы функции
Часто требуется передавать результат вычислений из подпрограммы в основную программу. Для этого можно воспользоваться подпрограммой - функцией. Подпрограмма - функция возвращает вычисленное значение. Пример использования подпрограммы - функции:
Y=sin(x);
Использование подпрограмм-функций позволяет приблизить процесс написания программ к математической записи выражений, которые необходимо вычислить. Использование подпрограмм-функций позволяет увеличить наглядность программ и, в результате, увеличить скорость написания и отладки программ.
Подпрограммы-функции обычно возвращают простые типы переменных, такие как байт, слово или целое значение. Однако при помощи переменной-указателя можно возвращать и более сложные переменные, такие как массивы переменных или строки. Например, программа, приведенная на листинге 2, может быть реализована в виде подпрограммы-функции:
Листинг 2. Пример подпрограммы - процедуры с передачей данных через параметр подпрограммы
... if(PeredatByte('A')!=0)printf(“Отказ последовательного порта”); ... /******************************************************* Подпрограмма передачи байта через последовательный порт ********************************************************/ int PeredatByte(char byte) {for(i=1000;i<0;) {if(TI==0) //Если предыдущий байт передан {SBUF=byte; //то передать очередной байт return(0); //и вернуть признак нормального выполнения подпрограммы } } return(-1); //Если превышено время ожидания, то вернуть признак отказа передатчика }
В данной функции производится проверка работоспособности порта, и если он не отвечает дольше заданного срока, то производится принудительный выход из функции. Признак нормального или аварийного завершения работы передается через значение функции, равное нулю или минус единице. В вызывающей программе этот признак анализируется и в случае аварийного завершения подпрограммы, выдается сообщение пользователю аппаратуры.