В данной статье рассматриваются азы программирования микроконтроллеров на Си. Язык программирования Си - высокоуровневый язык, основной идеей которого является работа с функциями, аргументы которых передаются как параметры. Любая функция состоит из имени и скобок с аргументами. Аргументы разделяются запятыми. Основное тело программы заключено в функцию main(). Любая программа должна содержать эту функцию т.к. с неё начинается работа программы.

Расмотрим пример простой программы для микроконтроллера AVR для компилятора WinAVR:

#include <avr/io.h>
#define F_CPU = 1000000UL;
#include <util/delay.h>

int main(void){
DDRD = 0b00000100;     // второй бит порта D - выход, остальные входы
while(1){
PORTD ^= 0b00000100;     // исключающее или - сменить состояние второго бита
_delay_ms(250);     // ожидание 250 мс
}
return 0;
}


В этой программе содержатся основные элементы языка.
Все препроцессорные команды начинаются со знака "#".

#include <avr/io.h> - препроцессорная команда которая подключает библиотеку аппаратных описаний микроконтроллера. В ней содержатся аппаратные адреса портов и регистров микроконтроллера. Используя эту библиотеку можно использовать легкозапоминающиеся мнемоники такие как: DDRD, PORTD, TCNT0, MCUCR... а не их адреса, которые не так легко запомнить. Например, ресли рассмотреть файл io.h для микроконтроллера ATtiny13:
...
/* Timer/Counter0 (8-bit) */
#define TCNT0                _SFR_IO8(0x32)

/* Timer/Counter 0 Control Register B */
#define TCCR0B               _SFR_IO8(0x33)
#  define FOC0A                7
#  define FOC0B                6
#  define WGM02                3
#  define CS02                 2
#  define CS01                 1
#  define CS00                 0
...


Заметить, что адресу  регистра Timer0 присваивается легкозапоминаемая мнемоника TCNT0.Поэтому в своей программе мы можем писать так:

TCCR0B |=(0<<CS02)|(1<<CS01)|(1<<CS00);     // устанавливаем коэффициент
// деления тактовой частоты
TCNT0 = 239;     // фактически записываем значение в регистр с адресом 0x32
DDRB |=(1<<1)|(1<<2);     // Делаем выходами первый и второй бит порта B (он же регистр ввода/вывода с адресом 0x17)


Если файл *.h заключен в двойные кавычки, то поиск файла проводится в папке проекта.

#define F_CPU = 1000000UL;     //указывает компилятору, что наш кристал тактируется от резонатора с тактовой частотой в миллиор герц т.е. 1МГц. "UL" - после числа показывает, что число Unsigned Long т.е. беззнаковое типа "long"


int main(void) - означает, что функция main возвращает значение типа int т.е. значения от 0 до 65535.


Открывающаяся фигурная скобка “{” показывает начало исполняемой части функции.

while(1){...} - бесконечный цикл, код заключенный в фигурные скобки будет выполняться бесконечно.


"//" - символы начала комментария, текст в строке после этих символов не включается в программу при компиляции.
"Return 0" - возвращает значение функции main(). Все функции должны заканчиваться закрывающимися фигурными скобками "}. После каждой команды надо ставить ";".

Основные типы данных:

Тип Название Размер в битах Диапазон значений
char Символ 8 -128...127
int Целое число 16 -32768...32767
float Вещественное число 32 ±10-38...±3*1038
long int Длинное целое 32 ±2147483647
unsigned char ASCII символ 8 0...255
unsigned int Беззнаковое целлое 16

0...65535

 
Для начинающих рекомендую почитать книгу Шпак Ю.А. "Программирование на языке С для AVR и PIC", скачать можно в нашем разделе книги по микроконтроллерам.
Вопросы задавайте на форуме.
 

 

Добавить комментарий


Защитный код
Обновить