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

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

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

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

Рік:
2024
Тип роботи:
Розрахункова робота
Предмет:
Програмування мікроконтролерів систем автоматики
Варіант:
19

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

Міністерство освіти і науки України Національний університет “Львівська політехніка” Кафедра КСА Звіт до графічно-розрахункової роботи з предмету «Програмування мікроконтролерів систем автоматики» Варіант №19 Львів 2017 Мета графічно-розрахункової роботи: закріпити отримані при вивченні даного курсу знання і навики програмування мікроконтролерів AVR мовою асемблер та мовою високого рівня Сі; навчитися проектувати мікроконтролерні мережі на основі інтерфейсу RS-485 та розробляти для них протоколи обміну даними; отримати навики розроблення клієнтських програм під Windows для реалізації зв’язку між персональним комп’ютером та мікроконтролером згідно інтерфейсу RS-232. Короткі теоретичні відомості Інтерфейс RS-232 був розроблений для забезпечення зв’язку між термінальним обладнанням та апаратурою передачі даних, використовуючи послідовний обмін двійковими даними. Стандарт RS-232 був розроблений у 1969 році американською Асоціацією електронної промисловості, та після незначних поправок отримав назву RS-232С. У 1991 році була здійснена модифікація цього стандарту, після чого він отримав назву EIA/TIA-232E. Інша відома назва цього протоколу ITU V.24. Загально прийнятою назвою є EIA-232, або просто RS-232. У стандарті передбачені асинхронний та синхронний режими обміну, однак переважна більшість пристроїв (наприклад ПК) працюють лише в асинхронному режимі. RS-485 (інша назва EIA/TIA-485) – найпоширеніший стандарт фізичного рівня зв’язку (канал зв’язку + спосіб передачі сигналу). Цей інтерфейс забезпечує обмін даними між декількома пристроями по одній двопровідній лінії зв’язку в напівдуплексному режимі. Для каналу зв’язку вибирається вита пара. В основі інтерфейсу RS-485 лежить принцип диференціальної (балансної) передачі даних. По одному дроті (умовно А) іде оригінальний сигнал, а по іншому (B) – його інверсна копія. Тобто, якщо на одному дроті «1», то на іншому «0», і навпаки. Тому між двома дротами витої пари завжди є різниця потенціалів»: при логічній «1» вона позитивна, а при «0» – негативна. Такий спосіб передачі забезпечує високу стійкість до синфазних перешкод (що діють на два дроти лінії одночасно). Стандарт RS-485 описує лише фізичний рівень процедури обміну даними. Його основні задачі це: перетворення вхідної послідовності «1» та «0» у диференціальний сигнал; передача диференціального сигналу в симетричну лінію зв’язку; підключення чи відключення передавача драйвера згідно сигналу верхнього протоколу обміну; прийом диференціального сигналу з лінії зв’язку. Решта особливостей обміну, синхронізації та квітування покладається на верхній протокол обміну, наприклад RS-232 чи ModBus. RS-485 забезпечує передачу даних зі швидкістю до 10 Мбіт/сек. Максимальна дальність залежить від швидкості: при швидкості 10 Мбіт/сек максимальна довжина лінії – 120 метрів, при швидкості 100 Кбіт/сек – 1200 метрів. Згідно зі специфікацією RS-485 на лінії можуть знаходитися до 32 прийомопередавачів, враховуючи узгоджуючі резистори (120 Ом). Це обумовлено вхідним опором приймача 12 КОм з боку лінії. Деякі мікросхеми драйверів мають підвищений вхідний опір, і тому дають можливість підключати до лінії більшу кількість пристроїв. Завдання Тема 1. Цифровий давач температури DS18B20. «master»: ATmega164P, «slave»: ATmega32. частота тактування МК 9.216 МГц, швидк. передачі 9600 Бод, адреса задається за допомогою «піаніна», адреси МК: slave1 = 77, slave2 = 105, інтервал опитування МК «slave» = 1,7 сек., давачі підключаються до виводів PD7, PB7 Код програми пристрою мовою асемблер Master //-------------------------------------------------------------------------------------------------------------------------------- #define F_CPU 9216000L #define BAUD 9600 #define UBRRcalc (F_CPU/(BAUD*16L)-1) #define BUF_SIZE 16 #define BUF_MASK (BUF_SIZE-1) #define BUF1_SIZE 16 #define BUF1_MASK (BUF1_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 BufOut[BUF_SIZE], StartBufOut = 0, EndBufOut = 0; unsigned char Buf1Out[BUF_SIZE], StartBuf1Out = 0, EndBuf1Out = 0; volatile unsigned char WaitRead = 0, WaitWrite = 0; unsigned char Number = 0; //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART0_RX_vect) { unsigned char Temporary=UDR0; WriteBufOut(Temporary); } //-------------------------------------------------------------------------------------------------------------------------------- void WriteBufOut(unsigned char value) { BufOut[EndBufOut++] = value; EndBufOut &= BUF_MASK; cli(); if(WaitRead == 0) UCSR1B |= 1<<UDRIE1; sei(); } //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART1_UDRE_vect) { PORTD |= 1<<PD4; UCSR1B |= 1<<TXB81; asm("nop"); UDR1 = BufOut[StartBufOut++]; StartBufOut &= BUF_MASK; if(StartBufOut == EndBufOut || WaitRead == 1) UCSR1B &= ~(1<<UDRIE1); } //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART1_TX_vect) { PORTD &= ~(1<<PD4); } //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART1_RX_vect) { unsigned char One; One = UDR1; WriteBuf1Out(One); Number++; if (Number == 4) { Number = 0; WaitRead = 0; if(StartBufOut != EndBufOut) UCSR1B |= 1<<UDRIE1; } } //-------------------------------------------------------------------------------------------------------------------------------- void WriteBuf1Out(unsigned char value) { Buf1Out[EndBuf1Out++] = value; EndBuf1Out &= BUF1_MASK; cli(); if(WaitWrite == 0) UCSR0B |= 1<<UDRIE0; sei(); } //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART0_UDRE_vect) { UDR0 = Buf1Out[StartBuf1Out++]; WaitWrite = 1; StartBuf1Out &= BUF1_MASK; if(StartBuf1Out == EndBuf1Out || WaitWrite == 1) UCSR0B &= ~(1<<UDRIE0); } //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART0_TX_vect) { WaitWrite = 0; } //-------------------------------------------------------------------------------------------------------------------------------- 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 PORTB #define LCDcontrolPIN PINB #define LCDcontrolDDR DDRB #define RS 0 #define RW 1 #define E 2 #define F_CPU 9216000L #define BAUD 9600 #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, PB7}; char timer=0, address; unsigned char BufferOUT[BUF_SIZE], StartBufOUT = 0, EndBufOUT = 0, Boof[4]; volatile unsigned char waitread = 0, write = 0; //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART_RXC_vect) { if (UDR == address) { WriteBufOUT(Boof[0]); WriteBufOUT(Boof[1]); WriteBufOUT(Boof[2]); WriteBufOUT(Boof[3]); UCSRA &= ~(1<<MPCM); UCSRB |= 1<<UDRIE; write = 1; } } //-------------------------------------------------------------------------------------------------------------------------------- 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; } } //-------------------------------------------------------------------------------------------------------------------------------- ISR(USART_TXC_vect ) { if( StartBufOUT == EndBufOUT ) PORTD &= ~(1<<PD2); } //-------------------------------------------------------------------------------------------------------------------------------- ISR(TIMER0_COMP_vect) { timer++; if (timer==40) { timer=0; unsigned int tempHB, tempLB, temp; unsigned char tempDigital,tempDecimal, minus = 0; char Sbuf[4]; Clear_LCD(); if(OneWireReset(OW1)) { OneWireWriteByte(OW1, SKIP_ROM); OneWireWriteByte(OW1, READ_SCRATCHPAD); tempLB = (unsigned int)OneWireReadByte(OW1); tempHB = (unsigned int)OneWireReadByte(OW1); Boof[0]=(unsigned char) tempLB; Boof[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); Boof[2]=(unsigned char) tempLB; Boof[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; } } //-------------------------------------------------------------------------------------------------------------------------------- int main() { Initial(); address = ~PINC; 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 = 0x00; PORTC = 0xFF; 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 rozr_v19 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } bool RS = false; private void button2_Click(object sender, EventArgs e) { if (!RS) { serialPort1.Open(); button2.BackColor = Color.LimeGreen; } else { serialPort1.Close(); button2.BackColor = Color.Gainsboro; } RS = !RS; } bool DS = false; private void button1_Click(object sender, EventArgs e) { if (!DS) { button1.BackColor = Color.LimeGreen; } else { button1.BackColor = Color.Gainsboro; } DS = !DS; } bool Slave = false; byte[] boof = new byte[3]; private void timer1_Tick(object sender, EventArgs e) { if (DS && RS) { if (!Slave) { boof[0] = 77; 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; short temp2 = (short)(tempL2 | (tempH2 << 8)); temp2 /= 16; label3.Text = "Temperature Outside = " + temp2.ToString() + "*C"; label4.Text = "Temperature Inside = " + temp1.ToString() + "*C"; } else { boof[0] = 105; 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; short temp2 = (short)(tempL2 | (tempH2 << 8)); temp2 /= 16; label5.Text = "Temperature Outside = " + temp2.ToString() + "*C"; label6.Text = "Temperature Inside = " + temp1.ToString() + "*C"; } Slave = !Slave; } } private void Form1_FormClosed(object sender, FormClosedEventArgs e) { if (RS) serialPort1.Close(); } } } Скріншот клієнтської програми / Висновок: Отже, я закріпила отримані при вивченні даного курсу знання і навики програмування мікроконтролерів AVR мовою високого рівня Сі. Навчилася проектувати мікроконтролерні мережі на основі інтерфейсу RS-485 та розробляти для них протоколи обміну даними. Отримала навики розроблення клієнтських програм під Windows для реалізації зв’язку між персональним комп’ютером та мікроконтролером згідно інтерфейсу RS-232 мовою С#. Принципова схема пристрою, що зібрана у пакеті Proteus /
Антиботан аватар за замовчуванням

20.04.2018 20:04-

Коментарі

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

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

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

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

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

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

Admin

26.02.2023 12:38

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