Статья №2

  Переменная – это  величина, которая  может  меняться  в  процессе  выполнения программы. В  Bascom  переменная, а  следовательно  и  в  микроконтроллере, - это быстрое  осуществление  доступа  к  ячейке  памяти, данные  в  которой  могут  меняться.

    В  Bascom  переменные  бывают  следующих  типов:

               - числовые

               - строки

               - массивы

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

    В  Bascom  есть  следующие  типы  числовых  переменных:

    - Bit

Хранит  значение  0  или  1. Используется  для  хранения  состояния  кнопки, переключателя, контакта  порта  ввода/ вывода  и  др.

    - Byte

Xранит  в  памяти  один  байт  (8  бит). Используется  для  хранения  числа  от  0  до  255  или символа. Часто  используется  в  микроконтроллерах  AVR  типа tiny, когда  память ограничена. Необходимо  отметить, что  при  прибавлении  1  к  переменной  Byte, имеющей значение  255, она  сбрасывается  до  0.

    - Integer

Хранит  в  памяти  два  байта. Используется  для  хранения  числа  от  -32768  до  +32767. Так  как  один  бит  зарезервирован  под  знак  числа, оставшиеся  делятся 15  делятся  пополам  на  положительные  и  отрицательные  значения. При  переполнении  переменной  данного  типа, её  значение  изменится  с  +32767  на  -32768.

    - Word

Хранит  два  байта  информации, не имеющей  знака. Для  хранения  доступны  все  16  бит, т.е.  числа  от  0  до  65535. При  переполнении  значение  65535  изменяется  до  0.

    - Long

Хранит  в  памяти  4  байта. Из  32  бит  один  отводится  под  знак, а  остальные  хранят  модуль  числа  от   -2147483648  до  2147483647. При  переполнении  значение  переменной  +2147483647  изменится  на  -2147483648.

    - Single

Четырёхбайтный  тип  для  хранения  чисел  с  плавающей  запятой.  Запоминает   числа  от  1.5х10ˆ45  до  3.4x10ˆ38. Используется  только  для  хранения  дробных  чисел  не  более  девяти  знаков  после  запятой.

    

    Пример  описания  переменной:

   Dim  X  as  Byte          ‘ Объявим  переменную  Х  типа  Byte

          X = 100                  ‘ положим  в  неё  число  100

 

    Теперь  возвратимся  к  программе  “INT0”, которая  была  представлена  в  статье  №1.  Дело  в  том, что  только  идеальная  кнопка  может  строго  переключать  состояние  с разомкнутого  на  замкнутый  и  обратно, но  таких  кнопок  в  природе, к  сожалению, нет. При нажатии  и  отпускании  реальная  кнопка  выдаёт  серию  импульсов, называемых дребезгом, длительность  которого  может  достигать  50  миллисекунд. Таким  образом  мы получим  множество  прерываний  вместо  одного. Поэтому  необходимо  реализовать  функцию  антидребезга  с  помощью  введения  в  программу  задержки. Назовём  новую  программу   “INT0 + DEB”. Её  блок – схема  представлена  на  Рис.1. 

 

Рис.1 - Блок-схема программы "INT0+DEB"

 

Здесь  видно, что  в  программу  введены  две  задержки:  задержка  по  срабатыванию  от  внешнего  сигнала  и  задержка  после  появления  слова  на  дисплее. Таким  образом, программа  как  бы  пережидает  дребезг  и  при  нажатии  кнопки  и  при  её  отпускании. Ниже  приведена  программа  “INT0 + DEB”.

 

    Первая  задержка  создана  с  помощью  функции  задержки  срабатывания  от  внешних  сигналов  DEBOUNCE, а  вторая – с  помощью  Waitms. Они  равны, и  их  длительность  составляет  по  75 миллисекунд. В  остальном  же  программа  идентична  программе  “INT0”.

    

$Regfile = "attiny2313.dat"

$Crystal = 4000000

$hwstack = 40

