| Форум РадиоКот https://radiokot.ru/forum/ |
|
| ws2812b не плавное переключение цветов https://radiokot.ru/forum/viewtopic.php?f=59&t=192443 |
Страница 1 из 2 |
| Автор: | mab72 [ Вт фев 27, 2024 19:58:14 ] |
| Заголовок сообщения: | ws2812b не плавное переключение цветов |
stm32g431cbu6 платка от weact studio + ws2812b перепробовал тучу кода из инета, даже свой накарябал. Всеравно при перетекании из одного цвета в соседний в определенных местах происходит резкое изменение цвета (как прикрепить видео не знаю). Подскажите в какую сторону копать, МК кроме как переводом HSV в RGB и отправкой этого в таймер ничего больше не делает. |
|
| Автор: | Martian [ Вт фев 27, 2024 20:10:05 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
в коде в строке 159 ошибка |
|
| Автор: | mab72 [ Вт фев 27, 2024 20:47:58 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
окай, а так Спойлер#include "main.h"#include "math.h" //---------- #define TIM17_ARR 209 //168000000 : 800000 = 210 #define T0 (TIM17_ARR/3) #define T1 ((TIM17_ARR/3)*2) //---------- __IO static uint8_t pwm_buf[] = {T0, T0, T1, T0, 0}; __IO static uint8_t buf[25] = {0}; __IO static uint8_t g_buf[] = {T1, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, 0}; __IO static uint8_t r_buf[] = {T0, T0, T0, T0, T0, T0, T0, T0, T1, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, 0}; __IO static uint8_t b_buf[] = {T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T0, T1, T0, T0, T0, T0, T0, T0, T0, 0}; typedef struct { uint8_t r; uint8_t g; uint8_t b; } RGB_t; typedef struct { uint16_t h; uint8_t s; uint8_t v; } HSV_t; typedef struct { int h; int s; int v; } HSV_v2_t; typedef struct { uint16_t h; uint8_t s; uint8_t v; } HSV_v3_t; static const uint8_t max_whiteness = 15; //static const uint8_t max_value = 17; static const uint8_t sixth_hue = 16; static const uint8_t third_hue = sixth_hue * 2; static const uint8_t half_hue = sixth_hue * 3; static const uint8_t two_thirds_hue = sixth_hue * 4; static const uint8_t five_sixths_hue = sixth_hue * 5; static const uint8_t full_hue = sixth_hue * 6; //static const RGB_t black = {0, 0, 0}; static HSV_t _hsv = {0, 0, 0}; static RGB_t _rgb = {0, 0, 0}; //static uint8_t rgb_v2[3]={0, 0, 0}; static HSV_v2_t _hsv_v2 = {0, 0, 0}; static HSV_v3_t _hsv_v3 = {0, 0, 0}; static const uint8_t dim_curve[256] = { 0, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 16, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 21, 21, 22, 22, 22, 23, 23, 24, 24, 25, 25, 25, 26, 26, 27, 27, 28, 28, 29, 29, 30, 30, 31, 32, 32, 33, 33, 34, 35, 35, 36, 36, 37, 38, 38, 39, 40, 40, 41, 42, 43, 43, 44, 45, 46, 47, 48, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 78, 79, 81, 82, 83, 85, 86, 88, 90, 91, 93, 94, 96, 98, 99, 101, 103, 105, 107, 109, 110, 112, 114, 116, 118, 121, 123, 125, 127, 129, 132, 134, 136, 139, 141, 144, 146, 149, 151, 154, 157, 159, 162, 165, 168, 171, 174, 177, 180, 183, 186, 190, 193, 196, 200, 203, 207, 211, 214, 218, 222, 226, 230, 234, 238, 242, 248, 255, }; static uint8_t status = 0; //---------- void led_brd_ini(void); void rcc_ini(void); void tim_pwm_ini(void); //inline RGB_t rgb(uint8_t r, uint8_t g, uint8_t b) { // return (RGB_t) {r, g, b}; //} //inline HSV_t hsv(uint8_t h, uint8_t s, uint8_t v) { // return (HSV_t) {h, s, v}; //} void rgb2buf(RGB_t grb); void hsv2rgb(HSV_t hsv); void hsv2rgb_v2(int hue, int sat, int val, uint8_t * colors); void hsv2rgb_v3(HSV_v3_t hsv); void hsv2rgb_my(HSV_v3_t hsv); void arhiv(void); void DMA1_Channel1_IRQHandler(void); //---------- int main(void) { led_brd_ini(); rcc_ini(); tim_pwm_ini(); _hsv.h = 0; _hsv.s = 255; _hsv.v = 255; _hsv_v2.h = 0; _hsv_v2.s = 255; _hsv_v2.v = 255; _hsv_v3.h = 0; _hsv_v3.s = 255; _hsv_v3.v = 255; while(1) { hsv2rgb_my(_hsv_v3); //hsv2rgb_my(_hsv_v2); //hsv2rgb(_hsv); rgb2buf(_rgb); DMA1_Channel1->CCR &= ~DMA_CCR_EN; DMA1_Channel1->CPAR = (uint32_t)(&TIM17->CCR1); DMA1_Channel1->CMAR = (uint32_t)(buf); DMA1_Channel1->CNDTR = 25; DMA1_Channel1->CCR |= DMA_CCR_EN; for(__IO uint32_t i=0; i<2000000; i++) { } if(_hsv_v3.h<359) _hsv_v3.h++; else _hsv_v3.h = 0; } } //---------- MAIN //---------- //---------- //---------- //---------- //---------- void DMA1_Channel1_IRQHandler(void) { if(((DMA1->ISR) & DMA_ISR_TCIF1) == DMA_ISR_TCIF1) { DMA1->IFCR = DMA_IFCR_CTCIF1; status = 0; } } //---------- void arhiv(void) { } //---------- void hsv2rgb_my(HSV_v3_t hsv) { int hue = (int)(hsv.h); double val = (double)(hsv.v); // float sat = (float)(hsv.s); double r = 0; double g = 0; double b = 0; int sector = (hue / 60) % 6; switch(sector) { case 0: r = (double)val; g = (((double)(hue) * (double)4.325) / (double)255) * (double)val; b = 0; break; case 1: r = (double)255 - (((((double)hue - (double)60) * (double)4.325) / (double)255) * (double)val); g = (double)val; b = 0; break; case 2: r = 0; g = (double)val; b = ((((double)hue - (double)120) * (double)4.325) / (double)255) * (double)val; break; case 3: r = 0; g = (double)255 - (((((double)hue - (double)180) * (double)4.325) / (double)255) * (double)val); b = (double)val; break; case 4: r = ((((double)hue - (double)240) * (double)4.325) / (double)255) * (double)val; g = 0; b = (double)val; break; case 5: r = (double)val; g = 0; b = (double)255 - (((((double)hue - (double)300) * (double)4.325) / (double)255) * (double)val); break; } _rgb.r = (uint8_t)(round(r)); _rgb.g = (uint8_t)(round(g)); _rgb.b = (uint8_t)(round(b)); } //---------- void hsv2rgb_v3(HSV_v3_t hsv) { //int qdrt=(hsv.v - (255 - hsv.s)); //if(hsv.v<hsv.s) hsv.s=hsv.v; if((hsv.h>=0)&&(hsv.h<60)) { _rgb.r = hsv.v; _rgb.b = 255-hsv.s; _rgb.g = (uint8_t)(((hsv.v - (255 - hsv.s))/60)*hsv.h); } else if((hsv.h>59)&&(hsv.h<120)) { _rgb.g = hsv.v; _rgb.b = 0; _rgb.r = (uint8_t)(hsv.v-(((hsv.v - (255 - hsv.s))/60)*(hsv.h-60))); } } //---------- void hsv2rgb_v2(int hue, int sat, int val, uint8_t * colors) { int base; if (sat == 0) { // Achromatic color (gray). colors[0] = (uint8_t)val; colors[1] = (uint8_t)val; colors[2] = (uint8_t)val; } else { base = ((255 - sat) * val) >> 8; switch (hue / 60) { case 0: colors[0] = (uint8_t)val; colors[1] = (uint8_t)((((val - base) * hue) / 60) + base); colors[2] = (uint8_t)base; break; case 1: colors[0] = (uint8_t)((((val - base) * (60 - (hue % 60))) / 60) + base); colors[1] = (uint8_t)val; colors[2] = (uint8_t)base; break; case 2: colors[0] = (uint8_t)base; colors[1] = (uint8_t)val; colors[2] = (uint8_t)((((val - base) * (hue % 60)) / 60) + base); break; case 3: colors[0] = (uint8_t)base; colors[1] = (uint8_t)((((val - base) * (60 - (hue % 60))) / 60) + base); colors[2] = (uint8_t)val; break; case 4: colors[0] = (uint8_t)((((val - base) * (hue % 60)) / 60) + base); colors[1] = (uint8_t)base; colors[2] = (uint8_t)val; break; case 5: colors[0] = (uint8_t)val; colors[1] = (uint8_t)base; colors[2] = (uint8_t)((((val - base) * (60 - (hue % 60))) / 60) + base); break; } } } //---------- void rgb2buf(RGB_t grb) { for(__IO uint8_t i=0; i<8; i++) { if((grb.g & (0x80>>i)) == 0) buf[i] = T0; else buf[i] = T1; if((grb.r & (0x80>>i)) == 0) buf[i+8] = T0; else buf[i+8] = T1; if((grb.b & (0x80>>i)) == 0) buf[i+16] = T0; else buf[i+16] = T1; } } //---------- void hsv2rgb(HSV_t hsv) { uint8_t high = hsv.v * max_whiteness; uint8_t W; uint8_t low; uint8_t rising; uint8_t falling; uint8_t h_after_sixth; uint8_t z; uint16_t H; //if(hsv.v == 0) return black; //if(hsv.s == 0) return rgb(high, high, high); W = max_whiteness - hsv.s; low = hsv.v * W; rising = low; falling = high; h_after_sixth = hsv.h % sixth_hue; if (h_after_sixth > 0) {//not at primary color? ok, h_after_sixth = 1..sixth_hue - 1 z = hsv.s * (uint8_t)(hsv.v * h_after_sixth) / sixth_hue; rising += z; falling -= z + 1;//it's never 255, so ok } H = hsv.h; while (H >= full_hue) H -= full_hue; if (H < sixth_hue) {_rgb.r=high; _rgb.g=rising; _rgb.b=low;} else if (H < third_hue) {_rgb.r=falling; _rgb.g=high; _rgb.b=low;} else if (H < half_hue) {_rgb.r=low; _rgb.g=high; _rgb.b=rising;} else if (H < two_thirds_hue) {_rgb.r=low; _rgb.g=falling; _rgb.b=high;} else if (H < five_sixths_hue) {_rgb.r=rising; _rgb.g=low; _rgb.b=high;} else {_rgb.r=high; _rgb.g=low; _rgb.b=falling;} //return buf_1(high, low, falling); } //---------- void tim_pwm_ini(void) { /* PB9 AF1 is TIM17 channel_1 */ //Clk PB9 RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; MODIFY_REG(GPIOB->MODER, GPIO_MODER_MODE9, GPIO_MODER_MODE9_1); GPIOB->OTYPER &= ~GPIO_OTYPER_OT9; GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD9; GPIOB->AFR[1] |= (1<<1*4); //Clk TIM17 RCC->APB2ENR |= RCC_APB2ENR_TIM17EN; TIM17->CR1 |= TIM_CR1_ARPE; //preload enable MODIFY_REG(TIM17->CCMR1, TIM_CCMR1_OC1M, TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 //PWM mode | TIM_CCMR1_OC1PE //CCR preload enable ); TIM17->CCER |= TIM_CCER_CC1E; //channel 1 output is enable TIM17->BDTR |= TIM_BDTR_MOE; TIM17->ARR = 209; //168000000:800000=210 TIM17->CCR1 = 0; //((TIM17->ARR)/3); TIM17->DIER |= TIM_DIER_CC1DE; TIM17->DIER |= TIM_DIER_UDE; TIM17->CR1 |= TIM_CR1_CEN; //Clk DMA1 enable RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; DMA1_Channel1->CCR &= ~DMA_CCR_EN; MODIFY_REG(DMA1_Channel1->CCR, DMA_CCR_MEM2MEM | DMA_CCR_MSIZE | DMA_CCR_PSIZE | DMA_CCR_PINC, DMA_CCR_MINC | DMA_CCR_PSIZE_0 | DMA_CCR_DIR //| DMA_CCR_TCIE //| DMA_CCR_CIRC ); //DMA1_Channel1->CPAR = (uint32_t)(&TIM17->CCR1); //DMA1_Channel1->CMAR = (uint32_t)(pwm_buf); //DMA1_Channel1->CNDTR = 5; //NVIC_EnableIRQ(DMA1_Channel1_IRQn); RCC->AHB1ENR |= RCC_AHB1ENR_DMAMUX1EN; DMAMUX1_Channel0->CCR = (84<<DMAMUX_CxCR_DMAREQ_ID_Pos); //DMA1_Channel1->CCR |= DMA_CCR_EN; } //---------- void rcc_ini(void) { MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_4WS); while(((FLASH->ACR) & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS) { } CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE); SET_BIT(RCC->CR, RCC_CR_HSEON); while(((RCC->CR) & RCC_CR_HSEON) == 0) { } MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLR, RCC_PLLCFGR_PLLSRC_HSE | (42 << RCC_PLLCFGR_PLLN_Pos)); SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLREN); SET_BIT(RCC->CR, RCC_CR_PLLON); while(((RCC->CR) & RCC_CR_PLLRDY) != RCC_CR_PLLRDY) { } MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL); MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_CFGR_HPRE_DIV2); while(((RCC->CFGR) & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) { } for (__IO uint32_t i = (170 >> 1); i !=0; i--); MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_CFGR_HPRE_DIV1); MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_CFGR_PPRE1_DIV1); MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_CFGR_PPRE2_DIV1); /* Configure the SysTick to have interrupt in 1ms time base */ SysTick->LOAD = (uint32_t)((168000000 / 1000) - 1UL); /* set reload register */ SysTick->VAL = 0UL; /* Load the SysTick Counter Value */ SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk; /* Enable the Systick Timer */ SystemCoreClock = 168000000; } //---------- void led_brd_ini(void) { RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN; MODIFY_REG(GPIOC->MODER, GPIO_MODER_MODE6, GPIO_MODER_MODE6_0); GPIOC->OTYPER &= ~GPIO_OTYPER_OT6; GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6; MODIFY_REG(GPIOC->PUPDR, GPIO_PUPDR_PUPD6, GPIO_PUPDR_PUPD6_1); GPIOC->BSRR = GPIO_BSRR_BR6; } //---------- |
|
| Автор: | >TEHb< [ Ср фев 28, 2024 12:49:19 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Может быть времени на обсчёт или на отправку не хватает. Стоит попробовать увеличить то или другое искусственными задержками. |
|
| Автор: | GARMIN [ Ср фев 28, 2024 14:28:09 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Даблами считать восьмибитные цвета. Это очень круто. |
|
| Автор: | Martian [ Ср фев 28, 2024 17:54:44 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
флоатами точность падает, не те оттенки |
|
| Автор: | GARMIN [ Чт фев 29, 2024 09:04:14 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
У меня вот так: СпойлерКод: void hsv_2_rgb (hsv_t *hsv, rgb_t *rgb) { s32 h = hsv->h; u32 s = hsv->s; u32 v = hsv->v; u8 i; u8 a, b, c; u32 dh; if (s == 0) { rgb->r = v; rgb->g = v; rgb->b = v; return; } if (h < 0) { h = h + 360 + (360 * (-h % 360)); } if (h >= 360) { h = h % 360; } i = h / 60; dh = (255 * (h % 60)) / 60; // 0..255 a = (v * (dh + (((255 - dh) * (255 - s)) / 255))) / 255; b = (v * (255 - s)) / 255; c = (v * ((255 - dh) + (dh * (255 - s) / 255))) / 255; switch (i) { case 0: rgb->r = v; rgb->g = a; rgb->b = b; break; case 1: rgb->r = c; rgb->g = v; rgb->b = b; break; case 2: rgb->r = b; rgb->g = v; rgb->b = a; break; case 3: rgb->r = b; rgb->g = c; rgb->b = v; break; case 4: rgb->r = a; rgb->g = b; rgb->b = v; break; case 5: default: rgb->r = v; rgb->g = b; rgb->b = c; break; } } |
|
| Автор: | Martian [ Чт фев 29, 2024 09:07:45 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
не лучше ли /255 заменить на сдвиг ? |
|
| Автор: | GARMIN [ Пт мар 01, 2024 20:56:55 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
не лучше ли /255 заменить на сдвиг ? Сдвиг поделит на 256, а это ИМХО неправильно. |
|
| Автор: | mab72 [ Сб мар 02, 2024 09:03:46 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Может быть времени на обсчёт или на отправку не хватает. Стоит попробовать увеличить то или другое искусственными задержками. увеличил время паузы между изменением h++, все замечательно . Красиво переливается из одного в другой цвет. Морганий нет. Как доберусь до лаборатории буду колдовать с прерываниями от DMA и таймера. |
|
| Автор: | GARMIN [ Вт мар 05, 2024 19:19:03 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
mab72, обязательно проверь изменение насыщенности от белого к красному, розовому и слегка фиолетовому. Все HSV, которые я нашёл в интернете, здесь лагают, и мне пришлось делать свой вариант, который я выложил. |
|
| Автор: | mab72 [ Пт мар 15, 2024 13:48:35 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
mab72, обязательно проверь... Как будет время (очень много работы) обязательно гляну. |
|
| Автор: | mab72 [ Пт мар 22, 2024 15:25:44 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
mab72, обязательно проверь... Улучил минутку. Попробывал твой код. При переходе от синего в фиолетовый(красный) заметное дрожжание цвета и также дрожжит от красного к желтому. Капец, ну шо еще надо-та?! Кто нибудь поможите. |
|
| Автор: | >TEHb< [ Пт мар 22, 2024 15:31:04 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Небольшая заметка про оценку загруженности микроконтроллера. |
|
| Автор: | mab72 [ Пт мар 22, 2024 21:30:35 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Хм... заинтриговал. Пойду попробую. Расставлю маркеры и ЛА гляну шо к чему. |
|
| Автор: | jcxz [ Вс мар 24, 2024 15:13:57 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
окай, а так Мрак, ужас. Даблы для управления лампочками??? Это шутка? Переменные в ISR без volatile? Какие-то бессмысленные задержки: for(__IO uint32_t i=0; i<2000000; i++) {} ... Куча magic numbers... Дальше можно не смотреть. Всё переписать с нуля. |
|
| Автор: | mab72 [ Ср мар 27, 2024 20:43:35 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
окай, а так Мрак, ужас. Даблы для управления лампочками??? Это шутка? Переменные в ISR без volatile? Какие-то бессмысленные задержки: for(__IO uint32_t i=0; i<2000000; i++) {} ... Куча magic numbers... Дальше можно не смотреть. Всё переписать с нуля. Пугающий всех тип double поубирал, переменные в ISR "заволатайлил" (если я правильно понял этот пункт), задержку на переключение/изменение цвета оформил на SysTick и magic numbers поудалял. Перерисовал код, ну не с нуля, но я старался. Проблема осталась на синем и желтом цветах - заметное мерцание/дрожь. Спойлер#include "main.h"//---------- #define TIM17_ARR 209 //168000000 : 800000 = 210 #define T0 (TIM17_ARR/3) #define T1 ((TIM17_ARR/3)*2) #define NO_BSY 0 #define BSY 1 //---------- __IO static uint32_t del_ms = 0; static uint8_t buf[25] = {0}; typedef struct { uint8_t r; uint8_t g; uint8_t b; } RGB_t; typedef struct { uint16_t h; uint8_t s; uint8_t v; } HSV_t; __IO static uint8_t status = NO_BSY; static HSV_t my_hsv; static RGB_t my_rgb; //---------- void led_brd_ini(void); void rcc_ini(void); void tim_pwm_ini(void); void rgb2buf(RGB_t grb); void hsv_2_rgb_v4(HSV_t *hsv, RGB_t *rgb); void DMA1_Channel1_IRQHandler(void); void SysTick_Handler(void); void pausa_50(void); void delay_ms(__IO uint32_t del); //---------- int main(void) { led_brd_ini(); rcc_ini(); tim_pwm_ini(); my_hsv.h = 0; my_hsv.s = 255; my_hsv.v = 255; my_rgb.r = 0; my_rgb.g = 0; my_rgb.b = 0; while(1) { if(status == NO_BSY) { hsv_2_rgb_v4(&my_hsv, &my_rgb); rgb2buf(my_rgb); DMA1_Channel1->CCR &= ~DMA_CCR_EN; DMA1_Channel1->CPAR = (uint32_t)(&TIM17->CCR1); DMA1_Channel1->CMAR = (uint32_t)(buf); DMA1_Channel1->CNDTR = 25; DMA1_Channel1->CCR |= DMA_CCR_MINC; status = BSY; DMA1_Channel1->CCR |= DMA_CCR_EN; while(status != 0) { } pausa_50(); while(status != 0) { } if(my_hsv.h<359) my_hsv.h++; else my_hsv.h = 0; } delay_ms(100); } } //---------- MAIN //---------- //---------- //---------- void hsv_2_rgb_v4(HSV_t *hsv, RGB_t *rgb) { uint16_t h = hsv->h; uint8_t s = hsv->s; uint8_t v = hsv->v; uint8_t i; uint8_t a, b, c; uint32_t dh; if (s == 0) { rgb->r = v; rgb->g = v; rgb->b = v; return; } i = (uint8_t)(h / 60); dh = (uint32_t)((255 * (h % 60)) / 60); // 0..255 a = (uint8_t)((v * (dh + (((255 - dh) * (255 - s)) / 255))) / 255); b = (v * (255 - s)) / 255; c = (uint8_t)((v * ((255 - dh) + (dh * (255 - s) / 255))) / 255); switch (i) { case 0: rgb->r = v; rgb->g = a; rgb->b = b; break; case 1: rgb->r = c; rgb->g = v; rgb->b = b; break; case 2: rgb->r = b; rgb->g = v; rgb->b = a; break; case 3: rgb->r = b; rgb->g = c; rgb->b = v; break; case 4: rgb->r = a; rgb->g = b; rgb->b = v; break; case 5: default: rgb->r = v; rgb->g = b; rgb->b = c; break; } } //---------- void pausa_50(void) { uint8_t tmp = 0; DMA1_Channel1->CCR &= ~DMA_CCR_EN; DMA1_Channel1->CPAR = (uint32_t)(&TIM17->CCR1); DMA1_Channel1->CMAR = (uint32_t)(&tmp); DMA1_Channel1->CNDTR = 40; DMA1_Channel1->CCR &= ~DMA_CCR_MINC; status = 1; DMA1_Channel1->CCR |= DMA_CCR_EN; } //---------- void rgb2buf(RGB_t grb) { for(__IO uint8_t i=0; i<8; i++) { if((grb.g & (0x80>>i)) == 0) buf[i] = T0; else buf[i] = T1; if((grb.r & (0x80>>i)) == 0) buf[i+8] = T0; else buf[i+8] = T1; if((grb.b & (0x80>>i)) == 0) buf[i+16] = T0; else buf[i+16] = T1; } } //---------- void tim_pwm_ini(void) { /* PB9 AF1 is TIM17 channel_1 */ //Clk PB9 RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN; MODIFY_REG(GPIOB->MODER, GPIO_MODER_MODE9, GPIO_MODER_MODE9_1); GPIOB->OTYPER &= ~GPIO_OTYPER_OT9; GPIOB->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR9; GPIOB->PUPDR &= ~GPIO_PUPDR_PUPD9; GPIOB->AFR[1] |= (1<<1*4); //Clk TIM17 RCC->APB2ENR |= RCC_APB2ENR_TIM17EN; TIM17->CR1 |= TIM_CR1_ARPE; //preload enable MODIFY_REG(TIM17->CCMR1, TIM_CCMR1_OC1M, TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 //PWM mode | TIM_CCMR1_OC1PE //CCR preload enable ); TIM17->CCER |= TIM_CCER_CC1E; //channel 1 output is enable TIM17->BDTR |= TIM_BDTR_MOE; TIM17->ARR = 209; //168000000:800000=210 TIM17->CCR1 = 0; //((TIM17->ARR)/3); TIM17->DIER |= TIM_DIER_CC1DE; TIM17->DIER |= TIM_DIER_UDE; TIM17->CR1 |= TIM_CR1_CEN; //Clk DMA1 enable RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN; DMA1_Channel1->CCR &= ~DMA_CCR_EN; MODIFY_REG(DMA1_Channel1->CCR, DMA_CCR_MEM2MEM | DMA_CCR_MSIZE | DMA_CCR_PSIZE | DMA_CCR_PINC, DMA_CCR_MINC | DMA_CCR_PSIZE_0 | DMA_CCR_DIR | DMA_CCR_TCIE ); NVIC_EnableIRQ(DMA1_Channel1_IRQn); RCC->AHB1ENR |= RCC_AHB1ENR_DMAMUX1EN; DMAMUX1_Channel0->CCR = (84<<DMAMUX_CxCR_DMAREQ_ID_Pos); } //---------- void rcc_ini(void) { MODIFY_REG(FLASH->ACR, FLASH_ACR_LATENCY, FLASH_ACR_LATENCY_4WS); while(((FLASH->ACR) & FLASH_ACR_LATENCY) != FLASH_ACR_LATENCY_4WS) { } CLEAR_BIT(PWR->CR5, PWR_CR5_R1MODE); SET_BIT(RCC->CR, RCC_CR_HSEON); while(((RCC->CR) & RCC_CR_HSEON) == 0) { } MODIFY_REG(RCC->PLLCFGR, RCC_PLLCFGR_PLLSRC | RCC_PLLCFGR_PLLM | RCC_PLLCFGR_PLLN | RCC_PLLCFGR_PLLR, RCC_PLLCFGR_PLLSRC_HSE | (42 << RCC_PLLCFGR_PLLN_Pos)); SET_BIT(RCC->PLLCFGR, RCC_PLLCFGR_PLLREN); SET_BIT(RCC->CR, RCC_CR_PLLON); while(((RCC->CR) & RCC_CR_PLLRDY) != RCC_CR_PLLRDY) { } MODIFY_REG(RCC->CFGR, RCC_CFGR_SW, RCC_CFGR_SW_PLL); MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_CFGR_HPRE_DIV2); while(((RCC->CFGR) & RCC_CFGR_SWS) != RCC_CFGR_SWS_PLL) { } for (__IO uint32_t i = (170 >> 1); i !=0; i--); MODIFY_REG(RCC->CFGR, RCC_CFGR_HPRE, RCC_CFGR_HPRE_DIV1); MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE1, RCC_CFGR_PPRE1_DIV1); MODIFY_REG(RCC->CFGR, RCC_CFGR_PPRE2, RCC_CFGR_PPRE2_DIV1); SystemCoreClock = 168000000; SysTick_Config(SystemCoreClock/1000U); } //---------- void led_brd_ini(void) { RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN; MODIFY_REG(GPIOC->MODER, GPIO_MODER_MODE6, GPIO_MODER_MODE6_0); GPIOC->OTYPER &= ~GPIO_OTYPER_OT6; GPIOC->OSPEEDR |= GPIO_OSPEEDER_OSPEEDR6; MODIFY_REG(GPIOC->PUPDR, GPIO_PUPDR_PUPD6, GPIO_PUPDR_PUPD6_1); GPIOC->BSRR = GPIO_BSRR_BR6; } //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- //---------- void delay_ms(__IO uint32_t del) { del_ms = del; while(del_ms) { } } //---------- void SysTick_Handler(void) { if(del_ms>0) del_ms--; } //---------- void DMA1_Channel1_IRQHandler(void) { if(((DMA1->ISR) & DMA_ISR_TCIF1) == DMA_ISR_TCIF1) { DMA1->IFCR = DMA_IFCR_CTCIF1; status = NO_BSY; TIM17->CCR1 = 0; } } //---------- |
|
| Автор: | GARMIN [ Чт мар 28, 2024 21:13:43 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Не знаю. Где тут мерцание? Смотри с 0:30 Может дело в чём-то другом? |
|
| Автор: | mab72 [ Чт мар 28, 2024 22:33:09 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Не знаю... Если не секрет, функцию преобразования HSV в RGB можно глянуть? И да , какой МК использован? |
|
| Автор: | GARMIN [ Пт мар 29, 2024 20:38:44 ] |
| Заголовок сообщения: | Re: ws2812b не плавное переключение цветов |
Так я её показал выше, тебе не было интересно. Микроконтроллеры самые разные, STM32F051, 071, GD32... |
|
| Страница 1 из 2 | Часовой пояс: UTC + 3 часа |
| Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group http://www.phpbb.com/ |
|


