Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лабораторная работа № 4.doc
Скачиваний:
6
Добавлен:
01.04.2025
Размер:
97 Кб
Скачать
☆

Asm(код: список_выходных_операндов, список_входных_операндов)

Пример 4.3. Ассемблерная вставка.

asm(“in %0, %1” : “=r” (value) : “I” (_SFR_IO_ADDR(PORTD)));

В этой ассемблерной вставке описаны:

  1. ассемблерная команда “in %0, %1”;

  2. список выходных операндов “=r” (value);

  3. список входных операндов “I” (_SFR_IO_ADDR(PORTD)).

Вторая и третья части оператора asm предназначены для определения связи между регистрами микроконтроллера и операндами C. В самих ассемблерных инструкциях ссылки на операнды создаются с помощью символа “%” и порядкового номера операнда (начиная с нуля). В примере 5.1 ссылке %0 соответствует входной операнд “=r” (value), а ссылке %1 – выходной операнд “I” (_SFR_IO_ADDR(PORTD)). В результате может быть получена инструкция in r24, 12. Если ассемблерные инструкции не используют операндов, то соответствующие части оператора asm могут быть опущены, например, asm (“cli”::). Во избежание исключения ассемблерной вставки в результате оптимизационной стратегии компилятора, к оператору asm следует добавить атрибут volatile, например:

asm volatile (“in %0, %1” : “=r” (value) : “I” (_SFR_IO_ADDR(PORTD)));

Заголовочные файлы для программ в WinAVR находятся в папках:

  • \WinAVR\avr\include\,

  • \WinAVR\avr\include\avr\,

  • \WinAVR\avr\include\compat\,

  • \WinAVR\avr\include\util\.

В папке \WinAVR\avr\include\avr\ содержатся заголовочные файлы с определениями, специфичными для микроконтроллеров AVR. Например, там есть набор файлов, определяющих адреса портов, биты управляющих регистров и другие элементы конкретных микроконтроллеров. В примере 4.4 показан фрагмент заголовочного файла io2313.h, который облегчает работу с микроконтроллером AT90S2313.

Пример 4.4. Фрагмент файла определения микроконтроллера.

/* I/O registers */

/* Analog Comparator Control and Status Register */

#define ACSR _SFR_IO8(0x08)

/* UART Baud Rate Register */

#define UBRR _SFR_IO8(0x09)

/* UART Control Register */

#define UCR _SFR_IO8(0x0A)

/* UART Status Register */

#define USR _SFR_IO8(0x0B)

/* UART I/O Data Register */

#define UDR _SFR_IO8(0x0C)

Использование таких файлов позволяет при обращении к регистрам микроконтроллера в программе на языке C WinAVR использовать их мнемонические обозначения, например, DDRB или TCCR1A.

В примере 4.5 приведена программа, с помощью которой организуется ежесекундное мигание индикатора. При ее написании предполагается, что светодиодный индикатор подключен к выводу 0 порта B. Мигание индикатора задается с помощью прерывания при переполнении таймера, например таймера/счетчика Timer/Counter1. С помощью разрядов CS10 – CS12 регистра TCCR1B устанавливается коэффициент деления частоты системной синхронизации для тактирования таймера, например, коэффициент 1024 соответствует значению 5 в разрядах CS10 – CS12. Таким образом, в случае рабочей частоты микроконтроллера 4 МГц значение счетного регистра TCNT1 будет увеличиваться через каждые 1024/4000000 = 0.000256 с. Следовательно необходимо установить такое стартовое значение счетчика, чтобы до его переполнения отсчитывалось 1/0.000256 = 3906 импульсов. Поскольку с помощью 16 разрядов счетчика можно получить максимальное значение 65535, то он должен инициализироваться величиной

65536 – 3906 = 61630.

Реализация рассмотренного алгоритма приведена в примере 5.4.

Пример 4.5. Программа мигающего индикатора.

#include <avr/io.h>

#include <avr/interrupt.h>

#include <avr/signal.h>

#define Freq 4000000

INTERRUPT(SIG_OVERFLOW1)

{

TCNT1 = 0x10000 - (Freq / 1024);

PORTB ^= 0x01;

}

int main (void)

{

DDRB = 0x01;

TCCR1A = 0;

TCCR1B = 5;

TCNT1 = 0x10000 - (Freq / 1024);

TIFR = 0;

TIMSK = 0x04;

GIMSK = 0;

sei();

while(1) ;

}