Contents
- Пример простой программы на Си для микроконтроллера AVR
- Общая структура памяти программы на Си
- Типы данных в Си
- Операции и операторы
- Указатели и ссылки в Си
- Операторы управления программой
- Общая структура программы на Си и функция main()
- Функции пользователя
- Массивы в Си
- Структуры, объединения, перечисления
- Препроцессор, директивы
- Ввод/вывод в C
Язык Си (без ++) — один из основных языков для программирования микроконтроллеров, поскольку здесь требуется высокая скорость, а оперативной памяти не бывает много.
Пример простой программы на Си для микроконтроллера 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.