Смекни!
smekni.com

Устройство управления системой измерения веса (стр. 2 из 3)

7 6 5 4 3 2 1 0
- - - - - CS02 CS01 CS00
R R R R R R/W R/W R/W

Рис. 3.3 – Регистр управления таймером/счетчиком0 TCCR0

Биты 7…3 зарезервированы и всегда читаются как 0.

Биты 2, 1, 0 – выбор коэффициента деления предварительного делителя.

CS02 CS01 CS00 Значение
0 0 0 Стоп
0 0 1 СК
0 1 0 СК/8
0 1 1 СК/64
1 0 0 СК/256
1 0 1 СК/1024
1 1 0 Вн. Сигнал Т0, нар. фронт
1 1 1 Вн. Сигнал Т0, спад. фронт

Рис. 3.4–Выбор коэффициента деления предварительного делителя.

TCNT0 – данный регистр служит для загрузки и считывания показаний счетчика/таймера0.

7 6 5 4 3 2 1 0
MSB LSB
R/W R/W R/W R/W R/W R/W R/W R/W

Рис. 3.5 – регистр текущего значения счетчика TCNT0


TIMSK – данный регистр служит для установки и сброса флагов разрешения работы прерываний таймеров.

7 6 5 4 3 2 1 0
OCIE2 TOIE2 TICIE1 OCIE1A OCIE1B TOIE1 OCIE0 TOIE0
R/W R/W R/W R/W R/W R/W R/W R/W

Рис. 3.6 – регистр масок прерываний таймеров

TOIE1 – разрешение прерывания по переполнению таймера/счетчика 0

OCIE1A - разрешение прерывания по совпадению таймера/счетчика 1

TIFR - данный регистр содержит флаги прерываний таймеров

7 6 5 4 3 2 1 0
OCF2 TOV2 ICF1 OCF1A OCF1B TOV1 OCF0 TOV0
R/W R/W R/W R/W R/W R/W R/W R/W

Рис. 3.7 – регистр флагов прерываний таймеров.

TOV1 – флаг переполнения таймера/счетчика 0. 1 – произошло переполнение

OCF1A – флаг выхода совпадения 1А. 1 – произошло совпадение значения таймера/счетчика 1 и данных в регистре OCR1A.

3.2.2 Инициализациятаймера/счетчика1

16-разрядный таймер/счетчик может получать импульсы тактовой частоты – СК с предварительного делителя (СК/8, СК/64, СК/8256, СК/1024), импульсы с внешнего вывода или быть остановлен соответствующими установками регистра TCCR1B. Флаги состояния таймера (переполнения, совпадения и захвата) и управляющие сигналы находятся в регистре TIFR. Разрешение и запрещение прерываний от таймера управляется регистром TIMSK.

Таймер/счетчик1 поддерживает функцию совпадения, используя регистр совпадения OCR1A в качестве источника для сравнения с содержимым счетчика. Функция совпадения поддерживает очистку счетчика по совпадению.

TCNT1 - данный регистр служит для загрузки и считывания показаний счетчика/таймера.

15 14 13 12 11 10 9 8
MSB
LSB
7 6 5 4 3 2 1 0

Рис. 3.8 – регистр текущего значения счетчика TCNT1

TCCR1B – регистр управления таймером/счетчиком1

7 6 5 4 3 2 1 0
ICNC1 ICES1 - WGM13 WGM2 CS12 CS11 CS10
R/W R/W R/W R/W R/W R/W R/W R/W

Рис. 3.9 – Регистр управления таймером/счетчиком1 TCCR1B

Биты 2, 1, 0 – выбор коэффициента деления предварительного делителя.

CS02 CS01 CS00 Значение
0 0 0 Стоп
0 0 1 СК
0 1 0 СК/8
0 1 1 СК/64
1 0 0 СК/256
1 0 1 СК/1024
1 1 0 Вн. Сигнал Т1, нар. фронт
1 1 1 Вн. Сигнал Т1, спад. фронт

