Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Разработка ПО на языке Си для микроконтроллера AT91SAM7S.pdf
Скачиваний:
120
Добавлен:
18.05.2014
Размер:
838.69 Кб
Скачать

2Функции

2.1Объявления и определения функций

Функция – это обособленный блок программы, иначе говоря, подпрограмма, которую можно вызывать многократно. Функция в языке Си имеет имя, может принимать аргументы и возвращать значение. В листинге 4 приведён фрагмент программы, содержащий несколько функций.

Так же как и в случае с переменными, функция перед первым использованием должна быть объявлена или определена. Функции определяются следующим образом. Сначала указывается тип возвращаемого значения, за ним следует имя функции, после которого в скобках через запятую перечисляются аргументы с указанием их типов и имён. Далее следует тело функции, обрамлённое фигурными скобками. Результат работы функции (возвращаемое значение) указывается внутри тела функции после «команды» возврата из функции – ключевого слова return.

Аргументы, переданные в функцию, внутри неё относятся к автоматическому классу памяти и их изменение не приводит к изменению переменных, использованных при вызове функции. Иначе говоря, внутри функции создаются локальные копии переменных-аргументов, использованных при вызове функции. Тем не менее, в случае передачи в качестве аргумента указателя (см. п. 3), становится возможным через него изменить значение переменной или элемента массива, на который он указывает.

Объявление функции говорит компилятору о том, что где-то (возможно в другом исходном файле, или в том же файле, но ниже по тексту) определена такая функция. Объявление функции отличается от определения: в объявлении вместо тела функции после скобки, закрывающей список аргументов ставится точка с запятой. Также в объявлении функции не обязательно указывать имена аргументов (как это сделано, например, при объявлении функции newMean в листинге 4), но обязательно указывать их типы. Объявление функции также часто называют прототипом функции или сигнатурой функции.

Так, в листинге 4 функция newMean сначала объявляется, а затем определяется. Функция принимает три аргумента: первые два – типа float и 3й – unsigned int. Возвращаемое значение функции имеет тип float. Предварительно объявление позволяет использовать эту функцию внутри функции main до её фактического определения.

9

return (0.5 * adcCode) + 5.0;

Функция calcTemperature сразу определяется без предварительного объявления. В данном случае объявление не является обязательным, т. к. эта функция не используется до определения.

Для функций doAdc и setUpAdc приведены только объявления, а описания отсутствуют. Это означает, что при построении программы после получения объектных модулей из исходных файлов компоновщик попытается найти эти функции в одном из объектных модулей, участвующих в компоновке. В случае, если ему не удастся это сделать, построение завершится с ошибкой.

Для функции setUpAdc в качестве типа возвращаемого значения указан «void». Это означает, что функция не возвращает какого-либо результата.

Аргумент типа «void» функции main означает, что она не принимает аргументов.

Листинг 4. Фрагмент программы вычисления среднего значения температуры

//Объявление функции выполнения аналого-цифрового преобразования unsigned int doAdc (unsigned char channelIndex);

//Объявление функции подготовки заданного канала АЦП

void setUpAdc (unsigned char channelIndex);

//Объявление функции контроля температуры void checkTemperature (float value);

//Определение функции обратного преобразования float calcTemperature (unsigned int adcCode)

{

}

//Функция вычисления среднего (объявление) float newMean (float, float, unsigned int);

//"Точка входа"

int main (void)

{

// Номер канала АЦП

const char adcChannel = 4;

//Подготовить АЦП setUpAdc(adcChannel);

//Среднее значение температуры

10

float mean = 0.0;

unsigned int iteration = 0;

// Проводим 100 измерений while (iteration < 100)

{

// Выполнить преобразование

unsigned int adcCode = doAdc (adcChannel); // Вычислить температуру

float temp = calcTemperature(adcCode); // Вычислить текущее среднее

mean = newMean (mean, temp, iteration); // Увеличиваем счётчик

iteration++;

}

// Проверить температуру checkTemperature (mean);

}

//Определение функции вычисления среднего значения.

//Позволяет обновлять текущее среднее значение при

//поступлении новых результатов.

//currentMean – текущее значение среднего;

//newValue – новый отчёт, участвующий в вычислении среднего;

//iterationIndex – номер шага.

float newMean (float currentMean, float newValue, unsigned int iterationIndex)

{

return (currentMean * iterationIndex + newValue) / (iterationIndex

+ 1);

}

2.2Функция main

Выполнение программы на Си начинается с функции main. Однако перед тем, как начнётся выполнение этой функции, происходят некоторые подготовительные действия, необходимые для правильной работы программы такие, как подготовка стека (инициализация указателя стека), инициализация глобальных переменных и др. Данные действия выполняются в так называемом startup-модуле программы (также называемым startup-кодом), участвующем в сборке совместно с остальными модулями программы. Применительно к микроконтроллеру AT91SAM7S этот модуль также проводит инициализацию стеков для различных режимов работы процессора, настраивает встроенные

11

периферийный устройства и выполняет некоторые другие подготовительные действия.

Влистинге 4 функция main формально возвращает целое знаковое число (на что указывает тип «int», записанный перед именем функции) и не принимает никаких аргументов (на что указывает тип «void» в скобках после имени функции).

Вреальном программном обеспечении для микроконтроллеров функция main обычно никогда не завершается, поэтому для неё допускается не указывать возвращаемое значение, либо даже изменить тип возвращаемого значения на void.

12