Си для микроконтроллеров и чайников. Часть 1. Программные переменные и регистры микроконтроллера.. Раздел: Начинающим.

Eugene's MCU

Воскресенье, 13.07.2014, 18:02

Главная | | Мой профиль | Выход | RSS
Меню сайта
Категории каталога
Рекламный блок





Рекомендовать этот сайт:

Главная » Статьи » » Начинающим


Си для микроконтроллеров и чайников. Часть 1. Программные переменные и регистры микроконтроллера.
Краткое предисловие для начинающих: прочитать
   
     Начнём знакомство с использованием языка Си применительно к программированию микроконтроллеров  с выяснения общих вопросов, которым в существующих руководствах уделяется на удивление мало внимания.
 
§ > Общие вопросы. Переменные объявляемые пользователем.
     
     Итак, язык C - типичный представитель абстрактных языков программирования, а это значит, что его совершенно не интересует какого рода информацию мы будем обрабатывать, будь то содержимое компьютерного файла или внутренние управляющие регистры микроконтроллера.
  
     Основной объект программирования для классического Си - переменная. Это может быть одиночная или группа особым образом связанных переменных, например, массив или структура. По сути переменная представляет из себя некое хранилище для числа, имеющее своё уникальное имя и допустимый диапазон значений, выходить за пределы которого крайне нежелательно. И первое что мы должны сделать перед тем как начать использовать имя переменной в тексте программы это познакомить программу с её свойствами. В языке Си этот процесс называется объявлением переменной.
  
     Зачем нужно объявлять переменные?
  
     Хоть язык Си и абстрактный, используемый разработчиком микроконтроллер, как правило, вполне конкретный и имеет своё адресное пространство памяти с заданными свойствам, где и будет храниться объявляемая переменная. Объявление, помимо присвоения переменной имени, заставляет компилятор разместить её по конкретному адресу в памяти микроконтроллера (по какому именно нас в большинстве случаев совершенно не интересует).
  
     Как нужно объявлять переменные?
  
     Правило для объявления можно формулировать так: до того как мы впервые употребим имя переменной в тексте нашей программы, необходимо размесить её объявление в следующем формате:

       
    type name;  // Переменная с именем "name" и типом "type".
   
 
   
     здесь: type - так называемый идентификатор типа переменной из определённого набора стандартных типов;
     name - произвольное имя переменной, лишь бы оно не начиналось с цифры, состояло только из латинских символов, и не совпадало со служебными словами языка Си (список которых не так велик, чтобы столкнуться с такой ситуацией нужно на самом деле очень постараться).
  
     Что такое идентификатор типа и зачем его упоминать?
  
     Для хранения переменной микроконтроллер использует ячейки памяти, размер которых определяется его разрядностью. Так например, микроконтроллеры семейства AVR - 8-разрядные, а значит для хранения данных используют ячейки памяти размером в один байт, которые способны сохранять 256 различных числовых значений. Если ожидаемые значения переменной могут превысить это количество, то для её хранения понадобится две или более ячеек памяти. Поскольку Си, строго говоря, не представляет какие значения мы планируем присваивать переменной, то просит нас указать её тип, который как раз и определяет допустимый диапазон значений. Это необходимо чтобы не зарезервировать за ней избыточный или недопустимо малый объём памяти, а так же предупреждать нас при попытке присвоить слишком большое значение переменной, не способной его сохранить. Для 8-разрядных микроконтроллеров наиболее часто употребимые целочисленные типы данных следующие:
  
     способные хранить только положительные значения (беззнаковые):
     unsigned char - занимает один байт памяти, значения 0...255
     unsigned int - два байта, значения 0...65535
     unsigned long - четыре байта,  от 0 до (2^32)-1 
     способные хранить значения со знаком (знаковые):
     signed char - занимает один байт памяти, от -128...127
     signed int - два байта, значения -32768...32767
     signed long - требует четыре байта, значения от -(2^31) до (2^31)
   
     Ключевое слово "unsigned" (беззнаковое), вообще говоря, можно не употреблять, поскольку в Си по умолчанию тип, для которого не указан этот признак, считается беззнаковым. 
     Для работы с дробными числами в Си предусмотрены типы с плавающей точкой:
  
     float – 32 бита, значения от ±1.18E-38 до ±3.39E+38
     double – 32 (±1.18E-38…±3.39E+38) или 64 бита (±2.23E-308…±1.79E+308) в зависимости от настроек компилятора.
  
     Примечание: размер памяти для хранения переменных указанных типов и диапазон допустимых значений может незначительно меняться в зависимости от среды разработки или семейства микроконтроллеров.
  
     Для того чтобы перед началом использования переменной она уже имела конкретное значение, к объявлению часто дописывается инициализатор: знак равенства (в Си это оператор присваивания) и начальное значение переменной.

     Например:   
       
    int A=100;  // Переменная с именем "А" типом int и начальным значением равным 100.
    

     Практический пример: пусть планируется написать программу, мигающую светодиодом 5 раз. Для подсчёта числа миганий потребуется переменная, значение которой, очевидно никогда не будет отрицательным и не выйдет за пределы диапазона от 0 до 255, а значит в данном случае будет вполне достаточно использовать однобайтовый тип char:
  
       
    unsigned char ChisloMiganiy=0;
    
    
 