$swstack = 16

$framesize = 32

 

config Portd.6 = output                                     'PD6-выход

config portd.6 = 0                                          'исходное состояние PD6=0

config PORTD.2 = input                                      'PD2-вход

config portd.2 = 1                                          'исходное состояние PD2=1 (подтяжка)

config INT0 = FALLING                                       'прерывание INT0 по спаду импульса

config DEBOUNCE = 75                                        'задержка внешних сигналов на 75мс

 

dim Wtime as Byte                                           'объявление переменной типа Byte

 

on Int0 Displey                                             'определение подпрограммы прерывания

 

cls                                                         'очистка дисплея

 

Wtime = 255                                                 'величина задержки

 

Enable INTERRUPTS                                           'включение всех прерываний

Enable INT0                                                 'вкючение прерывания INT0

 

do                                                          'начало цикла

cls

set Portd.6                                                 'установка PD6=1

waitms Wtime                                                'задержка=255 тактов

reset PortD.6                                               'установка PD6=0

waitms Wtime

loop                                                        'конец цикла

 

Displey:                                                    'подпрограмма обработки прерывания

Lcd "stop"                                                  'вывод на дисплей слова Stop

Waitms 75                                                   'задержка 75мс

return                                                      'оператор возврата из подпрограммы

 

end                                                         'end program

 

     

    Cама  программа  находится  в  папке  приложение 1  данной  статьи. 

 

    Теперь  пришло  время  поговорить  о  таймерах. Как  известно  микроконтроллер  ATtiny2313  имеет  четыре  таймера: два  восьмибитных  таймера – счётчика  (0А и 0В)  и  два  шестнадцатибитных  таймера – счётчика (1А и 1В), однако  скачанная  автором  из  интернета  версия  Bascom  не  поддерживает  данные  таймеры, поэтому  мы  будем  говорить  о  Timer0  и  Timer1  (версия  для  AT90S2313). Однако  все  сказанное  ниже  в  полной  мере  справедливо  и  для  ATtiny2313.

    Восьмибитный  таймер – счётчик  (Timer0)  может  принимать  значение  от  0  до  255. С помощью  команды  Config  мы  можем  задать  ему  коэффициент  деления  частоты:

               Config  Timer0 = Timer,  Prescale = 1|8|64|256|1024

    Здесь  Timer0  настроен  на  счёт. Он  считает  тактовые  импульсы  с  выхода  делителя  с  переменным  коэффициентом  деления  1, 8, 64, 256, 1024. Если  тактовая  частота  контроллера  4МГц, а  коэффициент  деления  1024, тогда  таймер  будет  увеличивать  значение  через  каждые  0.256 миллисекунд  (1024/4000000 Гц)  и  будет  переполняться  каждые  65 миллисекунд  (255 х 0.256). Timer1  подобен  Timer0, но  считает, поскольку  он  шеснадцатибитный, до  65535. Таймеры  начинают  осчёт  сразу  после  конфигурации.

    Таймеры  можно  запустить  и  остановить  в  любой  момент  командами  Start  и  Stop. Например:  Start  Timer0  и   Stop  Timer0  или  Start  Timer1  и  Stop  Timer1.

    Информацию  из  таймера  можно  считать  и  вывести, например, на  дисплей:

                                          . . . .

                                     Timcounter = Timer0

                                     Lcd  “inftimer”;  Timcounter

                                         . . . .

    Однако  при  этом  надо  помнить, что переменные  для  считывания  (и  для  записи)  должны  быть  определённого  типа:  для  Timer0  типа  Byte, для  Timer1  типа  Word . Пример  записи  в  таймер :

                                      Stop  Timer1

                                          . . . . 

                                      Timer1 = 560

                                         . . . .

                                       Start  Timer1

 

 

    Но  наиболее  часто  таймеры  используют  для  создания  прерываний, при  обработке  которых  выполняются  какие – либо  действия. В качестве  примера  рассмотрим  генератор  импульсов. Блок – схема  программы  “timer”  представлена  на  Рис.2, где  видно, что  основная  программа  представляет  из  себя  уже  известный  нам  по  предыдущим  программам  цикл:  включение  и  отключение  порта D6  (светодиода).

 

 Рис.2 - Блок-схема программы "timer"

 

