Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

4 практика микроконтроллеры

.pdf
Скачиваний:
0
Добавлен:
25.11.2025
Размер:
679.56 Кб
Скачать

Министерство науки и высшего образования Российской Федерации Федеральное государственное автономное образовательное учреждение высшего образования «Омский государственный технический университет» Кафедра” Автоматизация и робототехника”

Практическое задание №4

Тема: «ПРОГРАММИРОВАНИЕ ИНТЕРФЕЙСА UART/USART В РЕЖИМЕ ПЕРЕДАЧИ БОЛЬШОГО ОБЪЕМА ДАННЫХ (МАССИВЫ)»

Вариант 13

Выполнил: Студент группы АТП-222

Пискунов А.И. Проверил:

Доц., к. н. Пешко М.С.

Омск 2025

Цель: Реализуйте вывод в интерфейс UART заданной последовательности данных через индивидуальные промежутки времени.

Обеспечьте начало передачи данных нажатием кнопки, подключенной к одному из выводов микроконтроллера.

Теоретическая справка

USART (Universal Synchronous-Asynchronous Receiver/Transmitter) –

универсальный синхронно-асинхронный приемопередатчик.

UART (Universal Asynchronous Receiver/Transmitter) – универсальный асинхронный приемопередатчик, интерфейс для связи цифровых устройств,

предназначенный для передачи данных в последовательной форме. Очень распространен и весьма востребован, имеет аппаратную реализацию во многих микроконтроллерах.

UART может использоваться как для взаимодействия компонентов внутри одного устройства (например, в режиме SPI), так и для подключения устройств между собой. Для внешних подключений сигналы с уровнями логики ТТЛ или КМОП подходят мало из-за низкой помехоустойчивости.

Распространенным стандартом физического уровня для UART, который подходит для подключения внешних устройств, является RS232/RS-485.

Ход работы

Рисунок 1 – Алгоритм работы

Описание алгоритма:

2

1.Установка частоты микроконтроллера

2.Подключение необходимых библиотек

3.Определяем скорость передачи

4.Расчёт значения регистра UBRR

5.Вводим массив для вывода, а также устанавливаем максимальное значения массива

6.Настраиваем Usart на скорость bauddivider

7.Отключаем глобальные прерывания

8.Очищаем регистры TCCR1A и TCCR1B

9.Устанавливаем PB4 как вход и устанавливаем высокий уровень,

для кнопки

10.Устанавливаем предделитель таймера на 256

11.Устанавливаем необходимое значение для таймера, 0.25 секунд

12.Разрешаем прерывания по переполнению таймера

13.Включаем глобальные прерывания

14.Включаем основной бесконечный цикл

15.Выключаем основной бесконечный цикл

16.Заходим в цикл при условии, что передатчик свободен

17.Записываем байт в регистр передатчика USART

18.Цикл заканчивается

19.Устанавливаем скорость передачи данных для старших 8 бит

20.Устанавливаем скорость передачи данных для младших 8 бит

21.Сбрасываем регистр состояния, соответственно работаем в обычной скорости и сбрасываем флаги

22.Включаем приёмник и передатчик

23.Устанавливаем размер 8 бит и 1 стоп бит

24.Прерывание по переполнению таймера

25.Устанавливаем необходимое значение для таймера, 0.25 секунд

26.Сбрасываем индекс строки

27.Разрешаем прерывания для передачи по байтам

3

28.Прерывание по опустошению регистра данных передатчика

29.Проверяем нажата ли кнопка, если да, то следующий шаг, если нет,

то сразу в конец

30.Условие, которое проверяет индекс строки

31.Условие выполняется, поэтому мы передаём по байту

32.Условие не выполняется, то прерывание запрещается

Рисунок 2 – Собранная схема

Рисунок 3 – Пример работы

Расчёт значения TCNT1 для прерывания таймера. По заданию необходимо 0.25 секунд, поэтому необходимо рассчитать значение TCNT1,

используя предделитель 256:

4

65536 − 0.25 16000000 = 49911

256

Листинг кода

#ifndef F_CPU

#define F_CPU 16000000UL #endif

#include <avr/io.h> #include <avr/interrupt.h> #define baudrate 9600L

#define bauddivider (F_CPU/(16*baudrate)-1) #define buffer_MAX 39

uint8_t buffer[buffer_MAX] = "Hello Piskunov A.I. ATP-222 variant 13"; volatile uint8_t buffer_index = 0;

void USART_Init(unsigned int ubrr);

void USART_Transmit(unsigned char data); int main(void) {

USART_Init(bauddivider);

DDRB &= ~(1 << PB4);

PORTB |= (1 << PB4); cli();

TCCR1A = 0;

TCCR1B = 0;

TCCR1B = (1 << CS12); TCNT1 = 49911; TIMSK1 = (1 << TOIE1); sei();

while (1) {

}

}

void USART_Transmit(unsigned char data) { while (!(UCSR0A & (1 << UDRE0))); UDR0 = data;

}

5

void USART_Init(unsigned int ubrr) { UBRR0H = (unsigned char)(ubrr >> 8); UBRR0L = (unsigned char)ubrr; UCSR0A = 0;

UCSR0B = (1 << RXEN0) | (1 << TXEN0);

UCSR0C = (1 << UCSZ00) | (1 << UCSZ01);

}

ISR(TIMER1_OVF_vect) { TCNT1 = 49911; buffer_index = 0;

UCSR0B |= (1 << UDRIE0);

}

ISR(USART_UDRE_vect) {

if ((PINB & (1 << PB4)) == 0) {

if (buffer_index < buffer_MAX) { UDR0 = buffer[buffer_index++];

} else {

UCSR0B &= ~(1 << UDRIE0);

}}

}

Вывод: В ходе выполнения практического задания, я смог написать код,

который выводит массив данных каждые 0.25 секунд при нажатой кнопки

6