
- •1 Микроконтроллеры avr. Назначение и внутренняя структура
- •1.1 Структура микроконтроллеров avr
- •1.2 Периферийные устройства микроконтроллеров avr
- •1.2.1 Порты ввода/вывода (I/o)
- •1.2.2 Прерывания (interrupts)
- •1.2.3 Таймеры/счетчики (timer/counters)
- •1.2.4 Сторожевой таймер (wdt)
- •1.2.5 Аналоговый компаратор (ac)
- •1.2.6 Аналого-цифровой преобразователь (a/d converter)
- •1.2.8 Последовательный периферийный интерфейс spi
- •1.2.9Двухпроводной последовательный интерфейс twi
- •1.2.10 Тактовый генератор
- •1.2.11 Сброс при снижении напряжения питания (bod)
- •2 Описание aTtiny2313
- •3 Способы генерации аналоговых сигналов
- •3.1 Генерация аналоговых сигналов с помощью шим
- •3.2 Генерация аналоговых сигналов с помощью r2r матрицы
- •4 Разработка программ генерации синусоидального напряжения
- •4.1 Хранение значений синусоиды в памяти программ
3.2 Генерация аналоговых сигналов с помощью r2r матрицы
Если к цифро-аналоговому преобразователю не предъявляются серьёзные требования, то его можно сделать самостоятельно из обычных резисторов. Называется такой ЦАП – R-2R. Своё название он получил из-за номиналов применяемых в нём резисторов с сопротивлениями R и 2*R. Сопротивления по идее могут быть любыми, но в разумных пределах. Если поставить очень большие сопротивления, например, по несколько мегаом, то нагрузка которая подключена к выходу, внесет существенные искажения в сигнал. Напряжение начнёт проседать. В курсовой работе используются резисторы, сопротивление которых 1Ком и 2Ком.
Рисунок 4 – ЦАП R-2R
Если есть много резисторов одного сопротивления, то получить сопротивление вдвое меньшее, можно просто включив параллельно два одинаковых резистора. Для такого ЦАП желательно использовать резисторы с 1%-м допуском.
Каждый вход ЦАП имеет свой «вес». Входы расположены в порядке уменьшения веса слева направо. Левый вход оказывает самое большое влияние на выходной сигнал, следующий за ним вдвое меньше и так далее. Ну а самый последний (правый) вход изменяет выходной сигнал на ничтожные милливольты. Если известна комбинация бит, поступающая на вход ЦАП, то рассчитать напряжение очень легко. Предположим, что на входе у нас число 10010101 тогда выходное напряжение можно рассчитать по формуле:
Согласно формуле, напряжение на выходе будет равно 2.91 вольта. Uпит – напряжение питания микроконтроллера. При расчете использовалось значение 5 вольт. Таким образом, восьмибитный ЦАП способен выдать 256 различных напряжений с шагом около 20 милливольт, что вполне неплохо.
К преимуществам таких ЦАП можно отнести:
возможность увеличения разрядности;
неплохая частота дискретизации;
схемотехническая простота и повторяемость.
Недостатки:
качество ЦАП сильно зависит от применяемых резисторов;
сопротивление ключей порта микроконтроллера вносят искажения;
громоздкость на плате
4 Разработка программ генерации синусоидального напряжения
4.1 Хранение значений синусоиды в памяти программ
Микроконтроллеры AVR имеют отдельную память данных и отдельную память программ.
Память программ (Flash ROM или Flash ПЗУ) предназначена для хранения последовательности команд, управляющих функционированием микроконтроллера, и имеет 16-ти битную организацию. Все AVR имеют Flash-память программ, которая может быть различного размера - от 1 до 256 КБайт. Ее главное достоинство в том, что она построена на принципе электрической перепрограммируемости, т. е. допускает многократное стирание и запись информации. Программа заносится во Flash-память AVR как с помощью обычного программатора, так и с помощью SPI-интерфейса, в том числе непосредственно на собранной плате. Возможностью внутрисхемного программирования (функция ISP) через коммуникационный интерфейс SPI обладают все микроконтроллеры AVR, кроме Tiny11 и Tiny28.
Гарантированное число циклов перезаписи Flash-памяти у микроконтроллеров AVR второго поколения составляет не менее 10 тыс. циклов при типовом значении 100 тыс. циклов. (В официальной технической документации Atmel Corp. указывается значение 10 тыс. циклов.).
Некоторые виды данных удобно хранить в памяти программ. К таким данным относятся наборы различных констант. В нашем случае в памяти программ удобно хранить набор значений синусоиды, соответствующих одному периоду. Для извлечения данных из памяти программ используется команда lpm.
;******************************************************************
;Генератор сигнала синусоидальной формы
;Хранение значений синусоиды в памяти программ
;Микроконтроллер ATtiny2313
;******************************************************************
.nolist ; Отменяем листинг всех подсоединяемых файлов
.include "tn2313def.inc" ; Присоединение файла описаний
.list ; Разрешение листинга
.def temp=r16 ; Регистр для хранения промежуточных данных
.def temp1=r17 ; Регистр для хранения текущего значения синусоиды
;-------------------------------- Начало программного кода-------------------------------
.cseg ; Выбор сегмента памяти команд
.org 0 ; Установка счетчика команд в 0
;-------------------------------- Инициализация стека---------------------------------------
ldi temp,RAMEND ; Выбор адреса вершины стека
out SPL,temp ; Запись его в регистр стека
;-------------------------------Инициализация портов вводавывода -------------------
ldi temp,0 ; Записываем ноль в регистр temp
out DDRD,temp ; Записываем этот ноль в DDRD (порт D на ввод)
out DDRA,temp ; Записываем ноль в DDRA (порт A на ввод)
ldi temp,0xFF ; Записываем число $FF в регистр temp
out PortD,temp ; Записываем temp в PortD (включаем подтяжки порта D)
out PortA,temp ; Записываем temp в PortA (включаем подтяжки порта A)
out DDRB,temp ; Записываем temp в DDRB (порт B на вывод)
; ----------------------------------- Инициализация компаратора-------------------------
ldi temp,0x80
out ACSR,temp ;Выключение компаратора
;-------------------------------------Основной цикл программы---------------------------
t1:
ldi temp,0 ; Записываем ноль в регистр temp
ldi ZH,High(Array*2) ; Запись старшего и младшего байта начального
ldi ZL,Low(Array*2) ; адреса массива в регистровую пару Z
P1:
lpm r17, Z+ ; Загрузка с постинкрементом в r17(temp1)
; содержимого ячейки, адрес которой хранится в
; регистровой паре Z
out PortB,temp1 ; Вывод текущего значения синусоиды в порт PB
cpi temp,255 ; Проверка счетчика (temp1) на равенство 255
breq t1 ; Если равно 255, то переходим на метку t1
inc Temp ; Увеличиваем счетчик на единицу
rjmp P1 ; Безусловный переход на метку P1
;----------------------------Массив значений периода синусоиды-----------------------
; Массив состоит из 256 чисел, то есть один период синусоиды строится по
; 256-ти точкам
Array:
.db 128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174,177,180,182,185,188,191,194,196,199,201,204,206,209,211,214,216,218,220,222,224,226,228,230,232,234,236,237,239,240,242,243,244,246,247,248,249,250,251,251,252,253,253,254,254,254,255,255,255
.db 255,255,255,255,254,254,253,253,252,252,251,250,249,248,247,246,245,244,242,241,240,238,236,235,233,231,229,227,225,223,221,219,217,215,212,210,208,205,203,200,197,195,192,189,187,184,181,178,175,172,169,167,164,160,157,154,151,148,145,142,139,136,133,130
.db 126,123,120,117,114,111,108,105,102,99,96,92,89,87,84,81,78,75,72,69,67,64,61,59,56,53,51,48,46,44,41,39,37,35,33,31,29,27,25,23,21,20,18,16,15,14,12,11,10,9,8,7,6,5,4,4,3,3,2,2,1,1,1,1
.db 1,1,1,2,2,2,3,3,4,5,5,6,7,8,9,10,12,13,14,16,17,19,20,22,24,26,28,30,32,34,36,38,40,42,45,47,50,52,55,57,60,62,65,68,71,74,76,79,82,85,88,91,94,97,100,103,106,109,112,116,119,122,125,128
4.2 Хранение значений синусоиды в ОЗУ. Применение косвенной адресации
Оперативное запоминающее устройство статического типа SRAM предназначено для хранения данных, получаемых в процессе работы микроконтроллера. При выключении напряжения питания микроконтроллера данные в SRAM теряются.
Адрес байта при обращении к SRAM может быть указан в коде команды с обращением к SRAM (прямая адресация) или предварительно записан в пару регистров X, Y или Z (косвенная адресация). Обращение к SRAM может выполняться с использованием адреса, хранящегося в регистреуказателе стека.
Байт для записи в SRAM поступает из регистра общего назначения. Байт, считанный из SRAM, поступает в регистр общего назначения.
В адресное пространство SRAM кроме адресов, по которым выполняется обращение к ячейкам памяти SRAM, включены 32 адреса для обращения к регистрам общего назначения (адреса от $00 до $1F) и 64 адреса для обращения к регистрам ввода-вывода (адреса от $20 до $5F).
Первой ячейке SRAM соответствует адрес $60.
Всего адресное пространство ОЗУ содержит 224 ячейки, из которых 128 ячеек составляют внутреннюю память данных.
Для всех способов адресации доступны все 32 регистра общего назначения, 64 регистра ввода—вывода и 128 байтов памяти данных SRAM микросхемы Attiny2313.
;******************************************************************
;Генератор сигнала синусоидальной формы
;Хранение значений синусоиды в ОЗУ
;Микроконтроллер ATtiny2313
;******************************************************************
.nolist ; Отменяем листинг всех подсоединяемых файлов
.include "tn2313def.inc" ; Присоединение файла описаний
.list ; Разрешение листинга
.def temp1=r16 ; Главный рабочий регистр
.def temp2=r17 ; Регистр для хранения текущего значения синусоиды
;---------------------- Резервирование ячеек памяти (SRAM)---------------------------
.dseg ; Выбираем сегмент ОЗУ
.org 0x60 ; Устанавливаем текущий адрес сегмента
buf: .byte 64 ; Резервируем 64 байта в ОЗУ под массив чисел со ;значениями четверти периода синусоиды
;-------------------------------- Начало программного кода-------------------------------
.cseg ; Выбор сегмента памяти команд
.org 0 ; Установка счетчика команд в 0
;-------------------------------- Инициализация стека---------------------------------------
ldi temp1,RAMEND ; Выбор адреса вершины стека
out SPL,temp1 ; Запись его в регистр стека
;-------------------------------Инициализация портов вводавывода -------------------
ldi temp1,0 ; Записываем ноль в регистр temp
out DDRD,temp1 ; Записываем этот ноль в DDRD (порт D на ввод)
out DDRA,temp1 ; Записываем ноль в DDRA (порт A на ввод)
ldi temp1,0xFF ; Записываем число $FF в регистр temp
out PortD,temp1 ; Записываем temp в PortD (включаем подтяжки порта D)
out PortA,temp1 ; Записываем temp в PortA (включаем подтяжки порта A)
out DDRB,temp1 ; Записываем temp в DDRB (порт B на вывод)
; ----------------------------------- Инициализация компаратора-------------------------
ldi temp1,0x80
out ACSR,temp1 ;Выключение компаратора
;-------------------------------------Основной цикл программы---------------------------
ldi XH, high(buf) ; В регистровую пару X записываем адрес
ldi XL, low(buf) ; начала буфера ОЗУ
ldi ZH, high(mas*2) ; В регистровую пару Z записываем старший и
ldi ZL,low(mas*2) ; младший байт начального адреса массива
ldi temp1,0 ; Записываем ноль в temp1, регистр будет
; работать как счетчик
;-------------------------------------Косвенная запись в память---------------------------
nn:
lpm temp2,Z+ ; Загрузка с постинкрементом в r17(temp1)
; содержимого ячейки, адрес которой хранится
; в регистровой паре Z
st X+,temp2 ;Совершаем запись содержимого регистра
; temp2 в ОЗУ по адресу, который хранится
; в регистровой паре X
inc temp1 ; Увеличиваем значение счетчика на единицу
cpi temp1,64 ; Проверка счетчика на равенство 64
brne nn ; Если не равно 64, то переходим на метку nn,
; если равно 64, то есть если в ОЗУ записались
;все числа массива, то переходим на метку start
;-------------------------------------Косвенное чтение из памяти-------------------------
start:
ldi XH, high(buf) ; В регистровую пару X записываем адрес
ldi XL, low(buf) ; начала буфера ОЗУ
;-------------------------------- Первая четверть синусоиды------------------------------
nn1:
ld temp2, X+ ; Чтение байта из ячейки ОЗУ, адрес которой
; хранится в регистровой паре X и запись
; прочитанного байта в регистр temp2. Затем
; содержание регистровой пары X увеличивается
; на единицу
out PortB,temp2 ;Вывод текущего значения синусоиды в порт РВ
dec temp1 ; Уменьшаем значение счетчика на единицу
cpi temp1,0 ; Сравниваем с нулем
brne nn1 ; Если не равно нулю, то переходим на метку nn1,
; если равно нулю, то есть если из ОЗУ были
; прочитаны и отправлены на порт B все 64 числа, то
; переходим на метку nn2
;-------------------------------- Вторая четверть синусоиды------------------------------
nn2:
ld temp2, -X ; Чтение байта из ячейки ОЗУ, адрес которой
; хранится в регистровой паре X и запись
; прочитанного байта в регистр temp2. Затем
; содержание регистровой пары X уменьшается
; на единицу
out PortB,temp2 ; Вывод текущего значения синусоиды в порт РВ
inc temp1 ; Увеличиваем значение счетчика на единицу
cpi temp1,64 ; Сравниваем с 64
brne nn2 ; Если не равно 64, то переходим на метку nn2,
; если равно 64, то есть если из ОЗУ были
; прочитаны и отправлены на порт B все 64 числа,
; начиная с последнего числа массива, записанного в
; ОЗУ и заканчивая первым, то
; переходим на метку nn3
; -------------------------------- Третья четверть синусоиды------------------------------
nn3:
ld temp2, X+ ; Чтение байта из ячейки ОЗУ, адрес которой
; хранится в регистровой паре X и запись
; прочитанного байта в регистр temp2. Затем
; содержание регистровой пары X увеличивается
; на единицу
com temp2 ;Выполняем побитную инверсию регистра temp2 для
; получения отрицательной полуволны синусоиды
out PortB,temp2 ; Вывод текущего значения регистра temp2 в порт РВ
dec temp1 ; Уменьшаем значение счетчика на единицу
cpi temp1,0 ; Сравниваем с нулем
brne nn3 ; Если не равно нулю, то переходим на метку nn3,
; если равно нулю, то есть если из ОЗУ были
; прочитаны и отправлены на порт B все 64
; числа, начиная с начального адреса буфера ОЗУ, то
; переходим на метку nn4
;----------------------------- Четвертая четверть синусоиды------------------------------
nn4:
ld temp2, -X ; Чтение байта из ячейки ОЗУ, адрес которой
; хранится в регистровой паре X и запись
; прочитанного байта в регистр temp2. Затем
; содержание регистровой пары X уменьшается
; на единицу
com temp2 ; Выполняем побитную инверсию регистра temp2 для
; получения отрицательной полуволны синусоиды
out PortB,temp2 ; Вывод текущего значения регистра temp2 в порт РВ
inc temp1 ; Увеличиваем значение счетчика на единицу
cpi temp1,64 ; Сравниваем с 64
brne nn4 ; Если не равно 64, то переходим на метку nn4,
; если равно 64, то есть если из ОЗУ были
; прочитаны и отправлены на порт B все 64 числа,
; начиная с последнего числа массива, записанного в
; ОЗУ и заканчивая первым, то выполняется
; переход на метку start
rjmp start
;----------------------- -Массив значений четверти синусоиды-------------------------
; Массив состоит из 64 чисел, то есть одна четверть синусоиды строится по
; 64-ём точкам
mas:
.db 128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174,177,180,182,185,188,191,194,196,199,201,204,206,209,211,214,216,218,220,222,224,226,228,230,232,234,236,237,239,240,242,243,244,246,247,248,249,250,251,251,252,253,253,254,254,254,255,255,255
4.3 Хранение значений синусоиды в энергонезависимой памяти (EEPROM)
Постоянное запоминающее устройство EEPROM предназначено для хранения данных, записанных при программировании микроконтроллера и получаемых в процессе выполнения программы. При выключении напряжения питания данные сохраняются. Ячейка памяти содержит 8 разрядов. Емкость EEPROM микросхемы ATtiny2313 составляет 128 байт.
EEPROM имеет обособленное адресное пространство. При обращении к EEPROM адрес записывается в регистр адреса EEAR. Байт, предназначенный для записи, заносится в регистр данных EEDR. Байт, полученный при чтении, поступает в этот же регистр. Для управления процедурами записи и чтения используется регистр управления EECR.
Для записи байта в EEPROM необходимо:
записать адрес в регистр адреса;
записать байт в регистр данных;
установить в единичное состояние разряд EEMWE регистра EECR
при EEMWE=1 установить в единичное состояние разряд EEWE регистра EECR
Процедура записи выполняется в зависимости от величины напряжения питания за 2,5 – 4 мс. При завершении записи разряд EEWE регистра EECR аппаратно сбрасывается в нулевое состояние.
Разряд EEMWE сохраняет единичное состояние в течение 4-ех тактов после установки и аппаратно сбрасывается в нулевое состояние.
Для чтения байта из EEPROM необходимо:
записать адрес в регистр адреса;
установить в единичное состояние разряд EERE регистра EECR.
Считанный байт поступает в регистр данных. Разряд EERE регистра EECR аппаратно сбрасывается в нулевое состояние.
;******************************************************************
;Генератор сигнала синусоидальной формы
;Хранение значений синусоиды в энергонезависимой памяти (EEPROM)
;Микроконтроллер ATtiny2313
;******************************************************************
.nolist ; Отменяем листинг всех подсоединяемых файлов
.include "tn2313def.inc" ; Присоединение файла описаний
.list ; Разрешение листинга.def data=r17
.def addres=r18 ; Указатель адреса в EEPROM
.def count=r19 ; Регистр передачи данных
.def temp=r20 ; Главный рабочий регистр
.def data=r21 ; Регистр передачи данных
;---------------------- Резервирование ячеек памяти (EEPROM)-----------------------
.eseg ; Выбираем сегмент EEPROM
.org 0x08 ; Устанавливаем текущий адрес сегмента
bufr: .byte 64 ; Буфер для хранения массива
;-------------------------------- Начало программного кода-------------------------------
.cseg ; Выбор сегмента памяти команд
.org 0 ; Установка счетчика команд в 0
;-------------------------------- Инициализация стека---------------------------------------
ldi temp,RAMEND ; Выбор адреса вершины стека
out SPL,temp ; Запись его в регистр стека
;-------------------------------Инициализация портов вводавывода -------------------
ldi temp,0 ; Записываем ноль в регистр temp
out DDRD,temp ; Записываем этот ноль в DDRD (порт D на ввод)
out DDRA,temp ; Записываем ноль в DDRA (порт A на ввод)
ldi temp,0xFF ; Записываем число $FF в регистр temp
out PortD,temp ; Записываем temp в PortD (включаем подтяжки порта D)
out PortA,temp ; Записываем temp в PortA (включаем подтяжки порта A)
out DDRB,temp ; Записываем temp в DDRB (порт B на вывод)
; ----------------------------------- Инициализация компаратора-------------------------
ldi temp,0x80
out ACSR,temp ;Выключение компаратора
; ----------------------------------- Проверка записи в EEPROM--------------------------
; Поскольку память EEPROM предназначена для долговременного хранения
; данных, то мы можем записать в неё массив один раз, а затем проверять,
;записан ли массив при повторном запуске программы. Если окажется, что
;массив не записан, то выполнится переход в цикл записи массива, если
;записан, то сразу в цикл чтения
ldi addres,0x08 ; Записываем в регистр addres начало сегмента EEPROM
mm:
cli ; Запрещаем все прерывания
sbic EECR,EEWE ;Проверяем готовность EEPROM
rjmp mm ;Если не готов, то ждем (переходим на метку mm)
out EEAR,addres ;Записываем адрес в регистр адреса
sbi EECR,EERE ;Устанавливаем бит разрешения чтения
in data,EEDR ; Помещаем прочитанный байт в регистр data
cpi data,128 ; Сравниваем с 128
breq start ; Если равно, т.е если массив уже записан в EEPROM,
; то переходим на метку start, если не равно, то
;переходим на метку Write
; ----------------------------------- Запись массива в EEPROM--------------------------
Write:
ldi addres,bufr ; Записываем в регистр addres начало сегмента EEPROM
ldi ZH,high(mas*2) ; В регистровую пару Z записываем старший и
ldi ZL,low(mas*2) ; младший байт начального адреса массива
m8:
lpm data,Z+ ; Загрузка с постинкрементом в r17(temp1)
; содержимого ячейки, адрес которой хранится
; в регистровой паре Z
nn1:
cli ;Запрещаем все прерывания
sbic EECR,EEWE ;Проверяем готовность EEPROM
rjmp nn1 ;Если не готов, то ждем
out EEAR,addres ;Записываем адрес в регистр адреса
out EEDR, data ;Записываем данные в регистр данных
sbi EECR,EEMWE ;Устанавливаем бит разрешения записи
sbi EECR,EEWE ;Устанавливаем бит записи
inc addres ;Увеличиваем адрес в EEPROM
inc count ; Увеличиваем значение счетчика на единицу
cpi count,64 ; Сравниваем с 64
brne m8 ; Если не равно, то переходим на метку m8, если
; равно, то есть если в EEPROM записались все 64
;числа массива, то переходим на метку start
; --------------------------------------- Чтение из EEPROM---------------------------------
start:
ldi count,0 ; Обнуляем счетчика
ldi addres,bufr ; Записываем в регистр addres начало сегмента EEPROM
;-------------------------------- Первая четверть синусоиды------------------------------
m1:
cli ;Запрещаем все прерывания
sbic EECR,EEWE; Проверяем готовность EEPROM
rjmp m1 ; Если не готов, то ждем (переходим на метку m1)
out EEAR,addres ; Записываем адрес в регистр адреса
sbi EECR,EERE ; Устанавливаем бит разрешения чтения
in data,EEDR ; Помещаем прочитанный байт в регистр data
inc addres ; Увеличиваем адрес в EEPROM на единицу
nop ; Нет операции
out PortB,data ; Вывод текущего значения синусоиды в порт PB
inc count ; Увеличиваем значение счетчика на единицу
cpi count,64 ; Сравниваем с 64
brne m1 ; Если не равно 64, то переходим на метку m1, если
; равно 64, то есть если из EEPROM были прочитаны
; и отправлены на порт B все 64 числа начиная с
; первого числа массива, записанного в EEPROM и
; заканчивая последним, то переходим на метку m2
;-------------------------------- Вторая четверть синусоиды------------------------------
m2:
cli ; Запрещаем все прерывания
sbic EECR,EEWE; Проверяем готовность EEPROM
rjmp m2 ; Если не готов, то ждем (переходим на метку m2)
out EEAR,addres; Записываем адрес в регистр адреса
sbi EECR,EERE ; Устанавливаем бит разрешения чтения
in data,EEDR ; Помещаем прочитанный байт в регистр data
dec addres ; Уменьшаем адрес в EEPROM на единицу
nop ; Нет операции
out PortB,data ; Вывод текущего значения синусоиды в порт PB
dec count ; Уменьшаем значение счетчика на единицу
cpi count,0 ; Сравниваем с 0
brne m2 ; Если не равно нулю, то переходим на метку m2,
; если равно нулю, то есть если из EEPROM были
; прочитаны и отправлены на порт B все 64 числа,
; (чтение массива с конца), то переходим на метку m3
;-------------------------------- Третья четверть синусоиды------------------------------
m3:
cli ; Запрещаем все прерывания
sbic EECR,EEWE; Проверяем готовность EEPROM
rjmp m3 ; Если не готов, то ждем (переходим на метку m3)
out EEAR,addres ; Записываем адрес в регистр адреса
sbi EECR,EERE ; Устанавливаем бит разрешения чтения
in data,EEDR ; Помещаем прочитанный байт в регистр data
inc addres ; Увеличиваем адрес в EEPROM на единицу
com data ; Выполняем побитную инверсию регистра data для
; получения отрицательной полуволны синусоиды
out PortB,data ; Вывод текущего значения регистра data в порт PB
inc count ; Увеличиваем значение счетчика на единицу
cpi count,64 ; Сравниваем с 64
brne m3 ; Если не равно 64, то переходим на метку m3, если
; равно 64, то есть если из EEPROM были прочитаны,
; инвертированы и отправлены на порт B все 64 числа
; начиная с первого числа массива, записанного в
; EEPROM и заканчивая последним, то переходим на
; метку m4
; ----------------------------- Четвертая четверть синусоиды-----------------------------
m4:
cli ; Запрещаем все прерывания
sbic EECR,EEWE ; Проверяем готовность EEPROM
rjmp m4 ; Если не готов, то ждем (переходим на метку m4)
out EEAR,addres ; Записываем адрес в регистр адреса
sbi EECR,EERE ; Устанавливаем бит разрешения чтения
in data,EEDR ; Помещаем прочитанный байт в регистр data
dec addres ; Уменьшаем адрес в EEPROM на единицу
com data ; Выполняем побитную инверсию регистра data для
; получения отрицательной полуволны синусоиды
out PortB,data ; Вывод текущего значения регистра data в порт PB
dec count ; Уменьшаем значение счетчика на единицу
cpi count,0 ; Сравниваем с 0
brne m4 ; Если не равно нулю, то переходим на метку m4,
; если равно нулю, то есть если из EEPROM были
; прочитаны, инвертированы и отправлены на порт B
; все 64 числа (чтение массива с конца), то переходим
; на метку start
rjmp start
;------------------------ Массив значений четверти синусоиды-------------------------
; Массив состоит из 64 чисел, то есть одна четверть синусоиды строится по
; 64-ём точкам
mas:
.db 128,131,134,137,140,144,147,150,153,156,159,162,165,168,171,174,177,180,182,185,188,191,194,196,199,201,204,206,209,211,214,216,218,220,222,224,226,228,230,232,234,236,237,239,240,242,243,244,246,247,248,249,250,251,251,252,253,253,254,254,254,255,255,255
Заключение
В результате курсового проектирования были созданы три рабочие программы генератора сигнала синусоидальной формы с использованием различных видов памяти микроконтроллера ATtiny2313.
Библиографический список
Евстифеев А. В. Микроконтроллеры AVR семейств Tiny и Mega фирмы «ATMEL». М.: Издательский дом «Додэка-XXI», 2004. 560 с.
Гребнев В. В. Микроконтроллеры семейства AVR фирмы Atmel. М.: ИП РадоиСофт, 2002. 176 с.
Белов А. В. Микроконтроллеры AVR в радиолюбительской практике. СПб.: Наука и Техника, 2007. 352 с.
Голубцов М. С. Микроконтроллеры AVR: от простого к сложному. М.: СОЛОН-Пресс, 2003. 288 с.