МИНОБРНАУКИ РОССИИ
Санкт-Петербургский государственный
электротехнический университет
«ЛЭТИ» им. В.И. Ульянова (Ленина)
Кафедра биотехнических систем
отчет
по индивидуальному домашнему заданию №5.5
по дисциплине «Медицинские микропроцессорные системы»
Тема: УПРАВЛЕНИЕ ЦВЕТОМ АДРЕСНОГО СВЕТОДИОДА WS2812B
Студенты гр. 2503 |
|
Кузнецов Д.А. |
|
|
Андронова П.Д. |
|
|
Лукшина А.О. |
Преподаватель |
|
Алексеев Б.Э. |
Санкт-Петербург
2025
Теоретическая справка
Схема подключения:
Светодиод |
Отладочная плата |
+5V |
VCC или VUSB |
DIN |
PA6 |
GND |
GND |
Адресные светодиоды серии WS2812B управляются однопроводным интерфейсом, с частотой передачи информации 8МГц. Логические «0» и «1» кодируются скважностью передаваемых импульсов:
После окончания передачи данных на линии должно быть выставлено состояние RET. После прошествия Treset времени в таком состоянии светодиод изменит свой цвет на последний полученный.
Цвет передаётся в формате 24bit GRB:
Задачи:
Напишите прошивку, которая способна зажечь светодиод одним постоянным цветом. Цвет может быть жёстко зашит в последовательность команд на передачу данных. Просто чтобы убедиться, что мы умеем передавать данные.
Модифицируйте прошивку так, чтобы цвет для отправки на диод брался из трёх регистров общего назначения.
Модифицируйте прошивку так, чтобы создавалась небольшая анимация. Как минимум последовательное переключение цветов: красный, зелёный, синий, белый. Как максимум можно перебрать полный спектр цветов RGB и сделать радугу.
Приложение. Листинг кода.
#include <avr/io.h>
#define F_CPU 8000000ul
#include <util/delay.h>
#include <avr/interrupt.h>
#define LED_Count 4
#define Color_Count 3
uint8_t Red = 0xFF;
uint8_t Blue = 0;
uint8_t Green = 0;
uint8_t Phase = 0;
void send_1(){ // Отправка 1
PORTA = (1 << PORTA6); // HIGH сигнал
asm __volatile__("nop;\n nop;\n nop;\n nop;"); // Ожидание 4 такта
PORTA = 0; // LOW сигнал
asm __volatile__("nop;"); // Ожидание 1 такт
}
void send_0(){ // Отправка 0
PORTA = (1 << PORTA6); // HIGH сигнал
asm __volatile__("nop;"); // Ожидание 1 такт
PORTA = 0; // LOW сигнал
asm __volatile__("nop;\n nop;\n nop;\n nop;"); // Ожидание 4 такта
}
void send_color(uint8_t color) // Сравнение битов в коде цвета
{
for (uint8_t i = 0; i < 8 ; i++) // Перебор битов
{
if (color & (1 << 7)) //Если последний бит 1
{
send_1(); // Отправляем 1
}
else
{
send_0(); // Иначе отправляем ноль
}
color <<= 1; // Сдвигаем вправо код цвета
}
}
void send_data(){ // Отправка данных на диоды
for (uint8_t i = 0; i < LED_Count; i++) // Для каждого из диодов
{
send_color(Green); // Зелёный цвет
send_color(Red); // Красный цвет
send_color(Blue); // Синий цвет
}
_delay_us(60); // Пауза, что закончили передачу
}
int main(void)
{
// Инициализация пинов
DDRA |= (1 << DDRA6); // Пин А6 - выход
PORTA &= ~(1 << PORTA6); // На выходе по умолчанию 0
// Настройки ядра
CCP = 0xD8; // Разблокируем настройки процессора
CLKPSR = 0; // Предделитель процессора 0
while (1)
{
for(uint8_t i = 0; i < LED_Count; i++) // инициализация диодов
{
switch (Phase){ // Проверяем фазу
case 0: // Красный -> Оранжевый -> Жёлтый
if(Green == 0xFF){ //Проверяем верх
Phase++; //Если достигли - след. фаза
}
else{ // Иначе - ВСЁ НА ЗЕЛЁНОЕ!
Green++;
}
break;
case 1: // Жёлтый -> Зелёный
if(Red == 0){ // Тут по аналогии
Phase++; // Но уменьшаем красный
}
else{
Red--;
}
break;
case 2: // Зелёный -> Голубой
if(Blue == 0xFF){
Phase++;
}
else{
Blue++;
}
break;
case 3: // Голубой -> Синий
if(Green == 0){
Phase++;
}
else{
Green--;
}
break;
case 4: // Синий -> Фиолетовый
if(Red == 0xFF){
Phase++;
}
else{
Red++;
}
break;
case 5: // Фиолетовый -> Красный
if(Blue == 0){ // Сбрасываем фазу
Phase = 0; // т.к. она последняя
}
else{
Blue--;
}
break;
}
}
send_data();
_delay_ms(5);
}
}