§ > Область видимости переменной.
 
     Источником многих затруднений для начинающих становится свойство языка, которое называется областью видимости объявленной переменной. Язык Си имеет возможность ограничить действие переменной конкретной областью программного кода, при этом в других частях программы она становится недоступной, благодаря чему высвобождается память, которая на других участках программы может использоваться другими переменными. Такие переменные называются локальными, а их использование - основной способ получения экономичного кода.
  
     На начальном этапе обучения все переменные желательно объявлять как глобальные. Для этого их объявления необходимо размещать в самом начале программы до и вне каких либо функций. В этом случае Вы можете быть уверены, что они будут доступны для работы в любом месте программы в пределах текущего файла.
 
§ > Область размещения переменной.
 
     Как известно, микроконтроллеры семейства AVR содержат три области памяти, реализованные по разным технологиям. Каждая из них имеет своё назначение и адресное пространство, нумерованное от нуля до максимального значения для конкретной модели:

     Для хранения пользовательских переменных может быть использована ОЗУ, энергонезависимая память EEPROM, а для хранения констант, значение которых не может быть изменено в процессе работы программы также и FLASH- память микроконтроллера.
  
     Для начала полезно знать, что переменные, объявленные пользователем без использования специальных ключевых слов типа _eeprom или _flash, размещаются в ОЗУ микроконтроллера, в виде одной или нескольких ячеек статической памяти SRAM. В процессе работы они периодически копируются в быструю регистровую память РОН, которая непосредственно взаимодействует с арифметически-логическим блоком АЛУ микроконтроллера. 
Вопросы размещения переменных внутри ОЗУ, как правило, представляют интерес только в контексте быстродействия программы.
 
§ > Регистры специального назначения микроконтроллера SFR.
   
     Итак, мы кратко рассмотрели объявление переменных предназначенных для организации вычислительного процесса, которые мало связаны со спецификой аппаратной части МК. 
  
     Управление и контроль работы микроконтроллера и его отдельных внутренних модулей осуществляется путём записи и чтения специальных ячеек-регистров в служебной области памяти ОЗУ - регистров специального назначения (Special Function Register, далее просто SFR). 
  
     Основная идея, позволяющая использовать Си для программирования микроконтроллеров, такова: регистры специального значения являются такими же переменными языка Си, как и объявленные пользователем. Этим переменным можно присваивать значения, управляя работой микроконтроллера, или считывать их, получая таким образом информацию о его текущем состоянии. Объявлять регистры микроконтроллера подобно пользовательским переменным не нужно по нескольким причинам. Во-первых, их размер заранее известен: в Си для AVR это беззнаковые 8-разрядные переменные. Во-вторых, SFR имеют строго определённые имена и адреса в памяти, являясь так называемыми регистрами ввода-вывода.
  
     Тем не менее знакомить программу с регистрами спецназначения нужно, и делается это с помощью подключения так называемых заголовочных файлов.

     В начале любой программы на Си мы можем видеть строки типа:  
    
   #include "file1.h" // Включить в код содержимое файла "file1.h".
  
    
     #include - это директива (указание), заставляющая среду разработки поместить в данное место программы содержимое файла с именем file1.h. Файлы с расширением .h называются заголовочными или h-файлами. Разработчик может создавать собственные h-файлы и помещать их, учитывая содержимое, в любое место программы. Однако, чтобы познакомить программу с SFR для данного типа микроконтроллера, необходимо подключать вполне конкретные заголовочные файлы. Их имена и количество зависит от конкретной среды разработки и типа используемого микроконтроллера, так, например, в IAR для Atmega64 достаточно прописать строки: 
  
    
   #include "iom64"
   #include "inavr.h"
  
  
     После включения в текст необходимых h-файлов программа будет узнавать упоминаемые в ней имена SFR, например, регистр статуса микроконтроллера AVR с именем SREG, буфер приёма/передачи модуля UART - UDR и так далее.
  
  Заготовка программы для IAR, которая ничего не делает, но уже не "ругается" на имена регистров специального назначения микроконтроллера Atmega16, должна выглядеть так:
  
    
   #include "iom16.h"
   #include "inavr.h"
   unsigned char ChisloMiganiy=0;
   void main (void)
   {
        // Здесь мы разместим программу, использующую переменную ChisloMiganiy
        // и любые регистры Atmega16, имена которых прописаны в файле iom16.h.
   }
  
    
     Хочется надеяться, что читатель знаком с правилами оформления комментариев в тексте программы. Это заметки, которые игнорируются языком Си и не считаются частью программного кода, если записаны в одной и более строках, заключённых между символами /* и */, или в одной строке, начинающейся с последовательности //.
     



При использовании материалов сайта ссылка на данный источник обязательна.

Категория: Начинающим | Добавил: eugenemcu (22.10.2009) | Автор:

Просмотров: 66847 | Рейтинг: 4.9/30 |
Всего комментариев: 0
Статистика

Наш магазин




Какую среду разработки Вы используете?

[ Результаты · Архив опросов ]
Всего ответов: 1556



Им нужна Ваша помощь: