Для розгалуження програми підтримуються інструкції умовних і безумовних переходів і викликів процедур, що дозволяють безпосередньо адресуватися в межах адресного простору. Більшість інструкцій являють собою одне 16-розрядне слово. Кожна адреса пам'яті програм містить 16- або 32-розрядну інструкцію. Пам'ять програм розділена на два сектори: сектор програми початкового завантаження і сектор прикладної програми. Обидва сектори мають роздільні біти захисту від запису і читання/запису.
Оскільки всі AVR-інструкції є 16 або 32-розрядними, флеш-пам'ять організована як 1 кбайт х 16. Програмний лічильник РС у МК є 16-розрядним, тому дозволяє адресувати до 64 кбайт пам'яті програм.
Flash-пам'ять програм.
ATmega8 містить 8 кб пам’яті для завантаження програм. Команда контроллера займає 16 або 32 біта, тому флеш-память програм організована у вигляді масиву 4К 16-ти бітових слів. Флеш-память розділена на дві секції - область додатків і область завантаження (що знаходиться в старших адресах). Флеш-память витримує до 10.000 циклів перезапису.
EEPROM пам'ять даних
ATmega8 містить постійний запам'ятовуючий пристрій для збереження даних, виконаний за технологією EEPROM, який містить 512 байт і забезпечує 100000 циклів стирання/запис.
Оперативний запам'ятовуючий пристрій статичного типу для збереження даних (SRAM), який містить 1 Кбайт вбудованої пам’яті.
Доступ до статичного ОЗП даних може бути легко здійснений через 5 різних режимів адресації архітектури AVR і виконується за два машинних цикли.
При генерації переривання і виклику підпрограм адреса повернення з програмного лічильника записується в стек. Стек ефективно розподілений у статичному ОЗП пам'яті даних і, отже, розмір стека обмежений загальним розміром статичного ОЗП і використовуваним його обсягом. У будь-якій програмі відразу після скидання повинна бути виконана ініціалізація покажчика стека (SP) (тобто перед виконанням процедур обробки переривань або викликом підпрограм). Покажчик стека - SP - доступний для читання і запису у просторі введення-виведення. На рис. 3.3 показано організацію пам’яті в мікроконтролері ATmega8.
Простір пам'яті введення - виведення містить 32 адреси з безпосередньою адресацією або може адресуватися як пам'ять даних.
Рис. 3.3 – Структура пам’яті
3.3 Розробка програмного забезпечення
Функціонування дозиметра керуються програмно за допомогою мікроконтролера.Програма написана на мові програмування С++ [3].
Текст програми пристрою має вигляд:
//------------------- підготовка--------------------//
//------------------- включення директив препроцесора ---------------------//
#include <istream.h>
#include <mega8.h>
#include <delay.h>
//-------------------- встановлення портів-----------------//
#define key1 PIND.0
#define key2 PIND.1
#define key3 PIND.2
#define key4 PIND.3
#define pulse PIND.4
#define beep PORTC.3//--- визначення імпульсів від датчика---//
#define light PORTC.2
#define sound PORTC.1
eeprom unsigned int zone1;
eeprom unsigned int zone2;
unsigned int k=0;
int sec=0;
int rf=0;
int j=0;
int i=1; //кнопки< >
int m_buffer=0;
int memory=1; // виділення пам’яті для зони 1
intmemory1=2; // виділення пам’яті для зони 2
intwarn=400; // стандартний рівень радіації
bitok=0; // так
bit x=0; // ні
bit a1=0;
bit a2=0;
bit a3=0;
bit a4=0;
char lcd_buffer[80]; // буфер рівня LCD!
//-------------------------- Переривання для таймера ------------------//
interrupt [TIM1_COMPA] void timer1_comp_isr(void)
{
sec++;
}
/*
void wait (void){
TCNT1=0;
while (TCNT1<780){};
}
*/
//---------------- Буквено-цифрові функції Модуля LCD----------------//
#asm
.equ __lcd_port=0x18 ;PORTB
#endasm
#include <lcd.h>// Оголосіть свої глобальні змінні тут
//----------------------Звуковий сигнал --------------------//
voidmy_beep(void) { // ключовий звуковий сигнал
beep = 0;
delay_ms(30);
beep = 1;} // Короткий звуковий сигнал
//----------------- Довгий звуковий сигнал ---------------------//
voidlong_beep(void) { // Ключовий звуковий сигнал
beep = 0;
delay_ms(55);
beep = 1;
delay_ms(30);
beep = 0;
delay_ms(30);
beep = 1;}
//------------------------ Ключі функцій -----------------------//
void my_keys(void){
if(!key1){ok=1;}else{delay_ms(10); ok=0;}
if(!key2){x=1;}else{delay_ms(10); x=0;}
if(i<8){if(!key4){i++; my_beep(); lcd_clear(); delay_ms(680); }}
if(i>1){if(!key3){i--; my_beep(); lcd_clear(); delay_ms(680); }}
}
//---------------------------- Головна програма ----------------------------//
voidmain(void)
{
PORTB=0x00;
DDRB=0x00;
PORTC=0x7F;
DDRC=0x7F;
PORTC.2=0;
PORTC.4=0;
PORTC.5=0;
PORTD=0xFF;
DDRD=0x00;
ACSR=0x80;
SFIOR=0x00;
//----------------------------- Для таймера ----------------------------//
OCR1A=4000; // Для кварца
TCCR1B=0x0D;
TIMSK=0x10;
lcd_init(16);
my_beep(); // Початок
delay_ms(100);
my_beep();
while (1) {
my_keys();
switch (i) {
case 1: // Запуск меню
my_keys();
lcd_gotoxy(0,0); lcd_putsf(“Menu _rogram”);
lcd_gotoxy(0,1); lcd_putsf(“Enter key~ “);
delay_ms(1);
if(sec>=60){#asm(“cli”); m_buffer=k; } //anti kosac
break; //STOP1
case 2: // Тест датчика
my_keys();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”fon=%4umkr Time=%2uc” “RF=%2u “,k,sec,rf);// PRINT ON LCD
lcd_puts(lcd_buffer); // З буфера на LCD
delay_ms(1); // потрібно обслуговувати таймери
if((ok)&(a1)){delay_ms(50); #asm(“sei”);} //Start k=0; j=0; rf=0;
if(x){#asm(“cli”); beep=1;} //Зупинка
if(sec>=60){#asm(“cli”); a1=0;m_buffer=k; } // Авто зупинка
if(sec==61){sec=0; k=0; j=0; rf=0; beep=1;} // повторний запуск
if(ok){a1=1;}
if(x){a1=0;}
if((!pulse)&(a1)){delay_ms(10); k++; j++;} // Введіть допустиме значення радіації
if(j==20){delay_us(1); rf++; j=0;}
if(k==warn){delay_us(1); beep=0;} // Небезпечне випромінювання
if(k==1600){delay_us(1); sec=0; k=0; j=0; rf=0; beep=1;} //Допустиме випромінювання
break;
case 3: // Зберігання значення в пам’яті EEPROM в зоні 1
my_keys();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”Zone1=%4umkr “,memory);// TO LCD
lcd_puts(lcd_buffer);
lcd_gotoxy(0,1); lcd_putsf(“Save Load”);
delay_ms(1);
if(sec>=60){#asm(“cli”); m_buffer=k; }
if((ok)&(k>=10)){ zone1=m_buffer;} // Збережіть лише значення >10
if(x){ memory=zone1;}
break;
case 4: // Зберігання значення в пам’яті EEPROM в зоні 2
my_keys();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”Zone2=%4umkr “,memory1);
lcd_puts(lcd_buffer);
lcd_gotoxy(0,1); lcd_putsf(“Save Load”);
delay_ms(1); // need wait on timers
if(sec>=60){#asm(“cli”); m_buffer=k; } // Збережіть лише значення >10
if((ok)&(k>=10)){ zone2=k;}
if(x){ memory1=zone2;}
break;
case 5: // Вмикання/вимикання сигнальної лампочки
my_keys();
lcd_gotoxy(0,0); lcd_putsf(“Backlight “);
lcd_gotoxy(0,1); lcd_putsf(“v on/off x”);
if(ok){a2=1; PORTC.4=1;}
if(x){a2=0; PORTC.4=0;}
delay_ms(1);
if(sec>=60){#asm(“cli”); m_buffer=k; }
if(a2){ lcd_gotoxy(11,0); lcd_putsf(“on “); }
if(!a2){ lcd_gotoxy(11,0); lcd_putsf(“off “);}
break;
case 6: // Вмикання/вимикання звукового резонатора
my_keys();
lcd_gotoxy(0,0); lcd_putsf(“Sound “);
lcd_gotoxy(0,1); lcd_putsf(“v on/off x”);
if(ok){a3=1; PORTC.5=1;}
if(x){a3=0; PORTC.5=0;}
delay_ms(1);
if(sec>=60){#asm(“cli”); m_buffer=k; }
if(a3){ lcd_gotoxy(11,0); lcd_putsf(“on “); }
if(!a3){ lcd_gotoxy(11,0); lcd_putsf(“off “);}
break;
case 7: // Попереджувальний рівень +/-
my_keys();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”Warning=%4umkr “,warn);
lcd_puts(lcd_buffer);
lcd_gotoxy(0,1); lcd_putsf(“v +/- x”);
//delay_ms(1); // need wait on timers
if(sec>=60){#asm(“cli”); m_buffer=k; }
if(warn<1500){if(!key1){warn++; delay_ms(80); }}
if(warn>10){if(!key2){warn--;delay_ms(80); }}
break;
case 8: // Вмикання режиму безперервного вимірювання
my_keys();
lcd_gotoxy(0,0);
sprintf(lcd_buffer,”Fon=%4umkr Bufer=%4u” “RF=%2u “,k,m_buffer=k,rf);// Вивід значення на LCD
lcd_puts(lcd_buffer);
//lcd_gotoxy(0,1); lcd_putsf(“While”);
delay_ms(1); // need wait on timers
if((ok)&(a4)){delay_ms(50); #asm(“sei”);} //Start k=0; j=0; rf=0;
if(x){#asm(“cli”); beep=1;} // Зупинка
if(sec==61){ sec=0; k=0; j=0; rf=0; beep=1;m_buffer=k;}
if(ok){a4=1;}
if(x){a4=0;}
if((!pulse)&(a4)){delay_ms(10); k++; j++;}
if(j==20){delay_us(1); rf++; j=0;}
if(k==warn){delay_us(1); beep=0;} // Сигнальне вимірювання
if(k==1600){delay_us(1); sec=0; k=0; j=0; rf=0; beep=1;} //максимальне значення вимірювання
break;
}
};
4.МОДЕЛЮВАННЯ РОБОТИ
Моделювання проводилось за допомогою програми Proteus 7 Professional [4]. Так як за відсутністю програмних еквівалентів і електронних компонентів доцільно виконати моделювання роботи, яке полягає в виводі на дисплей значення вимірювання радіації, світлової та звукової індикації випромінювання, не вдалось. Замість блокинг генератора на вхід одновібратора подається прямокутній сигнал і спостерігаємо на дисплеї (Рис. 4.1) .
Рисунок 4.1 – Результати моделювання
5. ВИСНОВКИ
В даній роботі було розроблено цифровий дозиметр з трьома режимами вимірювання, з візуальним і звуковим оповіщенням рівня радіації, збереження даних в енергонезалежній пам’яті, збереження на дисплеї попереднього значення, вимірювання, регулювання рівня сигналізації. Також розглянули структуру мікроконтролера ATmega8, написали програму курування мікроконтролером, промоделювали пистрій в програмі Proteus 7 Professional.
ЛІТЕРАТУРА
1 Офіціальний сайт www.vikipedia.uaМікроконтролери AVR.
2 Новиков Ю.В., Скоробогатов П.К. Основы микропроцессорной техники. Курс лекций
3 Бродин В.Б., Калинин А.В. Системы на микроконтроллерах и БИС программируемой логики. — М.: ЭКОМ, 2002.
4 Жан М. Рабаи, Ананта Чандракасан, Боривож Николич Цифровые интегральные схемы. Методология проектирования = Digital Integrated Circuits.
5 Гостев В.И. Системы управления с цифровыми регуляторами.
6 Баранов В.Н. Применение микроконтроллеров AVR. Схемы, алгоритмы, программы.
7 Трамперт. Измерение, управление и регулирование с помощью AVR микроконтроллеров_2006.
8 Угрюмов Е.П. Цифровая схемотехника. СПб.2004г.528с.ил.
ДОДАТОК А
Повна структура мікроконтролера ATmega8ДОДАТОК Б
Граф-схема алгоритму функціонування пристрою.
ДОДАТОК Г
Друкована плата пристрою.
Цифрова частина схеми
Високовольтна частина схеми
//-------------------Підготовка--------------------//
//------------------- включення директив препроцесора ---------------------//
#include <stdio.h>
#include <mega8.h>
#include <delay.h>
//-------------------- встановлення портів-----------------//
#define key1 PIND.0
#define key2 PIND.1
#define key3 PIND.2
#define key4 PIND.3
#define pulse PIND.4
#define beep PORTC.3 //--- визначення імпульсів від датчика---//