Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
686.docx
Скачиваний:
85
Добавлен:
24.04.2019
Размер:
6.68 Mб
Скачать

6.4 Программирование таймера

Микроконтроллер ADuC812 имеет три программируемых 16-битных

таймера/счетчика: Таймер 0, Таймер 1, Таймер 2. Каждый таймер состоит из

двух 8-битных регистров THX и TLX. Все три таймера могут быть настроены

на работу в режимах “таймер” или "счетчик". Организация и принцип работы

Таймера 0 и 1 рассмотрена в подразделе 2.2.6.1.

Чтобы

настроить

таймер

на

определенную

частоту

(работа

по

прерыванию) в МК ADuC812 стенда SDK-1.1, необходимо выполнить

следующую последовательность действий:

 Выбрать один из 4-х режимов работы таймера (регистр TMOD);

 Настроить таймер на заданную частоту (инициализировать регистры

THx, TLx);

 Включить таймер (регистр TCON);

251

 Написать обработчик прерывания от таймера и установить вектор

прерывания в пользовательской таблице прерываний (внешняя память

данных начиная с адреса 2003h);

 Разрешить прерывания от выранного таймера (регистр IE);

 Разрешить все прерывания (регистр IE).

В

приведенном

примере

программы

реализована

анимация

на

светодиодных индикаторах. Исходные коды драйвера ПЛИС смотрите в

разделе 6.2.

unsigned long __systime = 0;

///////////////////////////////////////////////////////////////////////////

// Инициализация Таймера 0 (1000Гц)

///////////////////////////////////////////////////////////////////////////

void InitSystimer0( void )

{

TCON = 0x00; // Выключение таймера 0 (и таймера 1)

TMOD = 0x01; // Выбор режима работы 16-разрядный таймер

TH0 = 0xFC; // Инициализация таймера 0:

TL0 = 0x67; // настройка на частоту работы 1000 Гц (чуть больше)

TCON = 0x10; // Включение таймера 0

}

///////////////////////////////////////////////////////////////////////////

// Чтение милисекундного счетчика

///////////////////////////////////////////////////////////////////////////

unsigned long GetMsCounter( void )

{

unsigned long res;

ET0 = 0;

res = __systime;

ET0 = 1;

}

return res;

///////////////////////////////////////////////////////////////////////////

// Возвращает прошедшее время (от момента замера)

///////////////////////////////////////////////////////////////////////////

unsigned long DTimeMs( unsigned long t2 )

{

unsigned long t1 = ( unsigned long )GetMsCounter();

}

return t1 - t2;

///////////////////////////////////////////////////////////////////////////

// Задержка в милисекундах

///////////////////////////////////////////////////////////////////////////

void DelayMs( unsigned long ms )

{

unsigned long t1 = ( unsigned long )GetMsCounter();

}

while ( 1 )

{

if ( DTimeMs( t1 ) > ms ) break;

}

252

//////////////////////// T0_ISR //////////////////////////////

// Обработчик прерывания от таймера 0.

//////////////////////////////////////////////////////////////

void T0_ISR( void ) __interrupt ( 1 )

{

// Время в милисекундах

__systime++;

}

TH0 = 0xFC;

TL0 = 0x67;

// Инициализация таймера 0:

// настройка на частоту работы 1000 Гц (чуть больше)

//////////////////////// SetVector //////////////////////////

// Функция, устанавливающая вектор прерывания в пользовательской таблице

// прерываний.

// Вход: Vector - адрес обработчика прерывания,

// Address - вектор пользовательской таблицы прерываний.

// Выход: нет.

// Результат: нет.

//////////////////////////////////////////////////////////////

void SetVector(unsigned char xdata * Address, void * Vector)

{

unsigned char xdata * TmpVector; // Временная переменная

// Первым байтом по указанному адресу записывается

// код команды передачи управления ljmp, равный 02h

*Address = 0x02;

// Далее записывается адрес перехода Vector

TmpVector = (unsigned char xdata *) (Address + 1);

*TmpVector = (unsigned char) ((unsigned short)Vector >> 8);

++TmpVector;

*TmpVector = (unsigned char) Vector;

// Таким образом, по адресу Address теперь

// располагается инструкция ljmp Vector

}

void main( void )

{

unsigned char light = 1;

InitSystimer0();

// Установка вектора в пользовательской таблице

SetVector( 0x200B, (void *)T0_ISR );

// Разрешение прерываний от таймера 0

ET0 = 1; EA = 1;

}

{

}

while( 1 )

leds( light );

if( light == 0xFF ) light = 1;

else light |= light << 1;

DelayMs( 300 );

253

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]