Статья №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.
Здесь видно, что в программу введены две задержки: задержка по срабатыванию от внешнего сигнала и задержка после появления слова на дисплее. Таким образом, программа как бы пережидает дребезг и при нажатии кнопки и при её отпускании. Ниже приведена программа “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 (светодиода).
Это действо происходит до тех пор пока 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”.
Она состоит из основного цикла, в котором на дисплее отображается содержимое регистра 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
|