Рис. 3.10–Выбор коэффициента деления предварительного делителя.

Инициализация таймера/счетчика1 происходит только при вызове функции Time wate (), которая устанавливается делитель частоты на 1024, путем записи значения PrescalerTmr1= 5 в регистр TCCR1B.

OCR1A – регистр совпадения А таймера/счетчика1. В этом регистре хранятся данные, которые непрерывно сравниваются с текущим значением таймера/счетчика1. Действие по совпадению задается регистрами управления таймером/счетчиком1 и регистром состояния.

15 14 13 12 11 10 9 8
MSB
LSB
7 6 5 4 3 2 1 0

Рис. 3.11 - регистр совпадения А таймера/счетчика1 OCR1A

Рассчитаем значение, которое необходимо занести в OCR1A для сравнения с содержимым таймера/счетчика1.

Количество тактовых импульсов, которые приходят на таймер/счетчик1 за 1 секунду, рассчитывается по формуле:

, где

К – значение делителя частоты

f – значение частоты генератора

Выбираем значение делителя частоты 1024, т.к. это максимально возможный коэффициент деления/задержки. Частота генератора задается путем подключения кварцевого резонатора к соответствующим выводам контроллера. В данном случае был выбран кварц на 7, 3728*106 Гц.

Т.к. необходима выдержка в 5 секунд то:

7200*5=36000

Т.к. прерывание по совпадению таймера/счетчика1 происходит только на следующий такт после совпадения, необходимо от значения 36000 вычесть 1. Это значение присваивается переменной comp_t1=35999, которая заносится в OCR1A.

voidTime_wate(void)

{#asm("cli")

TCCR1B = PrescalerTmr1;

OCR1A = comp_t1;

#asm("sei")

while (Tmr1Flag == 0)

}

3.3 Процедура обработки нажатия кнопки Пуск

Процедура обработки нажатия кнопки Пуск, вызывается при переполнении таймера/счетчика0. Использование таймера для проверки состояния порта через заданные интервалы времени является некоторой защитой от импульсных помех. Еще более повысить устойчивость приема сигнала от датчика импульсов в условиях помех можно за счет использования мажоритарного элемента. Если известно текущее состояние входного сигнала и два его предшествующих состояния, то значение сигнала определяется по следующему принципу:

OldOldPortSignal OldPortSignal NewPortSignal RealSignal Comment
0 0 0 0 НОЛЬ!
0 0 1 0 Кажется, ноль
0 1 0 0 Кажется, ноль
0 1 1 1 Кажется, единица
1 0 0 0 Кажется, ноль
1 0 1 1 Кажется, единица
1 1 0 1 Кажется, единица
1 1 1 1 ЕДИНИЦА!

void CheckButton (void)

{

unsigned char b;

static char OldPortSignal;

static char OldOldPortSignal;

NewPortSignal = PINC&1; //select PC0 - START_button

b = PINC&7; //select PC1,PC2 - bunker sensors

if((NewPortSignal != OldPortSignal) & (NewPortSignal != 0)) // Positive front found

{ RealSignal = (NewPortSignal ^ OldPortSignal) ^ OldOldPortSignal;

OldOldPortSignal = OldPortSignal;

OldPortSignal = RealSignal;

if(b) //bunker CLOSED!

{

PORTA=0x01; //PA0 - transporter ON!

Time_wate(); //wate 5 sec!

Tmr1Flag = 0;

PORTA=0x03; //PA0&PA1 - bunker OPEN!

}

}

}

3.4 Процедураиндикации

Выводит на на 4х разрядный 7-ми сегментный индикатор количество совершенных отгрузок. Индикатор подключен к порту В микроконтроллера. Управление разрядами индикатора осуществляется через порт D.

В процедуре используются 3 функции.

Первая Bin2BCD_4Digit выполняет преобразование числа отгрузок, представленных в двоичном виде, в BCD число и поразрядно заносит его в массив BufBCD:

void Bin2BCD_4Digit (unsigned int data)

