查看: 26438|回复: 68

【LPC845月饼板】+ WS2812数字灯亮起来

  [复制链接]
  • TA的每日心情
    奋斗
    14 小时前
  • 签到天数: 2400 天

    连续签到: 109 天

    [LV.Master]伴坛终老

    84

    主题

    2万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    22295
    最后登录
    2025-8-18
    发表于 2022-10-20 18:10:34 | 显示全部楼层 |阅读模式
    本帖最后由 流水源 于 2022-10-20 18:10 编辑

        本期主要展示WS2812数字灯,如何亮起来。

        LPC845月饼板上有12颗WS2812数字灯。下面说说如何把这个灯点亮呢。
    首先简单说明下WS2812灯,他是RGB 3种颜色,每种颜色8Bit,总共24Bit数据。每个Bit的0,1码是按照高低电平占空比来确定的。这个网上资料很多,不过这个0,1码的占空比大小有好几种。
    有的是0码是:H:0.5us,L:2.0us;1码是H:1.2us,L:1.3us。
    有的是0码是:H:0.3us,L:0.9us;1码是H:0.6us,L:0.7us。速度比上面的快1倍。
    还有其他的我就不多说了。

    我就是实现的0码是H:0.3us,L:0.9us;1码是H:0.6us,L:0.7us,这一种情况的。驱动WS2812B常用的方式有SPI、PWM、UASRT、GPIO模拟PWM等方式。本次就是用的SPI模式。使用SPI的mosi引脚驱动WS2812。
    根据WS2812的0,1码的占空比确定SPI输出数据,1字节8Bit。
    WS_BIT1             0x7C                 1码是H:0.6us,L:0.7us
    WS_BIT0             0x60                 0码是H:0.3us,L:0.9us

    根据电路图得到灯的驱动管脚,然后初始化GPIO和SPI。如下图可以看到使用的管脚是PIO1_13。
    0.jpg


    GPIO和SPI初始化如下,参照上一期LCD屏的SPI初始化。
    1. void drv_spi_gpio_init(void)
    2. {
    3.     CLOCK_EnableClock(kCLOCK_Iocon);
    4.     CLOCK_EnableClock(kCLOCK_Gpio0);
    5.     CLOCK_EnableClock(kCLOCK_Gpio1);
    6.    
    7.     CLOCK_EnableClock(kCLOCK_Spi0);
    8.     CLOCK_EnableClock(kCLOCK_Spi1);
    9.    
    10.     CLOCK_Select(kSPI0_Clk_From_MainClk);
    11.     CLOCK_Select(kSPI1_Clk_From_MainClk);
    12.    
    13.     RESET_PeripheralReset(kSPI0_RST_N_SHIFT_RSTn);
    14.     RESET_PeripheralReset(kSPI1_RST_N_SHIFT_RSTn);

    15.     gpio_pin_config_t SPILCD_IN_config = {
    16.         .pinDirection = kGPIO_DigitalInput,
    17.         .outputLogic = 1U,
    18.     };
    19.     gpio_pin_config_t SPILCD_IOH_config = {
    20.         .pinDirection = kGPIO_DigitalOutput,
    21.         .outputLogic = 1U,
    22.     };
    23.     gpio_pin_config_t SPILCD_IOL_config = {
    24.         .pinDirection = kGPIO_DigitalOutput,
    25.         .outputLogic = 0U,
    26.     };
    27.     /* Initialize GPIO functionality on pin */
    28.     GPIO_PinInit(GPIO, 0, 7, &SPILCD_IOL_config);//LCD_BLK
    29.     GPIO_PinInit(GPIO, 1, 6, &SPILCD_IOH_config);//LCD_DC
    30.     GPIO_PinInit(GPIO, 1, 7, &SPILCD_IOH_config);//LCD_RST
    31.     GPIO_PinInit(GPIO, 1,18, &SPILCD_IOH_config);//LCD_CS
    32.     GPIO_PinInit(GPIO, 1,19, &SPILCD_IOH_config);//LCD_CLK
    33.     GPIO_PinInit(GPIO, 0, 6, &SPILCD_IOH_config);//LCD_MOSI
    34.    
    35.     GPIO_PinInit(GPIO, 1,13, &SPILCD_IOH_config);//RGB_MOSI
    36.    
    37.     GPIO_PinInit(GPIO, 1,8, &SPILCD_IOH_config); //FLASH_CS
    38.     GPIO_PinInit(GPIO, 1,9, &SPILCD_IN_config); //FLASH_MISO
    39.     GPIO_PinInit(GPIO, 0,12, &SPILCD_IOH_config);//FLASH_CLK
    40.     GPIO_PinInit(GPIO, 0,13, &SPILCD_IOH_config);//FLASH_MOSI
    41.    
    42.     const uint32_t spilcd_ioc = (/* Selects pull-up function */
    43.                               IOCON_PIO_MODE_PULLUP |
    44.                               /* Enable hysteresis */
    45.                               IOCON_PIO_HYS_EN |
    46.                               /* Input not invert */
    47.                               IOCON_PIO_INV_DI |
    48.                               /* Disables Open-drain function */
    49.                               IOCON_PIO_OD_DI |
    50.                               /* Bypass input filter */
    51.                               IOCON_PIO_SMODE_BYPASS |
    52.                               /* IOCONCLKDIV0 */
    53.                               IOCON_PIO_CLKDIV0);
    54.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_7,  spilcd_ioc);
    55.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_6,  spilcd_ioc);
    56.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_7,  spilcd_ioc);
    57.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_18, spilcd_ioc);   
    58.    
    59.     /* Enables clock for switch matrix.: enable */
    60.     const uint32_t SPI_LCD_CLK = (/* Selects pull-up function */
    61.                                     IOCON_PIO_MODE_PULLUP |
    62.                                     /* Enable hysteresis */
    63.                                     IOCON_PIO_HYS_EN |
    64.                                     /* Input not invert */
    65.                                     IOCON_PIO_INV_DI |
    66.                                     /* Disables Open-drain function */
    67.                                     IOCON_PIO_OD_DI |
    68.                                     /* Bypass input filter */
    69.                                     IOCON_PIO_SMODE_BYPASS |
    70.                                     /* IOCONCLKDIV0 */
    71.                                     IOCON_PIO_CLKDIV0);
    72.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_19, SPI_LCD_CLK);

    73.     const uint32_t SPI_LCD_MOSI = (/* Selects pull-up function */
    74.                                     IOCON_PIO_MODE_PULLUP |
    75.                                     /* Enable hysteresis */
    76.                                     IOCON_PIO_HYS_EN |
    77.                                     /* Input not invert */
    78.                                     IOCON_PIO_INV_DI |
    79.                                     /* Disables Open-drain function */
    80.                                     IOCON_PIO_OD_DI |
    81.                                     /* Bypass input filter */
    82.                                     IOCON_PIO_SMODE_BYPASS |
    83.                                     /* IOCONCLKDIV0 */
    84.                                     IOCON_PIO_CLKDIV0);
    85.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_6, SPI_LCD_MOSI);
    86.    
    87.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_13, SPI_LCD_MOSI);  //RGB_IO=MOSI
    88.    
    89.     const uint32_t SPI_MISO = (/* Selects pull-up function */
    90.                                     0 |
    91.                                     /* Enable hysteresis */
    92.                                     IOCON_PIO_HYS_EN |
    93.                                     /* Input not invert */
    94.                                     IOCON_PIO_INV_DI |
    95.                                     /* Disables Open-drain function */
    96.                                     IOCON_PIO_OD_DI |
    97.                                     /* Bypass input filter */
    98.                                     IOCON_PIO_SMODE_BYPASS |
    99.                                     /* IOCONCLKDIV0 */
    100.                                     IOCON_PIO_CLKDIV0);
    101.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_9, SPI_MISO);   //f_miso

    102.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO1_8,   spilcd_ioc);    //f_cs
    103.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_12,  spilcd_ioc);   //f_clk
    104.     IOCON_PinMuxSet(IOCON, IOCON_INDEX_PIO0_13,  spilcd_ioc);   //f_mosi
    105.    
    106.     CLOCK_EnableClock(kCLOCK_Swm);
    107.    
    108.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI0_SCK,   kSWM_PortPin_P1_19);
    109.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI0_MOSI,  kSWM_PortPin_P0_6);
    110.    
    111.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MOSI,  kSWM_PortPin_P1_13);
    112.    
    113.     /* Disable clock for switch matrix. */
    114.     CLOCK_DisableClock(kCLOCK_Swm);
    115.    
    116.     spi_master_config_t userConfig = {0};
    117.     uint32_t srcFreq               = 0U;
    118.     /* Note: The slave board using interrupt way, slave will spend more time to write data
    119.      *       to TX register, to prevent TX data missing in slave, we will add some delay between
    120.      *       frames and capture data at the second edge, this operation will make the slave
    121.      *       has more time to prapare the data.
    122.      */
    123.    
    124.     SPI_MasterGetDefaultConfig(&userConfig);
    125.     userConfig.baudRate_Bps           = 30000000;
    126.     userConfig.sselNumber             = kSPI_Ssel0Assert;
    127.     userConfig.clockPolarity          = kSPI_ClockPolarityActiveHigh;
    128.     userConfig.clockPhase             = kSPI_ClockPhaseFirstEdge;
    129.     userConfig.direction              = kSPI_MsbFirst;
    130.     userConfig.delayConfig.preDelay   = 0x0U;
    131.     userConfig.delayConfig.postDelay  = 0x0U;
    132.     userConfig.delayConfig.frameDelay = 0x0U;
    133.     userConfig.delayConfig.transferDelay = 0x0U;
    134.     srcFreq                           = CLOCK_GetFreq(kCLOCK_MainClk);
    135.     SPI_MasterInit(SPI0, &userConfig, srcFreq);
    136.    
    137.     userConfig.baudRate_Bps           = 6000000;
    138.     SPI_MasterInit(SPI1, &userConfig, srcFreq);

    139. }




    140. SPI_Type * spi_table[2]=
    141. {
    142.     SPI0,
    143.     SPI1,
    144. };

    145. void spi_pre_h(void)
    146. {
    147.     CLOCK_EnableClock(kCLOCK_Swm);
    148.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MISO,  kSWM_PortPin_P1_9);  //F_MISO
    149.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MOSI,  kSWM_PortPin_P0_13); //F_MOSI
    150.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_SCK ,  kSWM_PortPin_P0_12); //F_CLK
    151.     CLOCK_DisableClock(kCLOCK_Swm);
    152.     SPI_MasterSetBaudRate(SPI1,30000000, CLOCK_GetFreq(kCLOCK_MainClk));
    153. }

    154. void spi_pre_l(void)
    155. {
    156.     CLOCK_EnableClock(kCLOCK_Swm);
    157.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MOSI,  kSWM_PortPin_P1_13); //RGB_IO
    158.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_MISO,  0XFF);  //
    159.     SWM_SetMovablePinSelect(SWM0, kSWM_SPI1_SCK ,  0XFF);  //
    160.     CLOCK_DisableClock(kCLOCK_Swm);
    161.     SPI_MasterSetBaudRate(SPI1,6000000, CLOCK_GetFreq(kCLOCK_MainClk));
    162. }
    复制代码


    ws2812驱动代码如下:
    1. #include "stdint.h"
    2. #include "string.h"
    3. #include "main.h"
    4. #include "drv_ws2812.h"
    5. #include "drv_spi.h"
    6. /*******************************************************************************
    7. * Definitions
    8. ******************************************************************************/
    9. #define WS_TRANSFER_SIZE   (WS2812_PIXELS*24)   // Transfer dataSize

    10. #define WS_BIT              24
    11. #define WS_BIT1             0x7C
    12. #define WS_BIT0             0x60

    13. /*******************************************************************************
    14. * Variables
    15. ******************************************************************************/
    16. volatile uint8_t g_WS2812TxBuf[WS_TRANSFER_SIZE];   // WS2812 Strip transmit data buffer

    17. typedef union WS2812_ARGB
    18. {
    19.     struct
    20.     {
    21.         uint8_t b;
    22.         uint8_t g;
    23.         uint8_t r;
    24.         uint8_t a;
    25.     }s_argb;
    26.     uint32_t u32_rgba;
    27. }WS2812_ARGB_U;

    28. /*
    29. * @brief   WS2812_StripInit
    30. * @param   NULL
    31. * @return  NULL
    32. */
    33. void WS2812_Init(void)
    34. {
    35.     spi_pre_l();
    36.     WS2812_ClearData();
    37.     WS2812_SendData();
    38. }


    39. /*
    40. * @brief   WS2812_PixelSetBuff
    41. * @param   n, LED num / c, color / brightness, brightness
    42. * @return  NULL
    43. */
    44. void WS2812_PixelSetIndexColor(uint16_t n, uint32_t color)
    45. {
    46.     volatile WS2812_ARGB_U l_color;
    47.     uint16_t c_temp;
    48.    
    49.     if(n < WS2812_PIXELS)
    50.     {
    51.         memset((void *)&g_WS2812TxBuf[n*WS_BIT], WS_BIT0, 24);
    52.         l_color.u32_rgba = color;
    53.         c_temp = l_color.s_argb.a + 1;
    54.         l_color.s_argb.r = (l_color.s_argb.r * c_temp) >> 8;
    55.         l_color.s_argb.g = (l_color.s_argb.g * c_temp) >> 8;
    56.         l_color.s_argb.b = (l_color.s_argb.b * c_temp) >> 8;
    57.         
    58.         if( ((l_color.s_argb.g>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+0] = WS_BIT1;
    59.         if( ((l_color.s_argb.g>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+1] = WS_BIT1;
    60.         if( ((l_color.s_argb.g>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+2] = WS_BIT1;
    61.         if( ((l_color.s_argb.g>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+3] = WS_BIT1;
    62.         if( ((l_color.s_argb.g>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+4] = WS_BIT1;
    63.         if( ((l_color.s_argb.g>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+5] = WS_BIT1;
    64.         if( ((l_color.s_argb.g>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+6] = WS_BIT1;
    65.         if( ((l_color.s_argb.g>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+7] = WS_BIT1;
    66.         
    67.         if( ((l_color.s_argb.r>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+0] = WS_BIT1;
    68.         if( ((l_color.s_argb.r>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+1] = WS_BIT1;
    69.         if( ((l_color.s_argb.r>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+2] = WS_BIT1;
    70.         if( ((l_color.s_argb.r>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+3] = WS_BIT1;
    71.         if( ((l_color.s_argb.r>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+4] = WS_BIT1;
    72.         if( ((l_color.s_argb.r>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+5] = WS_BIT1;
    73.         if( ((l_color.s_argb.r>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+6] = WS_BIT1;
    74.         if( ((l_color.s_argb.r>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+7] = WS_BIT1;
    75.         
    76.         if( ((l_color.s_argb.b>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+0] = WS_BIT1;
    77.         if( ((l_color.s_argb.b>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+1] = WS_BIT1;
    78.         if( ((l_color.s_argb.b>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+2] = WS_BIT1;
    79.         if( ((l_color.s_argb.b>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+3] = WS_BIT1;
    80.         if( ((l_color.s_argb.b>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+4] = WS_BIT1;
    81.         if( ((l_color.s_argb.b>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+5] = WS_BIT1;
    82.         if( ((l_color.s_argb.b>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+6] = WS_BIT1;
    83.         if( ((l_color.s_argb.b>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+7] = WS_BIT1;
    84.     }
    85. }

    86. void WS2812_PixelSetIndexRGB(uint16_t n, uint8_t r, uint8_t g, uint8_t b)
    87. {   
    88.     if(n < WS2812_PIXELS)
    89.     {
    90.         memset((void *)&g_WS2812TxBuf[n*WS_BIT], WS_BIT0, 24);

    91.         if( ((g>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+0] = WS_BIT1;
    92.         if( ((g>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+1] = WS_BIT1;
    93.         if( ((g>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+2] = WS_BIT1;
    94.         if( ((g>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+3] = WS_BIT1;
    95.         if( ((g>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+4] = WS_BIT1;
    96.         if( ((g>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+5] = WS_BIT1;
    97.         if( ((g>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+6] = WS_BIT1;
    98.         if( ((g>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 0+7] = WS_BIT1;
    99.         
    100.         if( ((r>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+0] = WS_BIT1;
    101.         if( ((r>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+1] = WS_BIT1;
    102.         if( ((r>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+2] = WS_BIT1;
    103.         if( ((r>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+3] = WS_BIT1;
    104.         if( ((r>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+4] = WS_BIT1;
    105.         if( ((r>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+5] = WS_BIT1;
    106.         if( ((r>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+6] = WS_BIT1;
    107.         if( ((r>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+ 8+7] = WS_BIT1;
    108.         
    109.         if( ((b>>7)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+0] = WS_BIT1;
    110.         if( ((b>>6)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+1] = WS_BIT1;
    111.         if( ((b>>5)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+2] = WS_BIT1;
    112.         if( ((b>>4)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+3] = WS_BIT1;
    113.         if( ((b>>3)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+4] = WS_BIT1;
    114.         if( ((b>>2)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+5] = WS_BIT1;
    115.         if( ((b>>1)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+6] = WS_BIT1;
    116.         if( ((b>>0)&0x01))  g_WS2812TxBuf[n*WS_BIT+16+7] = WS_BIT1;
    117.     }
    118. }
    119. /*
    120. * @brief   strip_clear, clean-up LED strip display
    121. * @param   NULL
    122. * @return  NULL
    123. */
    124. void WS2812_ClearData(void)
    125. {
    126.     memset((void *)&g_WS2812TxBuf[0], WS_BIT0, (WS_TRANSFER_SIZE));//
    127. }

    128. /*
    129. * @brief   color_dim dimme color
    130. * @param   color, number of LEDs
    131. * @return  dimmed color
    132. */
    133. void WS2812_SendData(void)
    134. {
    135.     volatile uint32_t i;
    136.     spi_pre_l();
    137.     for(i=0; i<WS_TRANSFER_SIZE; i++)
    138.     {
    139.         spi_writebyte(1,g_WS2812TxBuf[i]);
    140.     }
    141.     spi_pre_h();
    142. }

    143. void WS2812_ShowRGB(uint8_t r,uint8_t g,uint8_t b)
    144. {
    145.         uint8_t         i;

    146.         for(i=0; i<WS2812_PIXELS; i++)
    147.         {
    148.                 WS2812_PixelSetIndexRGB(i, r,g,b);
    149.         }
    150.     WS2812_SendData();
    151. }

    152. void WS2812_ShowColor(uint32_t color)
    153. {
    154.         uint8_t         i;

    155.         for(i=0; i<WS2812_PIXELS; i++)
    156.         {
    157.                 WS2812_PixelSetIndexColor(i, color);
    158.         }
    159.     WS2812_SendData();
    160. }

    161. void WS2812_ShowBuff(uint8_t *buff)
    162. {
    163.         uint8_t i;
    164.         uint8_t *pLedData = buff;

    165.     for(i=0; i<WS2812_PIXELS; i++)
    166.         {
    167.                 WS2812_PixelSetIndexRGB(i, pLedData[0],pLedData[1],pLedData[2]);
    168.         pLedData += 3;
    169.         }
    170.     WS2812_SendData();
    171. }
    复制代码


    好了,下面就可以开始测试WS2812效果了。
    写了2种效果,一个时钟模式,一个转圈模式
    1. uint8_t clock_color_level[8]=
    2. {
    3.     0x10,
    4.     0x30,
    5.     0x70,
    6.     0xa0,
    7.     0xff,
    8.     0,0,0,
    9. };

    10. uint8_t _hour,_minute,_second;
    11. void ws2812rgb_clock_fsm(fsm_pt_t *pt)
    12. {
    13.     static int i;
    14.     WS2812_ARGB_U rgb;
    15.    
    16.     PT_BEGIN(pt);
    17.    
    18.     _hour = 5;
    19.     _minute = 5;
    20.     _second = 40;
    21.    
    22.     while(1)
    23.     {
    24.         for(i=0;i<12;i++)
    25.         {
    26.             if(_second/5 == i) rgb.s_argb.r = clock_color_level[_second%5];
    27.             else    rgb.s_argb.r = 0;
    28.             
    29.             if(_minute/5 == i) rgb.s_argb.g = clock_color_level[_minute%5];
    30.             else    rgb.s_argb.g = 0;
    31.             
    32.             if(_hour == i)    rgb.s_argb.b = 0xff;
    33.             else rgb.s_argb.b = 0;
    34.             rgb.s_argb.a = rgb_light;
    35.             
    36.             WS2812_PixelSetIndexColor(i,rgb.u32_rgba);
    37.         }
    38.         WS2812_SendData();
    39.         
    40.         PT_WAIT_TIME(pt,1000);  //延时1秒
    41.         
    42.         _second++;
    43.         if(_second == 60)
    44.         {
    45.             _minute ++;
    46.             _second = 0;
    47.             if(_minute == 60)
    48.             {
    49.                 _minute = 0;
    50.                 _hour ++;
    51.                 if(_hour == 12)
    52.                 {
    53.                     _hour = 0;
    54.                 }
    55.             }
    56.         }
    57.     }
    58.     PT_END(pt);
    59. }
    复制代码
    1. void ws2812rgb_demo_fsm(fsm_pt_t *pt)
    2. {
    3.     static int i;
    4.    
    5.     PT_BEGIN(pt);
    6.     while(1)
    7.     {
    8.         for(i=0;i<12;i++)
    9.         {
    10.             WS2812_PixelSetIndexColor(i,WS2812_RED|(rgb_light<<24));
    11.             WS2812_SendData();
    12.             PT_WAIT_TIME(pt,100);
    13.         }
    14.         for(i=0;i<12;i++)
    15.         {
    16.             WS2812_PixelSetIndexColor(i,WS2812_GREEN|(rgb_light<<24));
    17.             WS2812_SendData();
    18.             PT_WAIT_TIME(pt,100);
    19.         }
    20.         for(i=0;i<12;i++)
    21.         {
    22.             WS2812_PixelSetIndexColor(i,WS2812_BLUE|(rgb_light<<24));
    23.             WS2812_SendData();
    24.             PT_WAIT_TIME(pt,100);
    25.         }
    26.     }
    27.     PT_END(pt);
    28. }
    复制代码
    main函数
    1. int main(void)
    2. {
    3.     BOARD_InitBootClocks();
    4.     SysTick_Config(SystemCoreClock / 1000U);
    5.     init_cycle_counter(true);
    6.    
    7.     BOARD_InitBootPins();
    8.     drv_gpio_init();
    9.     BOARD_InitDebugConsole();
    10.    
    11.     drv_spi_gpio_init();
    12.     drv_i2c_gpio_init();
    13.    
    14.     DbgConsole_Printf("LPC845 Mooncake Board Test!\r\n");
    15.    
    16.     spilcd_init();
    17.    
    18.     __cycleof__("lcd_fresh_time(n/30000=X ms):")
    19.     {
    20.         spilcd_fill(0,0,240,240,LCD_RED);
    21.     }
    22.     delay_ms(100);
    23.     __cycleof__("lcd_fresh_time(n/30000=X ms):")
    24.     {
    25.         spilcd_fill(0,0,240,240,LCD_GREEN);
    26.     }
    27.     delay_ms(100);
    28.     __cycleof__("lcd_fresh_time(n/30000=X ms):")
    29.     {
    30.         spilcd_fill(0,0,240,240,LCD_BLUE);
    31.     }
    32.     delay_ms(100);
    33.     __cycleof__("show 40*40 picture time:")
    34.     {
    35.         spilcd_draw_bitmap(100,100,40,40,(uint8_t *)gImage_1);
    36.     }
    37.     delay_ms(100);
    38.         
    39.     rgb_light = 0xff;
    40.     WS2812_Init();
    41.         while(1)
    42.         {
    43.         keyscan_fsm(&pt_key_scan);
    复制代码


    1.jpg
    3.jpg
    2.jpg
    4.jpg

    资料如下:
    lpc845_mooncake.zip (15.77 MB, 下载次数: 12)
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 13:17
  • 签到天数: 1868 天

    连续签到: 2 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112694
    最后登录
    2025-8-17
    发表于 2022-10-21 11:22:49 | 显示全部楼层
    听说这个芯片可以不受限制的随意连线?
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    14 小时前
  • 签到天数: 2400 天

    连续签到: 109 天

    [LV.Master]伴坛终老

    84

    主题

    2万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    22295
    最后登录
    2025-8-18
     楼主| 发表于 2022-10-21 11:33:57 | 显示全部楼层
    stm1024 发表于 2022-10-21 11:22
    听说这个芯片可以不受限制的随意连线?

    对的,基本没限制了
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    擦汗
    2022-2-25 10:20
  • 签到天数: 32 天

    连续签到: 1 天

    [LV.5]常住居民I

    1

    主题

    290

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    1147
    最后登录
    2025-7-2
    发表于 2022-10-21 11:52:58 | 显示全部楼层
    代码贴出来真好,这个圆形的屏哪整的
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    14 小时前
  • 签到天数: 2400 天

    连续签到: 109 天

    [LV.Master]伴坛终老

    84

    主题

    2万

    帖子

    3

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    22295
    最后登录
    2025-8-18
     楼主| 发表于 2022-10-21 13:56:43 | 显示全部楼层
    卍火影卍 发表于 2022-10-21 11:52
    代码贴出来真好,这个圆形的屏哪整的

    TB买的,20左右
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    2024-9-13 10:02
  • 签到天数: 297 天

    连续签到: 1 天

    [LV.8]以坛为家I

    34

    主题

    3512

    帖子

    38

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    6069

    活跃会员

    最后登录
    2025-7-30
    发表于 2022-10-24 14:24:19 | 显示全部楼层
    支持支持,哈哈哈哈
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    慵懒
    2025-8-6 11:04
  • 签到天数: 541 天

    连续签到: 1 天

    [LV.9]以坛为家II

    80

    主题

    2595

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    8322
    最后登录
    2025-8-7
    发表于 2022-10-26 09:19:43 | 显示全部楼层
    厉害,感谢分享
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    开心
    14 小时前
  • 签到天数: 1772 天

    连续签到: 188 天

    [LV.Master]伴坛终老

    15

    主题

    1万

    帖子

    1

    金牌会员

    Rank: 6Rank: 6

    积分
    21370
    最后登录
    2025-8-18
    发表于 2022-10-26 09:48:26 | 显示全部楼层
    支持支持
    回复

    使用道具 举报

  • TA的每日心情
    慵懒
    昨天 17:12
  • 签到天数: 1997 天

    连续签到: 9 天

    [LV.Master]伴坛终老

    4

    主题

    9003

    帖子

    0

    金牌会员

    Rank: 6Rank: 6

    积分
    14046
    最后登录
    2025-8-18
    发表于 2022-10-26 10:56:36 | 显示全部楼层
    写的不错
    该会员没有填写今日想说内容.
    回复

    使用道具 举报

  • TA的每日心情
    开心
    2025-8-8 16:43
  • 签到天数: 1504 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    97

    主题

    4692

    帖子

    12

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    10093
    最后登录
    2025-8-8
    发表于 2022-10-26 11:19:07 | 显示全部楼层
    楼主
    WS_BIT1 为什么是 0x7C,而不是 0xF0。同理,WS_BIT0为什么是0x60,而不是0xC0?

    我这里仅理论推导,没有实际硬件来验证。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /3 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2025-8-18 14:56 , Processed in 0.101081 second(s), 28 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表