4 лаба микроконтроллеры
.docxМинистерство науки и высшего образования Российской Федерации Федеральное государственное автономное образовательное учреждение высшего образования «Омский государственный технический университет» Кафедра” Автоматизация и робототехника”
Лабораторная работа №4
По теме: «Программирование порта ввода-вывода с семисегментным индикатором в параллельном режиме подключения»
Вариант 13
Выполнил:
Студент группы АТП-222
Пискунов А.И.
Проверил:
Асс. Холмов М.А.
Омск 2025
Цель: Обеспечьте вывод значений из предыдущей лабораторной работы в режиме бегущей строки на четырех семисегментных индикаторах.
Теоретическая справка
Для формирования отдельного символа на семисегментном индикаторе необходимо семь информационных проводов (или восемь, для светодиода dp). При этом, если индикаторов два, то требуется уже 14 (16) проводов, для трех индикаторов – 21 (23), а для четырех – 28 (32). Но на демонстрационной плате семисегментных индикаторов их всего шестнадцать, а согласно таблице распиновки разъема используются всего 13 контактов. Индикатор CC56-12SRWA имеет внутреннюю структуру, представленную на рис. 1
Рисунок 1 – Индикатор CC56-12SRWA
Рисунок 2 – Электрическая схема платы индикатора
После подачи на вывод DIGX значения «лог 1» открывается соответствующий транзистор, и семисегментный индикатор данного разряда начинает отображать значение, установленное на выводах a-g, dp. С переключением «лог 1» с одного вывода DIGX на другой переключается и индикация с одного индикатора на другой. Эффект непрерывности возникает, когда индикаторы перемигиваются с частотой, превышающей инерционность человеческого зрения (25 кадров в секунду). Для комфортного восприятия требуется порядка 5 мс на один разряд, что в пересчете на четыре разряда составит время 20 мс. Такая задержка соответствует частоте 50 кадров в секунду (что в два раза больше минимально необходимой).
Так как расчет паузы между выводом значения на разряды не должен приводить к загрузке процессора, его организуют при помощи таймера, который обеспечивает выполнение вывода значения на очередной разряд динамической индикации через каждые 5 мс. После выполнения подпрограммы обработчика таймера процессор имеет возможность заниматься своей «основной» деятельностью.
С информацией о регистрах управления таймерами для используемых процессоров необходимо ознакомиться в официальной документации. Последовательность действий процессора для обеспечения динамической индикации в общем случае выглядит следующим образом:
− отключение индицируемого разряда;
− выбор нового разряда для индикации;
− расчет значения для отображения на новом разряде;
− выставление кода символа для нового разряда;
− выставление сигнала включения нового разряда.
Ход работы
Рисунок 1 – Алгоритм работы
Описание алгоритма:
Установка частоты микроконтроллера
Инициализация необходимых библиотек
Инициализация переменных timer228, nomer и opa
Инициализация массива для вывода на семи сегментный дисплей
Порты PB0-3 устанавливаем, как выходы для дисплеев
Выключаем их
Отключение глобальных прерываний
Обнуление регистра TCCR1A и TCCR1B
Установка предделителя таймера на 64
Устанавливаем значение сравнения, после которого сработает прерывание
Разрешение прерывания по переполнению таймера
Включение глобальных прерываний
Все порты D устанавливаем, как выходы для сегментов a-f, а также устанавливаем им низкий уровень
Начинается главный цикл
Условие, проверяющее чему равна переменная nomer, которая отвечает за то какой дисплей будет показываться
Если переменная больше или равно 4, то приравнивается к 0
Условие, проверяющее чему равна переменная timer228, которая отвечает за то символ должен показываться сейчас
Если переменная равна или больше 7, то приравнивается к 0
Условие, проверяющие равна переменная opa переменной nomer
Если переменная opa не равна nomer, то значит, необходимо менять символ. Соответственно opa приравнивается к nomer, чтобы символ бесконечно не менялся пока находится в цикле, а лишь при прерывании
Timer228 увеличивается на 1
Меняется символ в зависимости от timer228
Конец основного цикла
Вход в обработчик прерывания при переполнении таймера.
Вновь устанавливаем значение сравнения
Условие, проверяющее чему равна переменная nomer
Если переменная равна 0, то включается четвёртый дисплей, а остальные выключаются
Условие, проверяющее чему равна переменная nomer
Если переменная равна 1, то включается третий дисплей, а остальные выключаются
Условие, проверяющее чему равна переменная nomer
Если переменная равна 2, то включается второй дисплей, а остальные выключаются
Условие, проверяющее чему равна переменная nomer
Если переменная равна 3, то включается первый дисплей, а остальные выключаются
Переменная nomer увеличивается на единицу
Листинг кода
#define F_CPU 16000000UL
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>
int timer228=0;
int nomer=0;
int opa=0;
unsigned char number[] = {
0b1111111, // 8
0b0000110, // 1
0b1110001, // F
0b1100110, // 4
0b1110111, // A
0b1000000, // -
0b0111001, // C
0b1011110, // d
};
int main(void) {
DDRB |= (1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3);
PORTB |=(1<<PB0)|(1<<PB1)|(1<<PB2)|(1<<PB3);
cli();
TCCR1A = 0;
TCCR1B = 0;
TCCR1B |= (1 << CS11)|(1 << CS10);
TCNT1=53036;
TIMSK1 = (1 << TOIE1);
sei();
DDRD = 0xff;
PORTD = 0x00;
while (1) {
if(nomer >=4){
nomer=0;
}
if(timer228>=7){
timer228=0;}
if(opa != nomer){
opa=nomer;
timer228++;
PORTD = number[timer228];}
}
}
ISR(TIMER1_OVF_vect)
{
TCNT1=53036;
if(nomer == 0){
PORTB &= ~(1<<PB3);
PORTB |=(1<<PB0)|(1<<PB1)|(1<<PB2);}
if(nomer == 1){
PORTB &= ~(1<<PB2);
PORTB |=(1<<PB0)|(1<<PB1)|(1<<PB3);}
if(nomer == 2){
PORTB &= ~(1<<PB1);
PORTB |=(1<<PB0)|(1<<PB2)|(1<<PB3);}
if(nomer == 3){
PORTB &= ~(1<<PB0);
PORTB |=(1<<PB1)|(1<<PB2)|(1<<PB3);}
nomer++;
}
Рисунок 1 – Пример работы программы
Рисунок 2 – Пример работы программы
Рисунок 3 – Пример работы программы
Рисунок 4 – Пример работы программы
Вывод: в ходе выполнения работы была разработана программа для микроконтроллера AVR, обеспечивающую бегущую строку на четырёх семисегментных дисплеях
