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

Лабы / 3 / Отчёт_ИДЗ3

.docx
Скачиваний:
0
Добавлен:
12.02.2026
Размер:
191.98 Кб
Скачать

МИНОБРНАУКИ РОССИИ

Санкт-Петербургский государственный

электротехнический университет

«ЛЭТИ» им. В.И. Ульянова (Ленина)

Кафедра биотехнических систем

отчет

по индивидуальному домашнему заданию №3

по дисциплине «Медицинские микропроцессорные системы»

Тема: Изучение режима работы pwm

Студенты гр. 2503

Ковалёва Д.Д.

Малышев К.А.

Новикова С.Л.

Преподаватель

Алексеев Б.Э.

Санкт-Петербург

2025

Задачи

  • Изучить принцип работы и программирование таймера в режиме ШИМ

  • Поработать более плотно с арифметикой и логикой на ассемблере.

Режимы работы таймера.

Режим работы таймера T0 определяется состоянием четырех битов WGM01…WGMx03 регистра TCCR0A и TCCR0B.

Счётные режимы

Оба режима Normal и CTC являются счётными, то есть таймер считает такты и запоминает сколько тактов прошло. Это может быть использовано для измерения промежутков времени.

Режим Normal

Это наиболее простой режим работы таймеров, он же единственный режим в младших моделях семейства. В этом режиме счетный регистр функционирует как обычный суммирующий счетчик. По каждому импульсу тактового сигнала осуществляется инкремент счетного регистра. При переходе через значение $FF возникает переполнение, и счет продолжается со значения $00. В том же такте сигнала, в котором обнуляется регистр TCNTn, устанавливается в «1» флаг переполнения счетного регистра TOVn (Timer Overflow).

При равенстве счетного регистра и регистра сравнения устанавливается флаг прерывания OCFn и, если разряд OCIEn регистра TIMSK установлен в «1», генерируется соответствующее прерывание. Наряду с установкой флага при равенстве счетного регистра и регистра сравнения может изменяться состояние вывода OC0x микроконтроллера.

Режим CTC (сброс при совпадении)

В этом режиме счетный регистр функционирует как обычный суммирующий счетчик, инкремент которого осуществляется по каждому импульсу тактового сигнала на входе таймера. Однако максимально возможное значение счетного регистра и, следовательно, разрешающая способность счетчика определяется регистром сравнения OCR0A и OCR0B. После достижения значения, записанного в регистре сравнения, счет продолжается со значения 0x0000. В том же такте сигнала, в котором обнуляется счетный регистр, устанавливается флаг прерывания TOV0 регистра TIFR0.

Рисунок 1 – Схема прерываний

Режим работы Fast-PWM (быстрый ШИМ)

Рисунок 2 – Схема работы ШИМ

В этом режиме таймер работает до верхнего значения переполнения, после чего сбрасывается. При этом, когда таймер начинает свою работу, флаг сравнения установлен, а когда достигает значения регистра сравнения, то значение флага инвертируется. Верхний предел (TOP) определяется регистром сравнения OCR0A, а порог переключения регистром OCR0B. Таким образом получается некая широтно-импульсная модуляция, о которой написано далее. При этом, пин, на который будет выводиться ШИМ, можно определить, задав регистр маски таймера на этот пин.

Режим работы phase-correct Fast-PWM.

Рисунок 3 – Схема работы фазокорректного ШИМ

Логика работы примерно такая же, как и с Fast-PWM, за тем исключением, что, при достижении верхнего предела, таймер не сбрасывается, а начинает считать в обратную сторону, пока не достигнет нижнего предела, а потом снова изменяет направление счёта.

Фазокорректным он называется, потому что сигнал ШИМ симметричный относительно центра периода, благодаря этому фаза сигнала не сдвигается.

Широтно-импульсная модуляция.

Широтно-импульсная модуляция (ШИМ) – метод кодирования аналогового сигнала путём изменения ширины (длительности) прямоугольных импульсов несущей частоты. Если проще, разберём это с математической точки зрения.

Наш микроконтроллер не может выдавать аналоговый сигнал в чистом виде, только логическую единицу (5 вольт) или логический 0 (землю). Но, допустим, чтобы изменять яркость горения светодиода, необходимо подавать на диод напряжение не только 5 и 0 вольт, но и промежуточные значения. Тут и приходит на помощь ШИМ.

Рассчитаем среднее значение напряжения вы выходе микроконтроллера, если половину времени сигнала подаётся 1 (5 вольт), а половину 0 (земля):

