Ноя 092018
 

Contents

Язык Си (без ++) — один из основных языков для программирования микроконтроллеров, поскольку здесь требуется высокая скорость, а оперативной памяти не бывает много.

Пример простой программы на Си для микроконтроллера AVR

Это текст программы компиляторов типа AvrStudio, CodeVisionAVR и т.п.

 #include // заголовочный файл для ввода-вывода #include #define BV(x) (1 << x) int main(void) { DDRC=0xFF; // порт PORTC настроен на выход PORTC=0xFF; // установка уровней на порте PORTC while(1) // начало цикла { PORTC=~(BV(5)); // переключение 5-го бита порта PORTC _delay_ms(1000); // задержка 1 секунда PORTC=BV(5); // переключение 5-го бита порта PORTC обратно _delay_ms(1000); } return 0; }

Функция main — это точка входа в программу, с которой компьютер начинает выполнение программы.

Допускается из main возвращать void, хотя это не по стандарту, так что лучше int.

В функцию main можно передавать аргументы командной строки:

int main(int argc, char* argv[]) { }

Вообще говоря, мы можем писать программу для MK AVR также на языке Processing/Wiring. Это тот же Си, но упрощенный. Но компилироваться это будет только в Arduino IDE или т.п., а потом можно загружать полученный hex в наш микроконтроллер. При этом не обязательно, чтобы МК стоял на плате Arduino. Разницы то нет.

Вот так выглядит аналогичная программа на Processing/Wiring:

int ledPin = 13; void setup() { pinMode(ledPin, OUTPUT); } void loop() { digitalWrite(ledPin, HIGH); delay(1000); digitalWrite(ledPin, LOW); delay(1000); }

Здесь не надо подключать хеддеры для МК, т.к. они подключатся автоматом. Но для внешних модулей могут понадобится. Короче, про Ардуино подробнее читайте здесь

http://ar.com/basic/uno

а пока мы вернемся к языку Си.

Общая структура памяти программы на Си

— куча — для динамического выделения памяти

— стек — локальные переменные класса памяти auto (включая аргументы функций)

— DATA — константы

— CODE — исполняемый код, инструкции процессора

Типы данных в Си

-Базовые типы данных: char, int, float, double.

-Модификаторы знака: signed, unsigned.

-Модификаторы знака: long, short.

void — тип без значения

При этом следующие типы равны:

int = signed int = signed // 16 или 32 бит (зависит от платформы ) unsigned = unsigned int char = signed char	// 8 бит (от -128 до 127) (ASCII) unsigned char // 8 бит (от 0 до 255) wchar_t // UNICODE

В Си логический тип реализован неявно (с помощью int): false = нуль, true = не нуль.

Введение псевдонимов для ранее описанных типов данных:

typedef тип имя

где тип — любой существующий тип данных, имя — новое имя для этого типа.

Пример: typedef unsigned char byte;

Преобразование типов:

Если операнды операции имеют разные типы, то происходит неявное приведение типов:

double a = 1.222; int i = a; // дробная часть отсекается! double x = 2/5;	// результат будет 0 !

(чтобы здесь получить 0.4 нужно было бы написать x=2.0/5 или 2/5.0)

Явное приведение типов:

int a=2, b=5; double b = (double)a / b;	// результат будет b=0.4

Принудительное преобразование типов:

(тип) выражение;

(желательно вообще избегать преобразования типов)

Переменные и константы

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

Декларация переменных (вместе с инициализацией):

[класс памяти] [квалификаторы] [модификаторы] тип идентификатор = инициатор;

Например,

static const unsigned char x = 100;

Здесь «;» — составляющая часть конструкции, завершающая часть.

Допустима (хотя и редко используется) запись: const x = 100; (по умолчанию int).

Квалификаторы (или «модификаторы доступа»): const, volatile.

const — означает, что переменные не могут изменяться во время выполнения программы; инициалиировать можно только при декларации;

volatile — содержимое переменной может измениться само собой (используется в многопоточных программах при взаимодействии процессов)

Возможен вариант const volatile, когда писать могут только снаружи.

Спецификторы хранения (описатель класса памяти): auto, register, extern, static.

auto — локальные переменных (по умолчанию) — программный стек.

register — просьба компилятору положить переменную в регистр ЦПУ (но он эту просьбу редко выполняет);

extern — объявление (declaration) переменных, но не определение (definition) (определение где-то в другом месте); определение может идти ниже по файлу (но как глобальная) или в другом файле.

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

Понравилось? Поделитесь:

:

Sorry, the comment form is closed at this time.