ГРАФІЧНО–РОЗРАХУНКОВА РОБОТА

Інформація про навчальний заклад

ВУЗ:
Національний університет Львівська політехніка
Інститут:
Не вказано
Факультет:
Не вказано
Кафедра:
Не вказано

Інформація про роботу

Рік:
2010
Тип роботи:
Розрахункова робота
Предмет:
Захист інформації
Група:
ІБ – 44

Частина тексту файла (без зображень, графіків і формул):

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ «ЛЬВІВСЬКА ПОЛІТЕХНІКА» кафедра захисту інформації ГРАФІЧНО–РОЗРАХУНКОВА РОБОТА з курсу "МІКРОПРОЦЕСОРНІ ПРИСТРОЇ" варіант № 27 НЗК – 0609083 Завдання: Написати та відлагодити програму для схеми, яка б здійснювала дискретизацію вхідного аналогового сигналу з діапазоном Uвх = 0-5 B з частотою FS, Гц аналого-цифровим перетворювачем MAX1241 (опорна напруга UREF = 5 В) та відображала значення напруги на рідкокристалічному дисплеї LM020L (1 рядок з 16 символами) з контролером HD44780, та передавала її зна-чення через послідовний порт в ПК зі швидкістю передачі R Бод. Тактова частота Ft МК AT90S2313 становить 7.3728 МГц. Якщо напруга виходить за межі 2.5 B ± 0.xx В (хх – останні дві цифри номера залікової книжки, якщо хх = 00 прийняти хх = 99) на дисплей виводиться повідомлення Alarm. Перевірити правильність роботи програми шляхом симуляції в середовищі Proteus 7. Варіант Частота дискретизації Fs, Гц Швидкість передачі по УАПП R, Бод  27 1.8 9600   Розрахункова частина Оскільки номер залікової книжки – 0609083, то межі напруги становлять: нижній поріг спрацювання: 1,67 В верхній поріг спрацювання: 3,33 В Якщо напруга не належить цьому відрізку необхідно вивести повідомлення Alarm. Знайдемо значення констант спрацювання за формулою: , де - напруги порогів спрацювання,  - опорна напруга на АЦП (5 Вольт),  - шукана константа.   Знайдемо подільник та поріг спрацювання таймера Т1, для того, щоб проводити опитування напруги з частотою дискретизації Fs = 0,4 Гц. Часовий інтервал генерації таймером переривання обчислюється за формулою:  Враховуючи, що при максимальному значені N = 65535, значення подільника становить DIV = 281, потрібно взяти подільник на порядок вище (DIV = 1024), тоді значення N становить:  Отже, значення порогу порівняння для таймера Т1 становить TimerVal = 4000 Знайдемо подільник частоти для UART, щоб забезпечити швидкість передачі R = 9600 бод. Швидкість визначається наступним виразом:  де  – швидкість передачі (в бодах);  – тактова частота МК, Гц; UBRR – вміст регістру контролера швидкості передачі (0…255) Звідси Лістинг програми .nolist .include <2313def.inc> .list .def lcd = r16 ; регістр, який містить команди або дані для РКД .def count = r17 .def temp = r18 .def Delay1 = r19 ; регістри часової затримки .def Delay2 = r20 .def Delay3 = r21 .def cmp1 = r22 .def cmp2 = r23 .def ACP_res1 = r24 ; регістри містять результат перетворення АЦП .def ACP_res2 = r25 .def ACP_res3 = r26 .def ACP_res4 = r27 .def B1 = r19 ; регістри вокористовуються при множенні .def B2 = r20 .def B3 = r21 .def B4 = r22 .def num = r28 .def end_num = r29 .equ N_2mks = 3 .equ N_50mks = 71 .equ N_2ms = 2946 .equ N_20ms = 29489 .equ CMP_low = 1368 ; нижній рівень спрацювання 2.5 - 0.83 = 1.67 .equ CMP_high = 2727 ; верхній рівень спрацювання 2.5 + 0.83 = 3.33 ; при подільнику 1024 і частоті 7,3728 частота спрацювання таймера 1.8 Гц .equ TimerVal = 4000 .equ RW = PD4 ; керування рідкокристалічним дисплеєм .equ E = PD5 .equ RS = PD6 .equ nCS = PB0 ; виводи для керування АЦП .equ DOUT = PB1 .equ SCLK = PB2 .cseg .org 0 rjmp RESET ; перехід після скидання .org 0x04 rjmp TIMER_EXT ; Timer1 overlow .org 0x0B RESET: ; ініціалізація стеку ldi temp, low(RAMEND) out SPL, temp ldi temp, (1<<PD1)+(1<<PD4)+(1<<PD5)+(1<<PD6) out DDRD, temp ; налаштувати виводи порта D ldi temp, ~((1<<PB1)+(1<<PB3)) out DDRB, temp ; налаштувати виводи порта B ; налаштування таймера ldi temp, high(TimerVal) out OCR1AH, temp ; занести старший байт ldi temp, low(TimerVal) out OCR1AL, temp ; занести молодший байт ldi temp, (1<<OCIE1A) ; дозволити переривання при співпадінні out TIMSK, temp ldi temp, (1<<CTC1) + (1<<CS12) + (1<<CS10) ; div = 1024 out TCCR1B, temp ldi temp, (1<<SE) ; дозволити енергозберігаючий режим out MCUCR, temp ; налаштування UART ldi temp, 47 out UBRR, temp; задати швидкість передачі 9600 бод при тактовій 7,3728 sbi UCR, TXEN ; дозволити передачу rcall LCD_Setup ; підпрограма ініціалізації РКД rcall TIMER_EXT ; вивести напругу і виставити флажок переривань Wait_Loop: sleep ; Idle режим rjmp Wait_Loop ;/////////////////////////////////////////////// TIMER_EXT: ; отримати і вивести дані про напругу ldi lcd, 0b00000001 ; очистити LCD встановити курсор на початок rcall LCD_Com ; послати команду в LCD rcall wait_2ms ; почекати поки LCD обробить команду rcall GetACP_Res ; отримати дані з АЦП ; порівняти отримані дані з нижнім порогом спрацювання ldi cmp1, low(CMP_low) ldi cmp2, high(CMP_low) cp ACP_Res1, cmp1 ; порівняти молодші байти cpc ACP_Res2, cmp2 ; порівняти старші байти і перенос brcs Alarm ; значення менше за нижній поріг ; Порівняти з верхнім порогом спрацювання ldi cmp1, low(CMP_high) ldi cmp2, high(CMP_high) cp cmp1, ACP_Res1 ; порівняти молодші байти cpc cmp2, ACP_Res2 ; порівняти старші байти і перенос brcs Alarm ; значення менше за нижній поріг ; значення є в допустимих межах - необхідно вивести число на LCD ldi ZL, low(szVBegin*2) ldi ZH, high(szVBegin*2) rcall LCD_Out ; вивести початок повідомлення (U = ) rcall Calc_Mul_Div ; множимо результат з АЦП на 5000 і ділимо на 4096 rcall GetDigits ; отримуємо значення напруги mov lcd, ACP_Res1 ; виводимо числове значення rcall LCD_Dat ldi lcd, '.' rcall LCD_Dat mov lcd, ACP_Res2 rcall LCD_Dat mov lcd, ACP_Res3 rcall LCD_Dat mov lcd, ACP_Res4 rcall LCD_Dat ldi ZL, low(szVEnd*2) ldi ZH, high(szVEnd*2) rcall LCD_Out ; вивести кінець повідомлення ( V) rcall UART_NextLine ; перейти на наступний рядок reti Alarm: ; Виводимо на LCD Alarm ldi ZL, low(szAlarm*2) ; завантажити в регістрову пару Z ldi ZH, high(szAlarm*2) ; адресу рядка rcall LCD_Out; ; вивести на LCD слово Alarm rcall UART_NextLine ; перейти на наступний рядок reti ;/////////////////////////////////////////////// LCD_Setup: ; затримка ~20 мс після включення живлення ldi Delay1, low(N_20ms) ldi Delay2, high(N_20ms) ldi Delay3, byte3(N_20ms) rcall Delay ; виставляємо команду ldi temp, 0x20 ; 4-бітний інтерфейс, 1-рядок, шрифт – 5х7 точок out PORTB, temp sbi PORTD, E ; сформувати передній фронт імпульсу на виводі Е rcall Pause cbi PORTD, E ; сформувати задній фронт імпульсу на виводі Е ldi lcd, 0x20 ; 4-бітний інтерфейс, 1-рядок, шрифт – 5х7 точок rcall LCD_Com ; послати команду в LCD ldi lcd, 0x20 ; 4-бітний інтерфейс, 1-рядок, шрифт – 5х7 точок rcall LCD_Com ; послати команду в LCD ldi lcd, 0b00000001 ; очистити LCD встановити курсор на початок rcall LCD_Com ; послати команду в LCD rcall wait_2ms ; почекати поки LCD обробить команду ldi lcd, 0b00000110 ; інкремент АС без зсуву дисплею rcall LCD_Com ; послати команду в LCD ldi lcd, 0b00001100 ; включити дисплей, виключити курсор rcall LCD_Com ; послати команду в LCD rcall wait_2ms ; почекати поки LCD обробить команду ret ;/////////////////////////////////////////////// ; передає через UART байт даних з регістра lcd UART_PutChar: sbis USR, UDRE rjmp UART_PutChar ; очікуємо щоб передати наступний байт out UDR, lcd ret ;/////////////////////////////////////////////// UART_NextLine: ; відіслати через UART символи переходу на новий рядок ldi lcd, 13 rcall UART_PutChar ldi lcd, 10 rcall UART_PutChar ret ;/////////////////////////////////////////////// ; підпрограма запису в LCD слова (адрес в рег. парі Z) LCD_Out: lpm ; зчитати символ з флеш-пам’яті програм mov lcd, r0 ; переслати символ в регістр lcd cpi lcd, 0 breq LCD_Out_Exit ; якщо наступний символ 0 - виходимо rcall LCD_Dat ; викликати підпрограму виводу символу на індикатор adiw ZL, 1 ; перейти до наступного символу rjmp LCD_Out LCD_Out_Exit: ret ; повернення з підпрограми ;/////////////////////////////////////////////// LCD_Com: ; підпрограма запису в LCD команд cbi PORTD, RS ; обнулити RS - передається команда mov temp, lcd ; завантажити в temp команду andi temp, 0xf0 ; обнулити обнулити молодшу тетраду out PORTB, temp ; встановити дані на шині та сигнал RS sbi PORTD, E ; сформувати передній фронт імпульсу на виводі Е rcall Pause cbi PORTD, E ; сформувати задній фронт імпульсу на виводі Е cbi PORTD, RS ; обнулити RS - передається команда mov temp, lcd ; завантажити в temp команду swap temp ; поміняти місцями тетради andi temp, 0xf0 ; обнулити обнулити молодшу тетраду out PORTB, temp ; встановити дані на шині даних sbi PORTD, E ; сформувати передній фронт імпульсу на виводі Е rcall Pause cbi PORTD, E ; сформувати задній фронт імпульсу на виводі Е rcall wait_50mks ; почекати поки LCD обробить команду ret ;/////////////////////////////////////////////// ; підпрограма запису в LCD байту даних та пересилки його через UART LCD_Dat: rcall UART_PutChar ; переслати дані також через UART sbi PORTD, RS ; встановити флажок опереції з даними mov temp, lcd ; завантажити в temp дані andi temp, 0xf0 ; обнулити молодшу тетраду out PORTB, temp ; вивести в В старшу тетраду даних sbi PORTD, E ; сформувати передній фронт імпульсу на виводі Е rcall Pause cbi PORTD, E ; сформувати задній фронт імпульсу на виводі Е mov temp, lcd ; завантажити в temp дані swap temp ; поміняти місцями тетради andi temp, 0xf0 ; обнулити молодшу тетраду out PORTB, temp ; вивести в В молодшу тетраду даних sbi PORTD, E ; сформувати передній фронт імпульсу на виводі Е rcall Pause cbi PORTD, E ; сформувати задній фронт імпульсу на виводі Е rcall wait_50mks ; почекати поки LCD обробить команду ret ;/////////////////////////////////////////////// GetACP_Res: ; отримання даних з АЦП clr ACP_res3 clr ACP_res4 sbi PORTB, nCS ; ініціалізуємо вихід cbi PORTB, SCLK ; ініціалізація ацп cbi PORTB, nCS ; початок перетворення acp_wait: sbis PINB, DOUT ; очікуємо на одиницю на виході DOUT rjmp acp_wait clr ACP_res1 ; очищаємо регістри результату clr ACP_res2 ldi count, 12 ; кількість ітерацій - необхідно зчитати 12 біт acp_read: ; зчитуємо результат sbi PORTB, SCLK cbi PORTB, SCLK ; формуємо один тактовий імпульс lsl ACP_res1 rol ACP_res2 sbic PINB, DOUT ; пропускаємо інструкцію якщо вхід в 0 ori ACP_res1, 1 ; виставляємо в молодший біт 1 dec count brne acp_read ret ; читання успішно завершено ;/////////////////////////////////////////////// Mul_2: ; підпрограма множить ACP_Res на 2 lsl ACP_Res1 rol ACP_Res2 rol ACP_Res3 rol ACP_Res4 ret ;/////////////////////////////////////////////// Mul_10: ; підпрограма множить ACP_Res на 10 rcall Mul_2 ; знайдемо 2x mov B1, ACP_Res1 mov B2, ACP_Res2 mov B3, ACP_Res3 mov B4, ACP_Res4 ldi temp, 2 loop: ; знайдемо 8х rcall Mul_2 dec temp brne loop add ACP_Res1, B1 ; 2x + 8x = 10x adc ACP_Res2, B2 adc ACP_Res3, B3 adc ACP_Res4, B4 ret ;/////////////////////////////////////////////// ; функція множить результат з АЦП на 50000 і ділить на 4096 Calc_Mul_Div: ; 50000/4096 = 100000/8192 ldi count, 5 loop_mul_10: rcall Mul_10 dec count brne loop_mul_10 ; 100000x ldi count, 13 ; тепер ділимо на 8192 (зсув вправо 13 раз) div_8192: lsr ACP_Res4 ror ACP_Res3 ror ACP_Res2 ror ACP_Res1 dec count brne div_8192 mov B1, ACP_Res1 mov B2, ACP_Res2 ; тут в двох байтах маємо [B2:B1] = ACP_Res*50000/4096 ret ;/////////////////////////////////////////////// GetDigits: ldi count, 8 ldi ZL, low(CmpDig*2) ldi ZH, high(CmpDig*2) next_push: lpm adiw ZL, 1 ; перейти до наступного символу push r0 ; занести в стек старші та молодші розряди чисел порівнняння dec count brne next_push ldi ZL, 24 clr ZH ldi count, 4 next_num: clr num ; тут повинна зберігатися цифра pop cmp1 ; забрати з стеку молодший байт числа з яким порівнюємо pop cmp2 ; взяти старший байт числа з яким порівнюємо num_loop: cp B1, cmp1 ; порівняти молодші байти cpc B2, cmp2 ; порівняти старші байти і перенос brcs store_num ; зберігаємо знайдене число sub B1, cmp1 sbc B2, cmp2 inc num ; збільшуємо кількість одиниць rjmp num_loop store_num: subi num, -'0' ; обчислюємо ANSI код цифри st Z+, num dec count brne next_num ret ;/////////////////////////////////////////////// Pause: ; Затримка на 2 мкс ldi Delay1, N_2mks m1: subi Delay1, 1 brcc m1 nop ret wait_50mks: ; підпрограма часової затримки на 50 мкс при тактовій частоті 7.3728 МГц ldi Delay1, low(N_50mks) ldi Delay2, high(N_50mks) ldi Delay3, byte3(N_50mks) rcall Delay ret wait_2ms: ; підпрограма часової затримки на 2 мс при тактовій частоті 7.3728 МГц ldi Delay1, low(N_2ms) ldi Delay2, high(N_2ms) ldi Delay3, byte3(N_2ms) rcall Delay ret Delay: subi Delay1, 1 sbci Delay2, 0 sbci Delay3, 0 brcc Delay nop ret szAlarm: .db 'A', 'l', 'a', 'r', 'm',0 szVBegin: .db 'U', ' ', '=', ' ', 0 szVEnd: .db ' ', 'V', 0 CmpDig: .db 0, 10, 0, 100, high(1000), low(1000), high(10000), low(10000) Розрахунки часових затримок Розрахуємо часову затримку на 20 мс., враховуючи завантаження констант, виклики підпрограм і т.д.: 1 + 1 + 1 + 3 + N_20ms · (1 + 1 + 1 + 2) + 4 = 0.02 · 7.3728 · 106  N_20ms = 29489 Розрахуємо часову затримку на 2 мс.: 3 + 1 + 1 + 1 + 3 + N_2ms · (1 + 1 + 1 + 2) + 4 + 4 = 0.002 · 7.3728 · 106  N_2ms = 2946 Розрахуємо часову затримку на 50 мкс: 3 + 1 + 1 + 1 + 3 + N_50mks · (1 + 1 + 1 + 2) + 4 + 4 = 50 · 10-6· 7.3728 · 106  N_50mks = 71 Розрахуємо часову затримку на 2 мкс: 3 + 1 + N_2mks · (1 + 2) + 4 = 2 · 10-6· 7.3728 · 106  N_50mks = 9 Результат симуляції схеми в Proteus  Висновок: під час виконання даної розрахункової роботи, я написала програму на мові асемблер під MK AT90S2313 для дискретизації вхідного аналогового сигналу аналого-цифровим перетворювачем і яка відображає значення напруги на рідкокристалічному дисплеї.
Антиботан аватар за замовчуванням

09.02.2012 04:02-

Коментарі

Ви не можете залишити коментар. Для цього, будь ласка, увійдіть або зареєструйтесь.

Ділись своїми роботами та отримуй миттєві бонуси!

Маєш корисні навчальні матеріали, які припадають пилом на твоєму комп'ютері? Розрахункові, лабораторні, практичні чи контрольні роботи — завантажуй їх прямо зараз і одразу отримуй бали на свій рахунок! Заархівуй всі файли в один .zip (до 100 МБ) або завантажуй кожен файл окремо. Внесок у спільноту – це легкий спосіб допомогти іншим та отримати додаткові можливості на сайті. Твої старі роботи можуть приносити тобі нові нагороди!
Нічого не вибрано
0%

Оголошення від адміністратора

Антиботан аватар за замовчуванням

Подякувати Студентському архіву довільною сумою

Admin

26.02.2023 12:38

Дякуємо, що користуєтесь нашим архівом!