Это  действо  происходит  до  тех  пор  пока  Timer0  не  дойдёт  до  переполнения, после  чего  наступает  прерывание  и,  естественно,  его  обработка, в течении  которой  инвертируется  PB1. С  этого  контакта  идёт  сигнал   частотой  отличной  от  частоты  сигнала  с  контакта  PD6. Tаким  образом,  мы  получили  двухчастотный  генератор. Программа  “timer”  представлена  ниже.   

     

$Regfile = "2313def.dat"

$Crystal=4000000

$hwstack=40

$swstack=16

$framesize=32

 

Config Pind.6 = Output                                     'PD6- выход

Config PinB.1 = Output                                     'PB1- выход

Config Timer0 = Timer , Prescale = 64         'коэфф.деления частоты

 

 

 

Dim Wtime As Byte                                          'определение переменной

 

On Timer0 Pulse:                                            'подпрограмма оработки прерывания

 

Wtime = 100

 

Enable INTERRUPTS                                   'включение прерываний

Enable Timer0                                               'влюч. прерываний по переполнению таймера0

 

Do                                                                    'начало цикла

  Set PORTD.6                                               'PD6=1

  Waitms Wtime                                             'задержка 

  Reset PORTD.6                                           'PD6=0

  Waitms Wtime

Loop                                                                 'конец цикла

      

Pulse:                                                            'обработка прерывания

  Toggle PortB.1                                            'инвертирование PB1

Return

 

End                                                                 'end program

 

    Данная  программа  находится  в  папке  Приложение 2  этой  статьи.

 

    Тimer1  может  работать  в  режиме  захвата. Это  значит, что  он  считает  тактовые  импульсы  через  предделитель  и, когда  на  вход  ICP  (PD6)  приходит  импульс, содержимое  Timer1  копируется  в  регистр  Input  Capture, что  позволяет  измерять  временные  интервалы  между  импульсами. 

    На  Рис.3  представлена  блок – схема  программы  “CAPT”.

 

 Рис .3 - Блок-схема программы "CAPT"

 

Она  состоит  из  основного  цикла, в  котором  на  дисплее  отображается  содержимое  регистра  ICP, и подпрограммы  обработки  прерывания  по  приходящему  импульсу, где  происходит  считывание  данных  из  регистра  захвата  и  сброс  Timer1. Программа  “CAPT”  приведена  ниже: 

 

$Regfile = "2313def.dat"

$Crystal = 4000000

$hwstack = 40

$swstack = 16

$framesize = 32

 

config PortD.6 = input

config TIMER1 = TIMER , PRESCALE = 64 , Capture Edge = Rising       'коэфф.деления 64,импульс по фронту

 

dim Wtime as Byte                                           'объявление переменных

dim Timcount as Word

 

on Capture1 Capt                                            'подпрог. обработки прерывания

 

Wtime = 100

Timcount = 0

 

enable INTERRUPTS                                           'разрешение прерываний

enable Capture1                                             'разрешение  прерываний по захвату

 

Do

Waitms Wtime

Cls

Lcd "Timer:" ; " " ; Timcount

Loop

 

Capt:                                                       'обработка прерывания

Timcount = capture1                                         'считывание из регистра захвата

Timer1 = 0                                                  'сброс таймера

return

 

End                                                         'end program

 

 

    В подпрограмме  обработки прерывания  информация  Timer1, сброшенная  в  регистр  захвата  capture1  копируется  в  Timcount, затем  таймер  очищается. При  последующем  импульсе  на  ICP  входе  цикл  повторяется, следовательно  Timcount  считает  время  между  импульсами на  ICP. Программа находится в папке Приложение 3.