Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

691_Mikushin_A.V._Programmirovanie_mikroprotsessorov_

.pdf
Скачиваний:
48
Добавлен:
12.11.2022
Размер:
1.96 Mб
Скачать

Ну а теперь, прежде чем начать знакомство со средой программирования, рассмотрим основные принципы построения языка программирования С-51 и его отличие от стандартного языка ANSI C.

1.1. Структура программ С-51

Язык программирования С-51 является структурно-модульным языком. Каждый оператор в программе является частью, по крайней мере, одного модуля. Каждая программа, написанная на языке программирования С-51, состоит из одного или более модулей. Каждый модуль записывается в отдельном файле

икомпилируется отдельно.

Вмодуле помещаются операторы, составляющие программу. Эти операторы объявляют константы или переменные и выполняют необходимые действия. Операторы, выполняющие действия, обязательно должны быть помещены в подпрограммы. Исполнение программы всегда начинается с функции с именем main (т.е. в простейшем случае достаточно написать только эту подпрограмму).

Функция начинается с заголовка подпрограммы, в который входит тип возвращаемой переменной, имя подпрограммы и круглых скобок, внутри которых объявляются переменные – параметры подпрограммы. В подпрограмме main (а также во всех подпрограммах, где не нужно возвращать переменные) вместо типа переменной указывается слово void. Вот уже и начались отличия в программировании микроконтроллеров! В стандартной программе, написанной на языке C, подпрограмма main может быть int типа. Здесь это не так. Ведь программа микроконтроллера никогда не должна завершаться! Исполняемые операторы подпрограммы заключаются в фигурные скобки.

Все переменные и константы, которые будут использоваться в программе, обязательно должны быть объявлены до подпрограммы, где они будут использованы первый раз.

При написании программы для микроконтроллеров всегда необходимо видеть перед глазами принципиальную схему устройства, для которого пишется программа, так как схема и программа тесно связаны между собой и дополняют друг друга. Для иллюстрации простейшей программы, написанной на языке программирования C-51, воспользуемся схемой, приведённой на рисунке 5.

11

Рисунок 5. Пример простейшей схемы устройства, построенной с использованием микроконтроллера

Для примера заставим гореть светодиод VD1. Этот светодиод будет светиться только тогда, когда через него будет протекать ток. Для этого на шестом выводе порта P0 должен присутствовать нулевой потенциал. Запишем его первой же командой нашей программы:

#include<reg51.h>

void main(void)

{P0=0; //Зажигание светодиода while(1); //Бесконечный цикл

}

Эта программа содержит только один исполняемый оператор. Это оператор присваивания ‘P0=0;’. Следующий оператор ‘while(1);’ обеспечивает зацикливание программы. Зацикливание программы сделано для того, чтобы микроконтроллер не выполнял больше никаких действий. В противном случае микроконтроллер перейдёт к следующей ячейке памяти, и будет выполнять команды, которые мы не записывали.

Обратите внимание, что язык программирования “знает”, по какому адресу памяти данных находится порт P0. Эта информация содержится в строке

#include<reg51.h>.

12

Для того чтобы получить более полное представление о структуре программ, написанных на языке программирования С-51, приведём пример исходного текста программы с использованием подпрограмм.

#include<reg51.h>

void svGorit(void)

{P0=0; //Зажигание светодиода

}

void main(void)

{svGorit(); //Вызов подпрограммы с именем svGorit while(1); //Бесконечный цикл

}

В приведённом примере использование подпрограммы никаких преимуществ не даёт, но в более сложных программах использование "говорящих" имён переменных может приблизить исходный текст программы к алгоритму, и, тем самым, сделать программу более понятной. Это в свою очередь значительно уменьшит время отладки программы.

1.2. Символы языка программирования С-51

Как и в любом другом текстовом файле, в исходном тексте программы, написанной на языке программирования С51, используются ASCII или ANSI символы. Множество символов, используемых в языке программирования С- 51, можно разделить на пять групп.

1. Символы, используемые для образования ключевых слов и идентификаторов (табл.1).

Вэту группу входят прописные и строчные буквы английского алфавита,

атакже символ подчеркивания. Следует отметить, что язык программирования С-51 различает прописные и строчные буквы. Например, идентификаторы start и Start будут считаться различными идентификаторами.

 

Таблица 1

Прописные буквы латинского

A B C D E F G H I J K L M N O P Q R S T U V W

алфавита

X Y Z

 

 

Строчные буквы латинского

a b c d e f g h i j k l m n o p q r s t u v w x y z

алфавита

 

 

 

Символ подчеркивания

_

Арабские цифры

0 1 2 3 4 5 6 7 8 9

 

 