Таким образом среднее значение напряжения составляет 2,5 вольта. А если время действия сигнала будет 0,8 времени импульса, то среднее значение будет уже 4 вольта. Отношение времени действия положительного напряжения ко всему периоду сигнала называется коэффициентом заполнения. Чаще используют обратную ему величину – скважность – отношение периода импульса к времени действия положительного напряжения в нём.

Таким образом, меняя скважность сигнала мы смогли симулировать различные уровни аналогового сигнала. При небольшом периоде сигнала, разница между ШИМ и аналоговым сигналом будет практически неразличима.

Примеры использования ШИМ сигнала.

ШИМ можно использовать, как очевидно, для регулировки яркости светодиодов, управления нагревательными элементами в электрической печи, управления скорости вращения двигателей постоянного тока, работы в системах связи (передачи информации по каналам связи).

Листинг программ

Исходной

.def Temp = r16

.equ IRQs_FOR_DUTY_CHANGE = 10

.def irq_counter = r18

.def delta = r19

.ORG 0x000 //Объясняем куда прыгает при достижении каких-либо прерываний

RJMP RESET

.ORG TIM0_OVFaddr

RJMP Tim_OVF

.ORG INT_VECTORS_SIZE

Tim_OVF:

DEC irq_counter // Уменьшаем счетчик прерываний

BREQ Tim_OVF_End // Если 0, запускаенм изменение

RETI

Tim_OVF_End:

LDI irq_counter, IRQs_FOR_DUTY_CHANGE // Сбрасываем счетчик прерываний

IN Temp, OCR0BL // Загружаем текущее значение OCR0B

ADD Temp, delta // Прибавляем дельту

OUT OCR0BL, Temp // Сохраняем новое значение OCR0B

CPI Temp, 0xFF // Проверяем, достигли ли максимума

BREQ negdelta // Если да, устанавливаем дельту в -1

CPI Temp, 0x00 // Проверяем, достигли ли минимума

BREQ negdelta // Если да, устанавливаем дельту в 1

RETI // Выходим из прерывания

negdelta:

NEG delta

RETI

RESET:

LDI Temp, (1 << DDRA5) // Устанавливаем ЛЕД пин как выход

OUT DDRA, Temp

LDI Temp, (1 << REMAP) // Устанавливаем маску ШИМ на этот пин

OUT GTCCR, Temp

LDI irq_counter, IRQs_FOR_DUTY_CHANGE // Сбрасываем счётчик прерываний

LDI delta, 1

// Настройки таймера

// Включаем режим быстрого 8-битного ШИМ-режима

LDI Temp, (1 << COM0B1)|(1 << COM0B0)|(1 << WGM00)

OUT TCCR0A, Temp

LDI Temp, (1 << WGM02)|(1 << CS00)|(0 << CS02) // Устанавливаем предделитель

OUT TCCR0B, Temp

LDI Temp, 0x80 // 0x80 устанавливаем скважность на 50%

OUT OCR0BL, Temp

LDI Temp, (1 << TOIE0)

OUT TIMSK0,Temp

SEI

start: // Бесконечный цикл программы

rjmp start

Конечной

#include <avr/io.h>

#include <avr/interrupt.h>

#define IRQs_FOR_DUTY_CHANGE 10 // Максимальное число прерываний

uint8_t irq_counter = 0; // Счётчик прерываний

uint8_t delta = 1; // Дельта изменения

int main(void)

{

// Устанавливаем Пин светодиода

DDRA |= (1 << DDRA5); // Направление выход

GTCCR |= (1 << REMAP); // Маска ШИМ на этот пин

// Установка таймера

// Устанавливаем на режим быстрый-ШИМ

TCCR0A |= (1 << COM0B1)|(1 << COM0B0)|(1 << WGM00);

TCCR0B |= (1 << WGM02)|(1 << CS00); // Устанавливаем предделитель

TIMSK0 |= (1 << TOIE0); // Разрешаем прерывание по переполнению

sei(); // Разрешим глобальные прерывания

while (1) {}

}

ISR(TIM0_OVF_vect) { //Сработало прерывание по переполнению

irq_counter++; // Увеличиваем счётчик прерываний

// Если прерываний 10

if (irq_counter == IRQs_FOR_DUTY_CHANGE) {

irq_counter = 0; // Сбросили счётчик

OCR0B += delta; // Изменяем порог переключения ШИМ

// Смотрим максимальное ли значение порога

if (OCR0B == 0xFF) {

delta = -1;

} // Или минимальное

if (OCR0B == 0) {

delta = 1;

}

}

}

Соседние файлы в папке 3