Вы здесь: Главная » Микроконтроллеры. Урок 2.

Микроконтроллеры. Урок 2.
редлагаю продолжить изучение микроконтроллеров…

Второй урок будет посвящен по большей части описанию языка C.
Очень много текста… Но ведь не все всё знают, а с чего-то надо начинать!
Тем более, что без знания основ и кое-каких хитростей программирования, сделать что-то интересное может не получиться...

Кстати, вопрос по поводу ошибки в программе  остается открытым.

Или можно включить в начало программы стандартные библиотеки функций:
delay.h – функции временных задержек
math.h – математические функции (корни, логарифмы и т.п.)

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

Обратите внимание, имена стандартных библиотек нужно указывать в треугольных скобках, а файлов, находящихся в папке проекта – в кавычках!

Остальные директивы нам особо не нужны, поэтому на них останавливаться не буду.


Переменные.

определение         |        длинна(в битах)  |  диапазон значений

bit (бит)                                        1                           0 , 1
char (символ)                             8    от 0 до 255
unsigned char                             8    от 0 до 255
signed char (символ)                         8    от -128 до 127
int (целое)                               16    от -32768 до 32767
unsigned int                               16    от 0 до 65535
long int                                        32    от -2147483648 до 2147483647
unsigned long int                        32    от 0 до 4294967295
float (с плавающей точкой)    32    ±1.175e-38 до ±3.402e38

Как можно заметить, префикс unsigned означает, что переменная должна быть без знака (т.е., больше нуля), а signed – наоборот. Беззнаковые переменные МК обрабатывает быстрее. Какой тип переменной использовать – это решать вам. Всё зависит от того, какие данные вы собираетесь там хранить. Чем меньше длинна переменной, тем быстрее ее обрабатывает МК. Это стоит учитывать, если в программе важна скорость. А переменную char можно использовать не только для хранения символов. Этот тип так назван в основном потому, что язык C изначально писался для 16-и битных процессоров, поэтому основным типом там был int, а char использовался для хранения текстовых переменных, т.к. в таблице ASCII каждому символу соответствует всего 8 бит, хотя и может использоваться как простая численная переменная. По умолчанию в CVAvr этот тип unsigned . А так как наша архитектура 8-и битная, предпочтительнее использовать именно тип char,если не нужны значения больше 255.

Описание переменных производится так:
char a;
int b=3;
float c, d, pi=3.14;


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

Глобальные переменные должны быть описаны вначале программы до самой первой функции.
А локальные – в самом начале функции.

Значения переменным можно присваивать двоичные, десятичные или шестнадцатичные.
По умолчанию, если написать число, например 33 , оно считается деятичным.
Если нужно указать его как шестнадцатичное, то перед ним нужно поставить "0x”, т.е., 0x33 – это уже 51, если перевести в десятичную систему. А двоичные определяются так: 0b00110011.


Следующий этап – функция.

Функции могут получать какие-то переменные, а могут и не получать…
Могут возвращать какое-то значение, а могут и не возвращать :)
Всё зависит только от того, что мы хотим этой функцией делать.

Но в любом случае, объявление функции начинается с определения ее типа:
char func()
int func()

и так далее

а вот если функция ничего не возвращает, то она объявляется как void
void func()


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



Если x меньше или равен 20 – включаем светодиод, а если больше – просто выходим из функции.


Операторы

Операторы побитового сдвига ("<< " и ">>”)
Любая переменная – это некоторая последовательность бит.
Например, число 1 в переменной char – 00000001
А эти операторы, как уже понятно из названия, сдвигают эти биты.
Сдвиг влево:
char a=1, b;
b=a<<1; // в b запишется 0b00000010
b=a<<7; // в b запишется 0b10000000

т.е., те же биты, но сдвинутые влево на число, стоящее справа от оператора, а в освободившиеся биты записываются нули. Причем значение самой переменной a остается неизменным, а полученное значение присваивается переменной b.
Сдвиг вправо действует так же, только в другую сторону :)

Побитовое И ("&&”)
Если в одном и том же бите у двух операндов "1”, то и результат "1”, а если хоть один "0”, то результат "0”
char a=0b00100010;
char b=0b10101010, c;
c=a&&b; // результат – 0b00100010


Побитовое ИЛИ ("||”)
В результате "1” будет там, где хотя бы у одного операнда есть "1”, и "0” там, где у обоих "0”
char a=0b00100010;
char b=0b10101010, c;
c=a||b; // результат – 0b10101010



ИСКЛЮЧАЮЩЕЕ-ИЛИ ("^”)
В результате "1” будет там, где значения битов не равны, а "0” там, где равны
char a=0b00100010;
char b=0b10101010, c;
c=a^b; // результат – 0b10001000


Инверсия ("~”)
Там, где было "0”, становится "1” и наоборот
char a=0b01010101, b;
b=~a; // результат – 0b10101010


Увеличение или уменьшение на единицу ("++”, "--")
int i=0, j=5;
i++; // к значению i прибавили 1 и записали обратно а i, т.е., i теперь равно единице.
j--; // о значения j отняли 1 и записали обратно а j, т.е., j теперь равно четырем.




Логические операции

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

Думаю, операторы "”, "=”, будут понятны всем.
А вот равенство проверяется двойным знаком равно "==”, если поставить одно равно, то это уже будет присвоение и программа будет работать неправильно!
Отрицание "!” – ставится перед логической операцией и инвертирует ее результат, т.е., если результатистина, то !результатложь
например, если
char a=2, b=2;
a<b - ложь
a<=b - истина
a!=b - ложь
a==b - истина
!(a==b) - ложь

и т.д.