В предыдущей части урока мы познакомились с лентами на 150 светодиодов, подготовили блок питания для них, соединили нашу схему и произвели её первоначальную проверку.
Перейдём в файл ws2812.h и изменим в макросе количество светодиодов
#define LED_COUNT 150
Только это ещё далеко не всё.
Перейдём в файл ws2812.c и также добавим размер временного буфера
uint8_t rgb_temp[15][3];
Теперь у нас в каждой группе будет не по 12, а по 15 светодиодов. В каждой ленте таких будет по 10 групп, так как на 12 число 150 не делится.
Функцию ws2812_prepareValue мы также перепишем, так как количество в цикле и количество циклов у нас изменилось
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
void ws2812_prepareValue (uint8_t r00, uint8_t g00, uint8_t b00, uint8_t r01, uint8_t g01, uint8_t b01, uint8_t r02, uint8_t g02, uint8_t b02, uint8_t r03, uint8_t g03, uint8_t b03, uint8_t r04, uint8_t g04, uint8_t b04, uint8_t r05, uint8_t g05, uint8_t b05, uint8_t r06, uint8_t g06, uint8_t b06, uint8_t r07, uint8_t g07, uint8_t b07, uint8_t r08, uint8_t g08, uint8_t b08, uint8_t r09, uint8_t g09, uint8_t b09, uint8_t r10, uint8_t g10, uint8_t b10, uint8_t r11, uint8_t g11, uint8_t b11, uint8_t r12, uint8_t g12, uint8_t b12, uint8_t r13, uint8_t g13, uint8_t b13, uint8_t r14, uint8_t g14, uint8_t b14 ) { rgb_temp[0][0]=r00; rgb_temp[0][1]=g00; rgb_temp[0][2]=b00; rgb_temp[1][0]=r01; rgb_temp[1][1]=g01; rgb_temp[1][2]=b01; rgb_temp[2][0]=r02; rgb_temp[2][1]=g02; rgb_temp[2][2]=b02; rgb_temp[3][0]=r03; rgb_temp[3][1]=g03; rgb_temp[3][2]=b03; rgb_temp[4][0]=r04; rgb_temp[4][1]=g04; rgb_temp[4][2]=b04; rgb_temp[5][0]=r05; rgb_temp[5][1]=g05; rgb_temp[5][2]=b05; rgb_temp[6][0]=r06; rgb_temp[6][1]=g06; rgb_temp[6][2]=b06; rgb_temp[7][0]=r07; rgb_temp[7][1]=g07; rgb_temp[7][2]=b07; rgb_temp[8][0]=r08; rgb_temp[8][1]=g08; rgb_temp[8][2]=b08; rgb_temp[9][0]=r09; rgb_temp[9][1]=g09; rgb_temp[9][2]=b09; rgb_temp[10][0]=r10;rgb_temp[10][1]=g10;rgb_temp[10][2]=b10; rgb_temp[11][0]=r11;rgb_temp[11][1]=g11;rgb_temp[11][2]=b11; rgb_temp[12][0]=r12;rgb_temp[12][1]=g12;rgb_temp[12][2]=b12; rgb_temp[13][0]=r13;rgb_temp[13][1]=g13;rgb_temp[13][2]=b13; rgb_temp[14][0]=r14;rgb_temp[14][1]=g14;rgb_temp[14][2]=b14; } |
Перепишем также и прототип в заголовочном файле
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
void ws2812_prepareValue (uint8_t r00, uint8_t g00, uint8_t b00, uint8_t r01, uint8_t g01, uint8_t b01, uint8_t r02, uint8_t g02, uint8_t b02, uint8_t r03, uint8_t g03, uint8_t b03, uint8_t r04, uint8_t g04, uint8_t b04, uint8_t r05, uint8_t g05, uint8_t b05, uint8_t r06, uint8_t g06, uint8_t b06, uint8_t r07, uint8_t g07, uint8_t b07, uint8_t r08, uint8_t g08, uint8_t b08, uint8_t r09, uint8_t g09, uint8_t b09, uint8_t r10, uint8_t g10, uint8_t b10, uint8_t r11, uint8_t g11, uint8_t b11, uint8_t r12, uint8_t g12, uint8_t b12, uint8_t r13, uint8_t g13, uint8_t b13, uint8_t r14, uint8_t g14, uint8_t b14 ); |
Соответственно, в файле main.c в вызове данной функции добавим аргументов с другими цветами, а также заодно увеличим яркость засчёт удвоения остальных аргументов
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
ws2812_prepareValue(255, 0, 0, 0, 255, 0, 0, 0, 255, 128, 128, 0, 0, 128, 128, 128, 0, 128, 192, 64, 0, 192, 0, 64, 64, 192, 0, 0, 192, 64, 0, 64, 192, 64, 0, 192, 192, 32, 32, 32, 32, 192, 32, 192, 32 ); |
К такому же виду приведём вызов данной функции и в функции ws2812_test01 в файле ws2812.c.
И все равно, если сейчас прошить контроллер, то светодиоды последние также не будут светиться.
Чтобы они засветились, исправим функцию ws2812_setValue, добавив в неё несколько строк, а также исправив существующие под схему 10×15
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
void ws2812_setValue(void) { uint8_t n=0; for(n=0;n<10;n++) { ws2812_pixel_rgb_to_buf_dma( rgb_temp[0][0], rgb_temp[0][1], rgb_temp[0][2], n*15); ws2812_pixel_rgb_to_buf_dma( rgb_temp[1][0], rgb_temp[1][1], rgb_temp[1][2], n*15+1); ws2812_pixel_rgb_to_buf_dma( rgb_temp[2][0], rgb_temp[2][1], rgb_temp[2][2], n*15+2); ws2812_pixel_rgb_to_buf_dma( rgb_temp[3][0], rgb_temp[3][1], rgb_temp[3][2], n*15+3); ws2812_pixel_rgb_to_buf_dma( rgb_temp[4][0], rgb_temp[4][1], rgb_temp[4][2], n*15+4); ws2812_pixel_rgb_to_buf_dma( rgb_temp[5][0], rgb_temp[5][1], rgb_temp[5][2], n*15+5); ws2812_pixel_rgb_to_buf_dma( rgb_temp[6][0], rgb_temp[6][1], rgb_temp[6][2], n*15+6); ws2812_pixel_rgb_to_buf_dma( rgb_temp[7][0], rgb_temp[7][1], rgb_temp[7][2], n*15+7); ws2812_pixel_rgb_to_buf_dma( rgb_temp[8][0], rgb_temp[8][1], rgb_temp[8][2], n*15+8); ws2812_pixel_rgb_to_buf_dma( rgb_temp[9][0], rgb_temp[9][1], rgb_temp[9][2], n*15+9); ws2812_pixel_rgb_to_buf_dma(rgb_temp[10][0],rgb_temp[10][1],rgb_temp[10][2],n*15+10); ws2812_pixel_rgb_to_buf_dma(rgb_temp[11][0],rgb_temp[11][1],rgb_temp[11][2],n*15+11); ws2812_pixel_rgb_to_buf_dma(rgb_temp[12][0],rgb_temp[12][1],rgb_temp[12][2],n*15+12); ws2812_pixel_rgb_to_buf_dma(rgb_temp[13][0],rgb_temp[13][1],rgb_temp[13][2],n*15+13); ws2812_pixel_rgb_to_buf_dma(rgb_temp[14][0],rgb_temp[14][1],rgb_temp[14][2],n*15+14); } } |
Вот теперь мы наконец-то соберём код и прошьём контроллер.
Теперь у нас светятся все светодиоды
Теперь перейдём к тестам.
В файле main.c удалим наш добавленный бесконечный цикл, а в основном бесконечном цикле закомментируем все тесты, кроме первого. Займёмся пока им
1 2 3 4 5 6 7 8 9 10 |
ws2812_test01(); //ws2812_test02(); //ws2812_test03(); //ws2812_test04(1); //ws2812_test04(2); //ws2812_test04(3); //ws2812_test04(4); //ws2812_test04(5); //ws2812_test04(6); //ws2812_test05(); |
Если мы сейчас запустим наш код, то светодиоды будут светиться все, так как мы их зажгли с помощью уже исправленной функции, но последние 6 светодиодов бежать не будут, поэтому перейдём в функцию ws2812_test01 в файле ws2812.c.
Первым делом в цикле добавим количество итераций
for(i=0;i<149;i++)
Также цифру с количеством устанавливаемых битов доже прибавим
memcpy((void*)(BUF_DMA+48+3576),(void*)DMA_BUF_TEMP,48);
Соберём код, прошьём контроллер и посмотрим результат.
К сожалению, я не могу в рамках статьи показать красоту бегущих огней, поэтому смотрите видео. А здесь картина получится практически как и предыдущая, единственное, я попробую поймать другой момент, то есть такой, чтобы цвет светодиодов был хотя бы сдвинут
Перейдём в файл main.c, закомментируем первый тест и раскомментируем второй
1 2 |
//ws2812_test01(); ws2812_test02(); |
В дальнейшем мы будем поступать таким образом со всем тестами и я повторяться не буду в том, какой тест мы будем раскоментировать, а какой комментировать. Вернёмся в файл ws2812.c и перейдём в тело функции ws2812_test02.
Здесь изменений будет немного побольше.
Во-первых инициализацию коэффициента в обоих местах мы перенесём на уровень выше, так как переменная i в расчёте коэффициента не используется
1 2 3 4 |
for(j=0;j<32;j++) { k=1000*(32-j)/32; for(i=0;i<144;i++) |
Также в обоих циклах самого нижнего уровня добавим количество итераций
for(i=0;i<150;i++)
Соберём код, прошьём контроллер.
Тест работает, все 150 светодиодов плавно и одновременно мигают
Переходим к следующему тесту — ws2812_test03.
Первым делом прибавим количество итераций также в обоих циклах
for(i=0;i<150;i++)
В обоих условиях меняем интервалы
if
(
(i<15)||((i>=30)&&(i<45))||((i>=60)&&(i<75))||((i>=90)&&(i<105))||((i>=120)&&(i<135))
)
И внутри в обоих циклах меняем делители в делениях по модулю
ws2812_pixel_rgb_to_buf_dma(rgb_temp[i%15][0]*k/1000,rgb_temp[i%15][1]*k/1000,rgb_temp[i%15][2]*k/1000,i);
Прошиваем, смотрим
Переходим к тесту ws2812_test04.
Раскомментируем пока только с единичкой
ws2812_test04(1);
Первым делом в начале теста изменим количество итераций в циклах обоих вложенностей
for(j=0;j<10;j++)
{
for(i=0;i<15;i++)
Ближе к окончанию тела тоже изменим количество итераций в двух циклах
for(jj=0;jj<150;jj++)
{
memcpy((void*)DMA_BUF_TEMP,(void*)(BUF_DMA+48),48);
for(i=0;i<149;i++)
Также изменим ниже количество обрабатываемых битов
memcpy((void*)(BUF_DMA+48+3576),(void*)DMA_BUF_TEMP,48);
Дальше поднимемся выше и займёмся оператором вариантов, а вернее его первым кейсом.
Сначала увеличим порог (можно его увеличить сразу во всех кейсах)
if(i<8)
А затем далее меняем 12 на 15, а 128 на 255
if(i<8)
{rgb_temp[j*15+i][0]=255/((i+1)*2); rgb_temp[j*15+i][1]=0; rgb_temp[j*15+i][2]=0;}
else
{rgb_temp[j*15+i][0]=255/((15-i)*2); rgb_temp[j*15+i][1]=0; rgb_temp[j*15+i][2]=0;}
Попробуем собрать код и прошить контроллер.
Тест отлично работает
В остальных кейсах аналогично 12 заменим на 15, 128 — на 255, 64 — на 128, раскомментируем в main.c вызов 4 теста со всеми аргументами, соберём код, прошьём контроллер и посмотрим результат
Остался ещё один тест — ws2812_test05.
В теле данной функции первым делом добавим количество итераций в цикле
for(i=0;i<150;i++)
В цикле удалим 2 последних условия
if(i%12==10) ws2812_pixel_rgb_to_buf_dma(128*k/3000,128*(1000-k)/667,128*(1000-k)/1000,i);
if(i%12==11) ws2812_pixel_rgb_to_buf_dma(128*(1000-k)/3000,128*k/667,128*(1000-k)/3000,i);
А число 128 везде в цикле заменим на 255, 12 — на 10, а 667 — на 1333
if(i%10==0) ws2812_pixel_rgb_to_buf_dma(255*k/1000,255*(1000-k)/1000,0,i);
if(i%10==1) ws2812_pixel_rgb_to_buf_dma(0,255*k/1000,255*(1000-k)/1000,i);
if(i%10==2) ws2812_pixel_rgb_to_buf_dma(255*k/1000,0,255*(1000-k)/1000,i);
if(i%10==3) ws2812_pixel_rgb_to_buf_dma(255*(1000-k)/1000,255*k/2000,255*k/2000,i);
if(i%10==4) ws2812_pixel_rgb_to_buf_dma(255*k/2000,255*k/2000,255*(1000-k)/1000,i);
if(i%10==5) ws2812_pixel_rgb_to_buf_dma(255*k/2000,255*(1000-k)/1000,255*k/2000,i);
if(i%10==6) ws2812_pixel_rgb_to_buf_dma(255*(1000-k)/2000,255*(1000-k)/2000,255*k/1000,i);
if(i%10==7) ws2812_pixel_rgb_to_buf_dma(255*k/1000,255*(1000-k)/2000,255*(1000-k)/2000,i);
if(i%10==8) ws2812_pixel_rgb_to_buf_dma(255*(1000-k)/2000,255*k/1000,255*(1000-k)/2000,i);
if(i%10==9) ws2812_pixel_rgb_to_buf_dma(255*(1000-k)/3000,255*(1000-k)/1333,255*k/1000,i);
Соберём проект, прошьём контроллер и посмотрим, как красиво теперь переливаются цвета светодиодов
Раскомментируем вызов функций всех тестов и посмотрим ещё раз на все тесты.
Если всё нормально, то пока отключим блок питания от розетки, также отключим программатор от ПК.
В следующей части урока мы изменим код проекта под использование ленты на 300 светодиодов и проверим его на практике.
Предыдущая часть Программирование МК STM32 Следующая часть
Исходный код для ленты на 150 светодиодов
Отладочную плату STM32F103C8T6 можно приобрести здесь STM32F103C8T6
Программатор недорогой можно купить здесь ST-Link V2
Ленты светодиодные WS2812B разные можно приобрести здесь WS2812B
Импульсный источник питания 5 В в 40A 200 Вт можно приобрести здесь 5 В в 40A 200 Вт
Логический анализатор 16 каналов можно приобрести здесь
Смотреть ВИДЕОУРОК в RuTube (нажмите на картинку)
Смотреть ВИДЕОУРОК в YouTube (нажмите на картинку)
Добавить комментарий