
- •Основы языка си для микроконтроллеров avr
- •1. Основы языка Си для микроконтроллеров avr
- •Препроцессор языка Cи его команды
- •Директива #include
- •Директивы #define, #undef
- •Директивы #if, #ifdef, #ifndef, #else и #endif
- •Встроенные макросы
- •Директива #line
- •Директива #error
- •Директивы #asmи #endasm
- •Зарезервированные ключевые слова
- •Идентификаторы
- •Комментарии
- •Константы
- •Переменные
- •Массивы
- •Типы данных
- •Операнды и операции
- •Унарные операции
- •Бинарные операции
- •Приоритеты операций и порядок вычислений
- •Операторы
- •If-else
- •Оператор for
- •Do-while
- •Continue
- •Оператор-выражение
- •Пустой оператор
- •Составной оператор
- •Функции
- •Указатели
- •Доступ к регистрам ввода/вывода
- •Побитовый доступ к регистрам ввода/вывода
- •Доступ к eeprom-памяти
- •Использование прерываний
- •Организация памяти sram
Указатели
Указатель — это переменная, содержащая адрес другой переменной. При объявлении переменной типа указатель необходимо определить тип объекта данных, адрес которых будет содержать переменная, и имя указателя с предшествующей звездочкой (*).
Синтаксис:
[ кодификатор места хранения переменной>] type [«модификатор места хранения указателя;»] имя_указателя;
или
type [кодификатор места хранения переменной>]*[кодификатор места хранения указателя>] имя_указателя;
где type может быть любым типом данных (int, char, struct и т. д.).
Пример:
unsigned int * а; // переменная а представляет собой указатель на переменную типа unsigned int (целое без знака)
char * х; // переменная х представляет собой указатель на переменную типа char
int nomer; // Объявляем целую переменную nomer
int *addres; // Переменную addres объявляем как указатель,
addres = & nomer; // ей присваиваем адрес переменной nomer (& - операция вычисления адреса)
int х,у; // Объявляем целые переменные х и у
int *point_x; // Переменная point_x объявлена как указатель,
point_x = &х; // ей присваивается адрес переменной х,
у = *point_x; // Переменной у присваивается значение х, это равносильно оператору: у = х;
Из-за Гарвардской архитектуры микроконтроллеров AVR, с раздельным пространством адресов для данныхSRAM, программыFLASH- иEEPROM-памяти, компиляторCodeVisionAVRимеет три типа указателей.
Для доступа к переменным, расположенным в SRAM, используются обычные указатели.
Для доступа к константам, расположенным во FLASH-памяти, используется модификатор типа места храненияflash.
Для доступа к переменным, расположенным в EEPROM, используется модификатор типа места храненияeeprom.
Хотя указатели могут указывать на различные области памяти, по умолчанию они хранятся в SRAM.
Пример:
/* Указатель на символьную строку, расположенную в SRAM */
char *point_to_sram = "String in SRAM";
/* Указатель на символьную строку, расположенную во FLASH */
flash char *point_to_flashl = "Stringl in FLASH";
char flash *point_to_flash2 = "String2 also in FLASH";
/* Указатель на символьную строку, расположенную в EEPROM */
eeprom char *point_to_eepl = "Stringl in EEPROM";
char eeprom *point_to_eep2 = "String2 also in EEPROM";
Для того чтобы сохранить сам указатель в других областях памяти, типа FLASHилиEEPROM, должны быть использованы модификаторы хранения указателяflash илиeeprom.
Пример:
/* Указатель - во FLASH, символьная строка - в SRAM */
char *flash flash_point_to_sram = "String in SRAM";
/* Указатель - во FLASH, символьная строка - во FLASH */
flash char *flash flash_point_to_flash = "String in FLASH";
/* Указатель - во FLASH, символьная строка - в EEPROM */
eeprom char *flash flash_point_to_eep = "String in EEPROM";
/* Указатель - в EEPROM, символьная строка - в SRAM */
char *eeprom eep_point_to_sram = "String in SRAM";
/* Указатель - в EEPROM, символьная строка - во FLASH */
flash char *eeprom eep_point_to_flash = "String in FLASH";
/* Указатель - в EEPROM, символьная строка - в EEPROM */
eeprom char *eeprom eep_point_to_eep = "String in EEPROM";
Указатели на области памяти FLASHиEEPROMвсегда используют 16 битов.
Поскольку указатели во FLASH-памяти используют 16 битов, общий размер массива констант и символьных строк не может превышать 64 К дляATmegal03 илиATmegal28. Тем не менее общий размер программы для этих чипов может быть 128 К.
Указатели могут быть сгруппированы в массивы, которые могут иметь до 8 измерений.
Пример:
/* Глобальные массивы указателей */
/* Объявим и инициализируем глобальный массив указателей на символьные строки, размещённые в SRAM. Сам массив указателей - в SRAM */
char *array_point[4] = {"Str_sraml","Str_sram2","Str_sram3","Str_sram4"};
/* Объявим и инициализируем глобальный массив указателей на символьные строки, размещённые во FLASH. Сам массив указателей - во FLASH */
flash char *flash array_point_flash[2] = {"Str_flashl","Str_flash2"};
/* Объявим и инициализируем глобальный массив указателей на символьные строки, размещенные в EEPROM. Сам массив указателей - в EEPROM */
eeprom char *eeprom array_point_eep[3] = {"Str_eepl","Str_eep2","Str_eep3"}
Пример:
/* Локальные массивы указателей */
/* Объявим и инициализируем несколько строк в EEPROM */
eeprom char strl[]="Stringl";
eeprom char str2[]="String2";
eeprom char str3[]="String3";
/* Основная функция программы */
void main(void) {
/* Объявим локальный массив указателей на символьные строки, размещённые в EEPROM. Сам массив указателей - в SRAM */
char eeprom *local_array_point[3];
/* и инициализируем массив */
local_array_point[0] = strl;
local_array_point[1] = str2;
local_array_point[2] = str3;
}
Указатели функций всегда занимают 16 битов, поскольку они используются для доступа к области FLASH-памяти. Для этих типов указателей нет необходимости использовать ключевое словоflash.
Пример:
/* Указатели функций */
/* Объявим и определим функцию summa */
int summa(int x, int у, int z) {
return (x+y+z);
}
/* Объявим и инициализируем глобальный указатель функции summa */
int (*sum__ptr) (int x, int y, int z)=summa;
/* Основная функция программы */
void main(void) {
int i;
i=(*sum_ptr) (5,12,7); // Вызовем функцию summa с фактическими аргументами 5, 12 и 7, используя указатель. Функция вернёт сумму этих значений. В результате i=5+12+7=24