{

unsigned char i;

for(i=0;i<4;i++)

{

BufBCD[i] = data % 10;

data /= 10;

}

Вторая функция Bin2Seg_4Digit преобразовывает полученное BCD число в семисегментный эквивалент (путем вызова функции Bin2Seg) и заносит результаты в массив BufSeg. Семисегментные эквиваленты представлены в виде заранее определенных значений

#define Dig0 SegA + SegB + SegC + SegD + SegE + SegF + 0

#define Dig1 0 + SegB + SegC + 0 + 0 + 0 + 0

#define Dig2 SegA + SegB + 0 + SegD + SegE + 0 + SegG

#define Dig3 SegA + SegB + SegC + SegD + 0 + 0 + SegG

#define Dig4 0 + SegB + SegC + 0 + 0 + SegF + SegG

#define Dig5 SegA + 0 + SegC + SegD + 0 + SegF + SegG

#define Dig6 SegA + 0 + SegC + SegD + SegE + SegF + SegG

#define Dig7 SegA + SegB + SegC + 0 + 0 + 0 + 0

#define Dig8 SegA + SegB + SegC + SegD + SegE + SegF + SegG

#define Dig9 SegA + SegB + SegC + SegD + 0 + SegF + SegG

#define DigMinus 0 + 0 + 0+ 0 + SegЕ +0 + 0

unsigned char Bin2Seg (unsigned char data)

{

switch(data)

{

case 0: return Dig0;

case 1: return Dig1;

case 2: return Dig2;

case 3: return Dig3;

case 4: return Dig4;

case 5: return Dig5;

case 6: return Dig6;

case 7: return Dig7;

case 8: return Dig8;

default: return Dig9;

}

}

//== Convert 4 digits from BinBuf[] into SegBuf[] ==========

void Bin2Seg_4Digit (void)

{

unsigned char i;

for(i=0;i<4;i++)

{

BufSeg[3-i] = Bin2Seg(BufBCD[i]);

}

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

void Ind (void)

{

unsigned char i;

for(i=0;i<4;i++)

{

PositionPort = AllDigitsOFF;

SymbolPort = BufSeg(i);

PositionPort = DigitNmb(i)

}


4.Листингпрограммы

Файл ind.h

//== Include files =================================

#include <mega16.h>

#define PortBMask 0xFF

//== Common declarations ============================

#define SymbolPort PORTB

#define SegA 1 // aa

#define SegB 2 // f b

#define SegC 4 // f b

#define SegD 8 // gg

#define SegE 16 // e c

#define SegF 32 // e c

#define SegG 64 // dd

#define Dig0 SegA + SegB + SegC + SegD + SegE + SegF + 0

#define Dig1 0 + SegB + SegC + 0 + 0 + 0 + 0

#define Dig2 SegA + SegB + 0 + SegD + SegE + 0 + SegG

#define Dig3 SegA + SegB + SegC + SegD + 0 + 0 + SegG

#define Dig4 0 + SegB + SegC + 0 + 0 + SegF + SegG

#define Dig5 SegA + 0 + SegC + SegD + 0 + SegF + SegG

#define Dig6 SegA + 0 + SegC + SegD + SegE + SegF + SegG

#define Dig7 SegA + SegB + SegC + 0 + 0 + 0 + 0

#define Dig8 SegA + SegB + SegC + SegD + SegE + SegF + SegG

#define Dig9 SegA + SegB + SegC + SegD + 0 + SegF + SegG

#define DigMinus SegA + SegB + SegC + SegD + 0 + SegF + SegG

#define PositionPort PORTD

#define Position0 0

#define Position1 1

#define Position2 2

#define Position3 3

#define AllDigitsOFF 4

#define DigitNmb = [254, 253, 251, 247]

//== Global Variables =========================

unsigned char BufSeg[4];

unsigned char BufBCD[4];

void Bin2BCD_4Digit (unsigned int data);

//== Convert binary char into 7 Segment Code =============

unsigned char Bin2Seg (unsigned char data)