Директивы процессора
|
|
Space | Дата: Четверг, 21.02.2008, 17:03 | Сообщение # 1 |
Зарегистрирован 25.12.2007
Группа: Администраторы
Сообщений: 1103
Статус: Offline
| C (Си) является универсальным языком программирования высокого уровня, который содержит команды низкого уровня, подобно языку ассемблера. Программа на языке Си может быть скомпилирована в машинные коды почти для всех типов процессоров. Удачное сочетание лаконичности конструкций и богатства выразительных возможностей позволило языку Си быстро распространиться и стать сегодня наиболее популярным языком прикладного и системного программирования. Можно даже сказать, что Си стал фундаментом, на котором строится современное программирование. Файлы программ на языке Си имеют расширение .C, а структура программы выглядит следующим образом. Code /* ---------------------------------------------- ПРИМЕР ПРОГРАММЫ НА AVR GCC ------------------------------------------------- */
#include <avr/io.h> /* заголовок */
int main(void) /* главная функция: начало программы */
{ /* открывающая скобка в начале программы */
оператор программы; оператор программы; ... оператор программы;
} /* закрывающая скобка в конце программы */ Открывающие программу строки комментариев являются необязательными, однако тому, кто читает код, они дают представление о назначении программы. Строка #include является заголовком. В заголовках содержится информация для компилятора об общих требованиях программы. В данном случае компилятору указывается, что нужно включить информацию, содержащуюся в файле io.h. Файл с именем io.h является частью пакета AVR GCC и содержит информацию о вводе и выводе. Эта строка не является оператором языка Си. Символ # указывает, что она должна быть обработана "препроцессором". Препроцессор осуществляет некоторую предварительную обработку текста программы перед началом компиляции и подключает внешние библиотеки. Какой конкретный файл (или файлы) таким образом подключается, зависит от потребностей программы. В общем виде программа на Си - это набор функций, которые вызывают друг друга для выполнения. Любая программа на языке Си состоит из одной или более функций, причём ровно одна из них обязательно должна называться "main" ("главная"). Программа всегда начинает выполняться с главной функции main. У программиста имеется возможность выбирать имена для всех создаваемых им функций, кроме той, с которой начинается выполнение программы. Отличительным признаком функции служат круглые скобки после её имени. Круглые скобки указывают на то, что main() - имя функции. В круглых скобках в общем случае содержится информация, передаваемая функции. Идущая следом открывающая фигурная скобка { отмечает начало последовательности операторов, образующих тело функции. Закрывающая фигурная скобка } отмечает конец последовательности операторов, образующих тело функции. На этой скобке выполнение функции завершается. Фигурные скобки применяются также для того, чтобы объединить несколько операторов программы в составной оператор или блок. Тело функции, заключенное в фигурные скобки, представляет собой набор операторов, каждый из которых оканчивается символом точка с запятой ;. При написании программы на Си можно поместить несколько операторов на одной строке или разместить один оператор в нескольких строках. Символ "точка с запятой" указывает компилятору конец оператора, но для человека удобнее, если каждый оператор будет размещен на отдельной строке. Кроме того, можно использовать пустые строки, чтобы отделить одну часть программы от другой. операторы выполняются последовательно в том порядке, в котором они записаны Операторы выполняются последовательно в том порядке, в котором они записаны, и примерно соответствуют шагам исходного алгоритма. Особо следует отметить использование комментариев в программе. Комментарии - это примечания, помогающие понять смысл программы. В Си комментарии записываются между значками /* */. Содержание комментариев компилятору совершенно безразлично: все, что находится между символами начала и конца комментария, им игнорируется. Комментарии можно располагать на той же строке, что и операции, которые они объясняют. Длинные комментарии могут занимать несколько строк. Для комментария не требуется в конце точка с запятой. При разработке программы комментарии могут оказать неоценимую помощь, особенно если приходится оставлять работу на длительное время, а затем возвращаться к ней. При наличии комментариев гораздо легче продолжить работу с того места, где вы остановились. Кроме того, с их помощью гораздо проще впоследствии адаптировать уже написанные программы к новым задачам. Внутри набора символов, который представляет комментарий, не может быть специальных символов, определяющих начало и конец комментариев. Неправильное определение комментариев: Code /* комментарии к программе /* мигания светодиодом */ */ или Code /* комментарии к программе мигания */ светодиодом */ AVR GCC поддерживает и второй метод записи комментариев - строка, начинающаяся с символов //, считается комментарием. Пример: Code // Это однострочный комментарий Подводя итог вышесказанному, еще раз отметим, что для создания читаемой программы следует придерживаться следующих правил: # располагайте один оператор на строке; # используйте пустые строки для "отделения" одной логической части программы от другой; # используйте комментарии. Но это не всё
|
|
| |
Space | Дата: Понедельник, 25.02.2008, 20:57 | Сообщение # 2 |
Зарегистрирован 25.12.2007
Группа: Администраторы
Сообщений: 1103
Статус: Offline
| Директивы препроцессора Препроцессор — это особая программа, которая выполняет предварительную обработку данных до начала компиляции. Рассмотрим стандартные директивы препроцессора, а также директивы, характерные для компилятора CCS-PICC. Директива #include Выше, в разделе "Структуры программы на С" уже упоминалась самая распространенная директива #include, которая используется фактически во всех программах для включения в текст программы заголовочных файлов (с определениями), имеющий расширение .h, или файлов .с (не содержащих функцию main()). Эта директива может использоваться в двух формах: #include <имя_файла> или #include "имя_файла" Если имя файла заключено между знаками "<" и ">", то он считается частью стандартной библиотеки, поставляемой вместе с компилятором. Если же имя файла заключено в двойные кавычки, то считается, что он расположен в той же папке, что и файл с исходным кодом. Директива #define Директива #define указывает препроцессору на необходимость выполнить подстановку в тексте программы определенной последовательности символов другой последовательностью. Формат директивы: #define заменяемая_последовательность фрагмент_подстановки Например: #define MyName "John Smith" #define Condition (a > b) #define Operation a = b char str[] = MyName; //Равнозначно char str[] = "John Smith"; int a, b; if Condition Operatrion; //Равнозначно if (a > b) a = b; В директиве #define могут использоваться параметры, благодаря чему она становится очень мощный и гибким инструментом, позволяющим заменять один простой текстовый элемент сложным выражением. Такие подстановки называют макросами. Например, выражение, в котором выбирается большее из двух значений, , можно представить в виде следующего макроса. #define larger (х, у) ( (х) > (у) ? (х) : (у) ) Если определен такой макрос, то код, использующий его, может иметь следующий вид. int а = 9; int b = 7; int с = 0; с = larger(a, b) ; Напоминает вызов функции, однако это не функция — компилятор получит ' от препроцессора последнюю строку в следующем виде. с = ( (а)>(Ь) ? (а) : (Ь) ); Основное отличие макроса от функции заключается в том, что код макроподстановки вставляется препроцессором в программный код везде, где встречается 1 заданный текстовый элемент, код же функции определяется только в одном месте, а в тех местах, где указано ее имя, осуществляется вызов этого кода. Есть и еще одно отличие, особенно важное при программировании микроконтроллеров, — при использовании макросов, в отличие от функций, ничего не помещается в стек, что позволяет сэкономить оперативную память. Кроме того, макросы преобразуются в обычный код, который выполняется быстрее, чем код функции, на вызов которого и возврат управления в вызывающую функцию уходит дополнительное машинное время. Наконец, при использовании макросов не требуется формального объявления типов данных. ^ Перечислим некоторые правила использования директивы #define: при создании комментариев в строке с #define всегда используется комментарий вида/* ... */; | следует помнить, что конец строки — это конец #define, и весь текст слева заменить текст справа; для преобразования параметра макроса в текстовую строку можно указать перед ним символ "#", например: #define OutString(s) puts(#s) OutString(Line); //Равнозначно puts("Line"); для конкатенации двух параметров можно воспользоваться оператором ##, например: define Concat(x, у) х ## у int i = Concat(2,1); //Равнозначно int i = 21; Директива #use i2c Директива #use i2c определяет порт I2С микроконтроллера. Ее синтаксис: #use i2c(опции) В качестве опций (указываются через запятую) могут использоваться следующие значения: ADDRESS=nn — задание адреса ведомого устройства; FAST — использование спецификации быстрой шины 12С; FORCE_HW — использование аппаратных функций 12С; MASTER — установка режима ведущего устройства; RESTART_WDT — перезагрузка сторожевого таймера во время ожидания в процессе выполнения встроенной функции i2c_read (); ЭСЬ=вывод — задание вывода SCL (вывод — адрес разряда); ЗОА=ВЫВОД — задание вывода SDA; SLAVE — установка режима ведомого устройства; SLOW — использование спецификации медленной шины 12С. В следующем примере в качестве линии данных устанавливается вывод О порта В, а в качестве тактирующей линии — вывод 1 того же порта (режим ведущего устройства): #use i2c(MASTER, sda=PIN_PIN_BO, scl=PIN_Bl) Пример для режима ведомого устройства: #use i2c(SLAVE, sda=PIN_C4, scl=PIN_C3, ADDRESS=0xA0, FORCE_HW) Директива #use i2c считается активной до тех пор, пока в тексте программы не встретится другая директиа #use i2c. Эта директива позволяет воспользоваться встроенными функциями, реализующими обмен данными по шине 12С (если включена опция FORCE_HW, TO программные функции не генерируются и используется аппаратный порт MSSP). Директива #use rs232 Директива препроцессора #use rs232 используется для инициализации последовательного порта, работающего по стандарту RS232. В зависимости от того, как заданы выводы передачи и приема, реализация порта может быть аппаратной или программной. Если выводы соответствуют приемопередатчику USART, то используется аппаратный порт, в противном случае — программный UART. Общая форма директивы #use rs232: #use rs232 (опция, опция, опция, ...) Возможны следующие опции: BAUD=X — установка скорости передачи; BITS=X — установка разрядности в х, где х — 5-9 в случае программного UART и 8-9 в случае аппаратного UART; ENABLE=Bывод — во время передачи компилятор переводит указанный вывод в состояние высокого уровня; ERRORS — ошибки приема сохраняются в переменной RS232_ERRORS; FLOAT_HIGH — использование на выходе схем с открытым коллектором; INVERT — инвертирует полярность выводов последовательного порта (используется только с программным приемопередатчиком UART); PARITY=X — контроль по четности: x=N — отсутствует; х=Е — контроль по четности; х=0 — контроль по нечетности; RCV=Bывод — установка вывода для приема данных; RESTART_WDT — сброс сторожевого таймера при ожидании символа в функции get char (); STREAM=имя_noтока — ассоциирует идентификатор потока с портом RS232 (этот идентификатор может использоваться в функциях, наподобие fputcO). хм1Т=вывод — установка вывода для передачи данных. Директива #zero_ram Директива препроцессора #zero__ram указывает компилятору сбрасывать пе-' ред началом выполнения программы все внутренние регистры, которые могут быть использованы для хранения переменных, в нуль.
|
|
| |
|