13

2. Прописные и строчные буквы русского алфавита (табл. 2).

Таблица 2

Прописные буквы русского

А Б В Г Д Е Ж З И К Л М Н О П Р С Т У Ф Х Ц Ч Ш

алфавита

Щ Ы Ь Э Ю Я

Строчные буквы русского

а б в г д е ж з и к л м н о п р с т у ф х ц ч ш щ ъ ы ь э

алфавита

ю я

3. Знаки нумерации и специальные символы (табл. 3).

Эти символы используются для организации процесса вычислений, а также для передачи компилятору определенного набора инструкций.

 

 

 

Таблица 3

Символ

Наименование

Символ

Наименование

,

запятая

)

круглая скобка правая

.

точка

(

круглая скобка левая

 

 

 

 

;

точка с запятой

}

фигурная скобка правая

 

 

 

 

:

двоеточие

{

фигурная скобка левая

 

 

 

 

?

вопросительный знак

<

Меньше

 

 

 

 

'

апостроф

>

Больше

!

восклицательный знак

[

квадратная скобка

 

 

 

 

|

вертикальная черта

]

квадратная скобка

/

дробная черта

#

Номер

 

 

 

 

\

обратная черта

%

Процент

~

тильда

&

Амперсанд

 

 

 

 

*

звездочка

^

исключающее ИЛИ

+

плюс

=

Равно

 

 

 

 

-

минус

"

Кавычки

4.Управляющие и разделительные символы. К этой группе символов относятся: пробел, символы табуляции, перевода строки, возврата каретки, символы новой страницы и новой строки. Эти символы отделяют друг от друга лексические единицы языка, к которым относятся ключевые слова, константы, идентификаторы и т.д. Последовательность разделительных символов (например, последовательность пробелов) рассматривается компилятором как один символ.

5.Управляющие последовательности, т.е. специальные символьные комбинации, используемые в функциях ввода и вывода информации. Управляющая последовательность начинается с использования обратной косой черты (\), за которой следует комбинация латинских букв и цифр. Список управляющих последовательностей приведён в таблице 4.

14

 

 

Таблица 4

Управляющая

Наименование

Шестнадцатеричный

последовательность

 

код

\a

Звонок

007

 

 

 

\b

Возврат на шаг

008

\t

Горизонтальная табуляция

009

 

 

 

\n

Переход на новую строку

00A

\v

Вертикальная табуляция

00B

 

 

 

\r

Возврат каретки

00D

\f

Новая страница

00C

 

 

 

\"

Кавычки

022

\'

Апостроф

027

 

 

 

\0

Ноль-символ

000

\\

Обратная дробная черта

05C

 

 

 

\OOO

Восьмеричный код ASCII или

 

 

ANSI символа

 

 

 

 

\xHHH

Шестнадцатеричный код ASCII

HHH

 

или ANSI символа

 

 

 

 

Управляющие последовательности \OOO и \xHHH (здесь O обозначает восьмеричную цифру; H обозначает шестнадцатеричную цифру) позволяет представить символ из кодовой таблицы ASCII или ANSI как последовательность восьмеричных или шестнадцатеричных цифр соответственно. Например, символ возврата каретки может быть представлен следующими способами:

\r - управляющая последовательность,

\015 - восьмеричный код символа возврата каретки, \x00D - шестнадцатеричный код символа возврата каретки.

Следует отметить, что в строковых константах всегда обязательно задавать все три цифры управляющей последовательности. Например, отдельную управляющую последовательность \n (переход на новую строку) можно представить как \010 или \xA, но в строковых константах необходимо задавать все три цифры, в противном случае символ или символы, следующие за управляющей последовательностью, будут рассматриваться как ее недостающая часть. Например:

"ABCDE\x009FGH" данная строковая команда будет напечатана с использованием определенных функций языка СИ, как два отдельных слова ABCDE и FGH, разделенные табуляцией, в этом случае если указать неполную управляющую строку "ABCDE\x09FGH",то при печати появится строка ABCDEЯGH, так как компилятор воспримет последовательность \x09F как символ "Я".

Отметим тот факт, что, если обратная дробная черта предшествует символу, не являющемуся управляющей последовательностью (т.е. не включенному в

15

табл.4) и не являющемуся цифрой, то эта черта игнорируется, а сам символ представляется как литеральный. Например:

символ \h представляется символом h в строковой или символьной константе.

Кроме определения управляющей последовательности, символ обратной дробной черты (\) используется также как символ продолжения. Если за (\) следует символ возврата каретки, то оба символа игнорируются, а следующая строка является продолжением предыдущей. Это свойство может быть использовано для записи длинных строк. Например:

printf("Это очень длинная \ строка")

Компилятор С-51 выдает сообщение об ошибке, если в тексте исходной программы встречается символ, отличающийся от символов, перечисленных выше.

1.3. Лексические единицы, разделители и использование пробелов

Наименьшей единицей операторов C-51 является лексическая единица. Каждая из лексических единиц относится к одному из классов:

идентификаторы;

ключевые слова;

простые ограничители (все специальные символы, кроме _, являются простыми ограничителями);

составные ограничители (они образуются посредством определенных комбинаций двух спецсимволов, а именно: !=,+=,-=,*=,<<,>>, <=, >=, /*, */,//);

числовые константы;

текстовые строковые константы;

Вбольшинстве случаев вполне очевидно, где заканчивается одна лексическая единица и начинается следующая. Например, в операторе присваивания:

X=AP*(FT-3)/A;

X, AP, FT, A - являются идентификаторами переменных; 3 - числовой константой; все прочие символы - простыми ограничителями.

Ключевые слова, идентификаторы и числовые константы должны обязательно отделяться друг от друга. Если между двумя идентификаторами, числовыми константами или ключевыми словами не может быть указан простой или составной ограничитель, то в качестве разделителя между ними должен вставляться символ пробела. Для улучшения читабельности программы вместо одного символа пробел может использоваться несколько символов пробела.

16

Идентификаторы.

Идентификаторы в языке программирования C-51 используются для определения имени переменной, подпрограммы, символической константы или метки оператора. Длина идентификатора может достигать 255 символов, но транслятор различает идентификаторы только по первым 31 символам.

Возникает вопрос – а зачем тогда нужен такой длинный идентификатор? Ответ: для создания "говорящего" имени подпрограммы или переменной, которое может состоять из нескольких слов. Например:

ProchitatPort();

//Прочитать порт

VklychitIndikator();

//Включить индикатор

В приведенном примере подпрограмма ProchitatPort выполняет действия необходимые для чтения порта, а подпрограмма VklychitIndikator выполняет действия, необходимые для зажигания индикатора. Естественно, что намного легче прочитать действие подпрограммы непосредственно из имени подпрограммы, чем лазить каждый раз в алгоритм программы или искать исходный текст подпрограммы для того чтобы в очередной раз разобраться – что же она выполняет? Для этого при объявлении имени подпрограммы можно потратить количество символов и большее чем 31!

То же самое можно сказать и про имена переменных. Например:

sbit ReleVklPitanija = 0x80; //К нулевому выводу порта P0 подключено реле включения питания

sbit svDiod = 0x81; //К первому выводу порта P0 подключен светодиод

sbit DatTemperat = 0x82; //Ко второму выводу порта P0 подключен датчик температуры

Вприведённом примере каждой ножке микроконтроллера назначается переменная с именем, отображающим устройство, подключённое к этой ножке. В результате при чтении программы не потребуется обращаться к принципиальной схеме устройства каждый раз, как только производится операция записи или чтения переменной, связанной с портами микроконтроллера. (Разбираться с принципиальной схемой занятие не менее "увлекательное" по сравнению с поиском неизвестной и неизвестно что выполняющей подпрограммы)

Вкачестве идентификатора может быть использована любая последовательность строчных или прописных букв латинского алфавита и цифр, а также символов подчёркивания ‘_’. Идентификатор может начинаться только с буквы или символа ‘_’, но ни в коем случае с цифры. Это позволяет программетранслятору различать идентификаторы и числовые константы. Строчные и прописные буквы в идентификаторе различаются. Например: идентификаторы abc и ABC, A128B и a128b воспринимаются как разные.

Идентификатор создается при объявлении переменной, функции, структуры и т.п. после этого его можно использовать в последующих операторах разрабатываемой программы. Следует отметить важные особенности при определении идентификатора:

17

Идентификатор не должен совпадать с ключевыми словами, с зарезервированными словами и именами функций из библиотеки компилятора языка С.

Следует обратить особое внимание на использование символа подчеркивание (_) в качестве первого символа идентификатора, поскольку идентификаторы, построенные таким образом, могут совпадать с именами системных функций или переменных, в результате чего они станут недоступными.

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

Примеры правильных идентификаторов:

A

XYR_56

OpredKonfigPriem

Byte_Prinjat

SvdiodGorit

Ключевые слова.

Ключевые слова – это зарезервированные слова, которые используются для построения операторов языка.

Список ключевых слов:

_at_

alien

auto

bdata

bit

break

case

char

code

compact

const

continue

data

default

do

double

else

enum

extern

far

float

for

goto

idata

if

int

interrupt

large

long

pdata

_priority_ reentrant

register

return

sbit

sfr

sfr16

short

signed

sizeof

small

static

struct

switch

typedef

_task_

union

unsigned

using

void

volatile

while

xdata

 

 

 

Обратите внимание, что ключевые слова не могут быть использованы в качестве идентификаторов.

Константы.

Константы предназначены для введения чисел в состав выражений операторов языка программирования C. В отличие от идентификаторов, всегда начинающихся с буквы, константы всегда начинаются с цифры. В языке программирования С-51 разделяют четыре типа констант:

1.Целые знаковые и беззнаковые константы,

2.Константы с плавающей запятой,

3.Символьные константы и литеральные строки.

18

Целочисленные константы могут быть записаны как восьмеричные, десятичные или шестнадцатеричные числа в зависимости от того, какая система счисления удобнее для представления константы. Константа может быть представлена в десятичной, восьмеричной или шестнадцатеричной форме. При выполнении вычислений обычно пользуются десятичными константами. При работе с ножками микроконтроллера или передаче двоичных данных удобнее пользоваться двоичными числами или их более короткой формой записи – восьмеричными или шестнадцатеричными числами.

Десятичная константа состоит из одной или нескольких десятичных цифр, причем первая цифра не может быть нулем (иначе число будет воспринято как восьмеричное).

Восьмеричная константа состоит из обязательного нуля и одной или нескольких восьмеричных цифр (среди цифр должны отсутствовать цифры восемь и девять, так как эти цифры не входят в восьмеричную систему счисления). Если константа содержит цифру, недопустимую в восьмеричной системе счисления, то константа считается ошибочной.

Шестнадцатеричная константа начинается с обязательной последовательности символов 0х или 0Х и содержит одну или несколько шестнадцате-

ричных цифр (0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)

Примеры целых констант:

 

Десятичная

Восьмеричная

Шестнадцатеричная

константа

константа

константа

16

020

0x10

127

0117

0x2B

240

0360

0XF0

Если требуется сформировать отрицательную целую константу, то используют знак ‘–‘ перед записью константы (который будет называться унарным минусом). Например: –0x2A, –088, –16.

Каждой целой константе присваивается тип, определяющий преобразования, которые должны быть выполнены, если константа используется в выражениях. Тип константы определяется следующим образом:

десятичные константы рассматриваются как знаковые числа, и им присваивается тип int (целая) или long (длинная целая) в соответствии со значением константы. Если константа меньше 32768, то ей присваивается тип int в противном случае long.

восьмеричным и шестнадцатеричным константам присваивается тип int, unsigned int (беззнаковая целая), long или unsigned long в зависимости от значения константы согласно табл 5.

19

 

 

Таблица 5

Диапазон шестнадцатеричных

Диапазон восьмеричных

Тип

констант

констант

 

0x0 - 0x7FFF

0 – 077777

int

 

 

 

0X8000 - 0XFFFF

0100000 – 0177777

unsigned int

0X10000 – 0X7FFFFFFF

0200000 – 017777777777

long

 

 

 

0X80000000 - 0XFFFFFFFF

020000000000 –

unsigned long

 

037777777777

 

 

 

 

Иногда требуется с самого начала интерпретировать константу как длинное целое число. Для того чтобы любую целую константу определить типом long, достаточно в конце константы поставить букву "l" или "L". Пример:

5l, 6l, 128L, 0105L, OX2A11L.

Примеры синтаксически недопустимых целочисленных констант:

12AF - шестнадцатеричная константа не имеет символов 0x в начале константы, поэтому по умолчанию для нее принимается десятичная система счисления, но тогда в ней присутствуют недопустимые символы.

0x2ADG - символ G недопустим при записи шестнадцатеричных чисел.

Константа с плавающей запятой – это десятичное число, представленное в виде действительного числа с десятичной запятой и порядком числа. Формат записи константы с плавающей запятой:

[ цифры ].[ цифры ] [ Е|e [+|-] цифры ].

Число с плавающей запятой состоит из целой и дробной части и (или) порядка числа. Для определения отрицательного числа необходимо сформировать константное выражение, состоящее из знака минуса и положительной константы. Примеры записи констант с плавающей запятой:

115.75, 1.5Е-2, -0.025, .075, -0.85Е2

Символьная константа – представляется ASCII или ANSI символом, заключенном в апострофы. Управляющая последовательность тоже может быть использована в символьных константах. При этом она рассматривается как одиночный символ. Значением символьной константы является числовой код символа. Примеры символьных констант:

' ' - пробел , 'Q' - буква Q ,

'\n' - символ новой строки , '\\' - обратная дробная черта , '\v' - вертикальная табуляция .

20