програмування мікроконтролерів AVR мовою асемблер

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

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

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

Рік:
2024
Тип роботи:
Розрахункова робота
Предмет:
Програмування мікроконтролерів систем автоматики
Група:
СІ-21
Варіант:
4 14 1

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

Міністерство освіти і науки України Національний університет “Львівська політехніка” Кафедра КСА Звіт до графічно-розрахункової роботи з предмету «Програмування мікроконтролерів систем автоматики» Варіант №4 Мета графічно-розрахункової роботи: закріпити отримані при вивченні даного курсу знання і навики програмування мікроконтролерів AVR мовою асемблер та мовою високого рівня Сі; навчитися проектувати мікроконтролерні мережі на основі інтерфейсу RS-485 та розробляти для них протоколи обміну даними; отримати навики розроблення клієнтських програм під Windows для реалізації зв’язку між персональним комп’ютером та мікроконтролером згідно інтерфейсу RS-232. Короткі теоретичні відомості Цифровий давач температури DS18B20 вимірює температуру в діапазоні від -55 до +125 °С, має програмовану роздільну здатність від 9 до 12 біт та дає можливість задавати верхній та нижній температурні пороги, у випадку порушення яких, виставляється прапорець аварії. Кожний термометр DS18B20 має унікальний 64-бітний серійний номер, який використовується для його адресації на 1-Wire шині. Це дозволяє об’єднати на одній шині декілька незалежно працюючих термометрів та здійснювати між ними та МК обмін даними по 1-Wire шині. Особливістю цього термометра є те, що його можна заживити не тільки від джерела живлення, але і від сигнального дроту. Це так званий режим паразитного живлення. У цьому режимі для підключення давача необхідно лише 2 дроти – сигнальний та «земля». 1-Wire шина повинна бути обов’язково підтягнута до «+» живлення через резистор номіналом 4,7 КОм. Напруга живлення від 3 до 5 В. / Зв’язок на 1-Wire шині реалізується на бітовому рівні. Передача кожного біту, незалежно від напряму, ініціалізується керуючим пристроєм (МК). Принцип формування усіх сигналів на 1-Wire шині однаковий. У початковому стані 1-Wire шина підтягнута через резистор до плюса напруги живлення. Керуючий пристрій (МК) садить на «землю» (лог. «0») на визначений час 1-Wire шину. Потім відпускає її (лог. «1») і, якщо потрібно, читає відповідь пристрою. 1-Wire протоколом визначені такі типи сигналів: скид/присутність; запис лог. «1»; запис лог. «0»; читання біта з пристрою. Ініціалізація: сигнал скиду та присутності. Усі сеанси зв’язку МК з давачем DS18B20 починаються зі сигналу скиду. МК встановлює на 480 мксек. в низький рівень (лог. «0») 1-Wire шину, а потім «відпускає» її (лог. «1»). Якщо до шини підключений давач, то він виявляє перепад рівнів і після паузи в 15-60 мксек. відповідає МК сигналом присутності – встановлює в низький рівень шину на час від 60 до 240 мксек. / Запис даних на 1-Wire шині. Обмін даними відбувається послідовно, молодшим бітом вперед. Передача чи прийом одного біта даних виконується протягом фіксованого проміжку часу (time slot). Розрізняють часові слоти запису та слоти читання. Тривалість часових слотів повинна бути > 60 мксек., а пауза між слотами > 1 мксек. Для передачі «0» МК встановлює 1-Wire шину в нуль на час від 60 до 120 мксек, потім «відпускає» її (лог. «1») та перед записом наступного біта витримує паузу > 1мксек. Для передачі «1» МК в встановлює 1-Wire шину в нуль на час від 1 до 15 мксек, «відпускає» шину (лог. «1») та витримує паузу, яка повинна забезпечувати тривалість часового слота > 60+1 мксек. / Читання даних на 1-Wire шині. МК встановлює 1-Wire шину в нуль на час від 1 до 15 мксек, після чого «відпускає» її, передаючи керування станом шини давачу. Якщо давач передає нуль, то він встановлює низький рівень на шині (лог. «0») до кінця часового слоту. Якщо ж він передає «1», тоді він залишає шину у «підтягнутому» до + напруги живлення стані. МК може зчитувати дані з давача через 15 мксек після початку часового слоту читання. / Завдання Тема 1. Цифровий давач температури DS18B20. «master»: ATmega324P, «slave»: ATmega16. частота тактування МК 8 МГц, швидк. передачі 4800 Бод, адреса задається у пам’яті EEPROM, адреси МК: slave1 = 125, slave2 = 128, інтервал опитування МК «slave» = 1,1 сек., давачі підключаються до виводів PB1, PD7 Код програми пристрою мовою асемблер Master #define F_CPU 8000000L #define BAUD 4800 #define UBRRcalc (F_CPU/(BAUD*16L)-1) #define BUF_SIZE 16 #define BUF_MASK (BUF_SIZE-1) #define BUF_SIZE_master 16 #define BUF_MASK_master (BUF_SIZE-1) #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #include <math.h> #include <stdlib.h> unsigned char BufferOUT[BUF_SIZE][2], StartBufOUT = 0, EndBufOUT = 0; unsigned char BufferOutMaster[BUF_SIZE], StartBufOutMaster = 0, EndBufOutMaster = 0; volatile unsigned char waitread = 0, waitwrite=0; unsigned char u=0; void WriteBufOUT(unsigned char value, unsigned char bit8) { BufferOUT[EndBufOUT][0] = value; BufferOUT[EndBufOUT++][1] = bit8; EndBufOUT &= BUF_MASK; cli(); if( waitread == 0 ) UCSR1B |= 1<<UDRIE1; sei(); } void WriteBufOutMaster(unsigned char value) { BufferOutMaster[EndBufOutMaster++] = value; EndBufOutMaster &= BUF_MASK_master; cli(); if( waitwrite == 0 ) UCSR0B |= 1<<UDRIE0; sei(); } ISR(USART0_RX_vect) { unsigned char w=UDR0; WriteBufOUT(w+1, 1); } ISR(USART0_UDRE_vect ) { UDR0 = BufferOutMaster[StartBufOutMaster++]; waitwrite = 1; StartBufOutMaster &= BUF_MASK_master; if( StartBufOutMaster == EndBufOutMaster || waitwrite == 1 ) UCSR0B &= ~(1<<UDRIE0); } ISR(USART0_TX_vect ) { waitwrite = 0;} unsigned int tempHB, tempLB, temp; ISR(USART1_RX_vect) { unsigned char tempDigital,tempDecimal, minus = 0; unsigned char One; u++; if (u==1) { One=UDR1; WriteBufOutMaster(One); } else if (u==2) { One=UDR1; WriteBufOutMaster(One); } else if (u==3) { One=UDR1; WriteBufOutMaster(One); } else if (u==4) { One=UDR1; WriteBufOutMaster(One); u=0; waitread = 0; if( StartBufOUT != EndBufOUT ) UCSR1B |= 1<<UDRIE1; } } ISR(USART1_TX_vect ) { PORTD &= ~(1<<PD4); } ISR(USART1_UDRE_vect ) { PORTD |= 1<<PD4; if( BufferOUT[StartBufOUT][1] == 1 ) UCSR1B |= 1<<TXB81; else { UCSR1B &= ~(1<<TXB81); waitread = 1; } asm("nop"); UDR1 = BufferOUT[StartBufOUT++][0]; StartBufOUT &= BUF_MASK; if( StartBufOUT == EndBufOUT || waitread == 1 ) UCSR1B &= ~(1<<UDRIE1); } int main() { cli(); Init(); _delay_ms(3000); sei(); while(1) {} } void Init() { DDRA = 0xFF; PORTA = 0x00; DDRB = 0xFF; PORTB = 0x00; DDRC = 0xFF; PORTC = 0x00; DDRD=0b11111010; PORTD=0b00000101; UBRR1L = (unsigned char)(UBRRcalc); UBRR1H = (unsigned char)(UBRRcalc>>8); UCSR1A = 0; UCSR1C = (1<<UCSZ11)|(1<<UCSZ10)|(1<<USBS1); UCSR1B = (1<<UCSZ12)|(1<<RXEN1)|(1<<TXEN1)|(1<<RXCIE1)|(1<<TXCIE1); UBRR0L = (unsigned char)(UBRRcalc); UBRR0H = (unsigned char)(UBRRcalc>>8); UCSR0A=0; UCSR0B=(1<<RXCIE0) | (1<<TXCIE0) | (1<<RXEN0) | (1<<TXEN0); UCSR0C=(1<<UCSZ01) | (1<<UCSZ00); } Slave #define LCDdataPORT PORTA #define LCDdataPIN PINA #define LCDdataDDR DDRA #define LCDcontrolPORT PORTC #define LCDcontrolPIN PINC #define LCDcontrolDDR DDRC #define RS 0 #define RW 1 #define E 2 #define F_CPU 8000000L #define BAUD 4800 #define UBRRcalc (F_CPU/(BAUD*16L)-1) #define BUF_SIZE 4 #define BUF_MASK (BUF_SIZE-1) #include <avr/io.h> #include <util/delay.h> #include <avr/pgmspace.h> #include <avr/interrupt.h> #include <math.h> #include <stdlib.h> #include "LCD_8.h" #include "DS18B20.h" OneWire OW1={&DDRD, &PIND, &PORTD, PD7}; OneWire OW2={&DDRB, &PINB, &PORTB, PB1}; char time=0, address = 125, u=0, k=8; unsigned char BufferOUT[BUF_SIZE], StartBufOUT = 0, EndBufOUT = 0, Memory[4]; volatile unsigned char waitread = 0, write = 0; ISR(TIMER0_COMP_vect) { time++; if (time==50) { time=0; unsigned int tempHB, tempLB, temp; unsigned char tempDigital,tempDecimal, minus = 0; char Sbuf[4]; if(OneWireReset(OW1)) { OneWireWriteByte(OW1, SKIP_ROM); OneWireWriteByte(OW1, READ_SCRATCHPAD); tempLB = (unsigned int)OneWireReadByte(OW1); tempHB = (unsigned int)OneWireReadByte(OW1); Memory[0]=(unsigned char) tempLB; Memory[1]=(unsigned char) tempHB; temp = (tempLB)|(tempHB<<8); if(temp&0x8000) { temp = ~temp + 1; minus = 1; } GotoXY(0, 0); if(minus) Set_Char('-'); else Set_Char('+'); tempDigital = temp >> 4; tempDecimal = temp & 0xF; tempDecimal = (tempDecimal<<1) + (tempDecimal<<3); tempDecimal = (tempDecimal>>4); Set_String( utoa(tempDigital,Sbuf,10) ); Set_Char('.'); Set_String( utoa(tempDecimal,Sbuf,10) ); Set_Char('*'); Set_Char('C'); } if(OneWireReset(OW1) ) { OneWireWriteByte(OW1, SKIP_ROM); OneWireWriteByte(OW1, CONVERT_TEMP); } minus = 0; if(OneWireReset(OW2)) { OneWireWriteByte(OW2, SKIP_ROM); OneWireWriteByte(OW2, READ_SCRATCHPAD); tempLB = (unsigned int)OneWireReadByte(OW2); tempHB = (unsigned int)OneWireReadByte(OW2); Memory[2]=(unsigned char) tempLB; Memory[3]=(unsigned char) tempHB; temp = (tempLB)|(tempHB<<8); if(temp&0x8000) { temp = ~temp + 1; minus = 1; } GotoXY(0, 1); if(minus) Set_Char('-'); else Set_Char('+'); tempDigital = temp >> 4; tempDecimal = temp & 0xF; tempDecimal = (tempDecimal<<1) + (tempDecimal<<3); tempDecimal = (tempDecimal>>4); Set_String( utoa(tempDigital,Sbuf,10) ); Set_Char('.'); Set_String( utoa(tempDecimal,Sbuf,10) ); Set_Char('*'); Set_Char('C'); } if(OneWireReset(OW2) ) { OneWireWriteByte(OW2, SKIP_ROM); OneWireWriteByte(OW2, CONVERT_TEMP); } } } void WriteBufOUT(unsigned char value) { if (write != 1) { BufferOUT[EndBufOUT++] = value; EndBufOUT &= BUF_MASK; } } ISR(USART_RXC_vect) { if (UDR == address) { WriteBufOUT(Memory[0]); WriteBufOUT(Memory[1]); WriteBufOUT(Memory[2]); WriteBufOUT(Memory[3]); UCSRA &= ~(1<<MPCM); UCSRB |= 1<<UDRIE; write = 1; } } ISR(USART_TXC_vect ) { if( StartBufOUT == EndBufOUT ) PORTD &= ~(1<<PD2); } ISR(USART_UDRE_vect ) { PORTD |= 1<<PD2; asm("nop"); UDR = BufferOUT[StartBufOUT++]; StartBufOUT &= BUF_MASK; if( StartBufOUT == EndBufOUT ) { UCSRB &= ~(1<<UDRIE); UCSRA |= (1<<MPCM); write=0; } } int main() { Initial(); if(OneWireReset(OW1) ) { OneWireWriteByte(OW1, SKIP_ROM); OneWireWriteByte(OW1, CONVERT_TEMP); } _delay_ms(1000); if(OneWireReset(OW2) ) { OneWireWriteByte(OW2, SKIP_ROM); OneWireWriteByte(OW2, CONVERT_TEMP); } _delay_ms(1000); sei(); while (1) { } } void Initial() { DDRA = 0xFF; PORTA = 0x00; DDRB = 0xFF; PORTB = 0x00; DDRC = 0xFF; PORTC = 0x00; DDRD=0b11111110; PORTD=0b00000001; UBRRL = (unsigned char)(UBRRcalc); UBRRH = (unsigned char)(UBRRcalc>>8); UCSRA = (1<<MPCM); UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0)|(1<<USBS); UCSRB = (1<<UCSZ2)|(1<<RXEN)|(1<<TXEN)|(1<<RXCIE)|(1<<TXCIE); LCD_ini(); TCCR0 = (1<<WGM01)|(1<<CS02)|(1<<CS00); OCR0 = 0x77; TIMSK = (1<<OCIE0); OneWireInit(OW1); OneWireInit(OW2); } Клієнтська програма using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace roz_v4 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } bool start = false; private void button1_Click(object sender, EventArgs e) { start = true; } bool pause = false; int k = 0, slave = 0; private void timer1_Tick(object sender, EventArgs e) { if (k < 3) k++; else pause = true; byte[] boof = new byte[5]; if (pause && start) { if (slave == 0) { boof[0] = 124; serialPort1.Write(boof, 0, 1); int tempL1 = serialPort1.ReadByte(); int tempH1 = serialPort1.ReadByte(); int tempL2 = serialPort1.ReadByte(); int tempH2 = serialPort1.ReadByte(); short temp1 = (short)(tempL1 | (tempH1 << 8)); temp1 /= 16; label3.Text = "Temper1 = " + temp1.ToString() + "*C"; short temp2 = (short)(tempL2 | (tempH2 << 8)); temp2 /= 16; label4.Text = "Temper2 = " + temp2.ToString() + "*C"; slave++; } else { boof[1] = 127; serialPort1.Write(boof, 1, 1); int tempL1 = serialPort1.ReadByte(); int tempH1 = serialPort1.ReadByte(); int tempL2 = serialPort1.ReadByte(); int tempH2 = serialPort1.ReadByte(); short temp1 = (short)(tempL1 | (tempH1 << 8)); temp1 /= 16; label6.Text = "Temper1 = " + temp1.ToString() + "*C"; short temp2 = (short)(tempL2 | (tempH2 << 8)); temp2 /= 16; label5.Text = "Temper2 = " + temp2.ToString() + "*C"; slave = 0; } } } private void Form1_Load(object sender, EventArgs e) { serialPort1.Open(); } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { serialPort1.Close(); } } } Скріншот клієнтської програми / Висновок: Отже, я закріпив отримані при вивченні даного курсу знання і навики програмування мікроконтролерів AVR мовою високого рівня Сі. Навчився проектувати мікроконтролерні мережі на основі інтерфейсу RS-485 та розробляти для них протоколи обміну даними. Отримав навики розроблення клієнтських програм під Windows для реалізації зв’язку між персональним комп’ютером та мікроконтролером згідно інтерфейсу RS-232 мовою С#. Принципова схема пристрою, що зібрана у пакеті Proteus /
Антиботан аватар за замовчуванням

20.04.2018 20:04-

Коментарі

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

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

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

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

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

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

Admin

26.02.2023 12:38

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