<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      本文以CH592測試,使用TMR的PWM功能驅動WS2812,這種方法相對于SPI DMA驅動的方式有點時節省IO資源,但是RAM消耗會比SPI方式大四倍。

      下面貼出程序:

      1.pwm_ws2812.c文件:

      #include "pwm_ws2812.h"
      
      /**
       * @brief  初始化WS2812緩沖區(填充前后復位信號)
       */
      void ws2812_buf_init(uint32_t *buf)
      {
          uint16_t i;
          // 前導復位信號(低電平)
          for(i = 0; i < WS2812_RESET_CYCLES; i++)
          {
              buf[i] = 0; // 占空比0%(低電平)
          }
          // 后導復位信號(確保數據發送完成后復位)
          uint16_t data_end = WS2812_RESET_CYCLES + WS2812_LED_NUM * 24;
          for(i = data_end; i < WS2812_BUF_LEN; i++)
          {
              buf[i] = 0;
          }
      }
      
      /**
       * @brief  內部函數:填充單個LED的24bit數據
       */
      static void ws2812_set_rgb_bits(uint32_t *buf, uint8_t g, uint8_t r, uint8_t b)
      {
          uint8_t i;
          // 綠色分量(8bit,先低后高)
          for(i = 0; i < 8; i++)
          {
              buf[i] = (g & 0x01) ? WS2812_T1H : WS2812_T0H;
              g >>= 1;
          }
          // 紅色分量(8bit,先低后高)
          for(i = 0; i < 8; i++)
          {
              buf[i + 8] = (r & 0x01) ? WS2812_T1H : WS2812_T0H;
              r >>= 1;
          }
          // 藍色分量(8bit,先低后高)
          for(i = 0; i < 8; i++)
          {
              buf[i + 16] = (b & 0x01) ? WS2812_T1H : WS2812_T0H;
              b >>= 1;
          }
      }
      
      /**
       * @brief  設置單個LED的顏色
       */
      void ws2812_set_single(uint32_t *buf, uint8_t led_idx, uint8_t g, uint8_t r, uint8_t b)
      {
          if(led_idx >= WS2812_LED_NUM) return; // 索引越界檢查
          // 計算當前LED在緩沖區中的起始位置
          uint32_t *led_buf = buf + WS2812_RESET_CYCLES + led_idx * 24;
          ws2812_set_rgb_bits(led_buf, g, r, b);
      }
      
      /**
       * @brief  填充所有LED為同一顏色
       */
      void ws2812_fill_all(uint32_t *buf, uint8_t g, uint8_t r, uint8_t b)
      {
          for(uint8_t i = 0; i < WS2812_LED_NUM; i++)
          {
              ws2812_set_single(buf, i, g, r, b);
          }
      }
      
      /**
       * @brief  發送WS2812數據
       */
      void ws2812_send(uint32_t *buf)
      {
          // 配置DMA傳輸范圍
          TMR2_DMACfg(ENABLE,
                     (uint16_t)(uint32_t)buf,
                     (uint16_t)(uint32_t)(buf + WS2812_BUF_LEN ),
                     Mode_Single);
          // 啟動PWM(低電平起始,單次傳輸)
          //TMR2_PWMInit(Low_Level, PWM_Times_1);
          TMR2_PWMEnable();
          TMR2_Enable();
      
      }
      
      /**
       * @brief  初始化WS2812硬件(定時器2+GPIO)
       */
      void ws2812_hw_init(void)
      {
          // 配置GPIO(PB11,推挽輸出)
          GPIOA_ModeCfg(GPIO_Pin_11, GPIO_ModeOut_PP_5mA);
      
      //    GPIOB_ModeCfg(GPIO_Pin_11, GPIO_ModeOut_PP_5mA);
      //    GPIOPinRemap(ENABLE, RB_PIN_TMR2); // 映射定時器2到PB11
      
          // 配置定時器2 PWM周期
          TMR2_PWMCycleCfg(WS2812_BIT_CYCLE); // 單bit周期
          TMR2_PWMInit(High_Level, PWM_Times_1);
      
      }

      2.pwm_ws2812.h文件:

      #ifndef __PWM_WS2812_H
      #define __PWM_WS2812_H
      
      #include "CH59x_common.h"
      
      // WS2812 配置參數(根據實際需求修改)
      #define WS2812_LED_NUM      10      // LED數量
      #define WS2812_CLK_FREQ     60      // 系統時鐘頻率(MHz),需與實際時鐘一致
      #define WS2812_RESET_US     50      // 復位信號最小時間(us)
      
      // 時序參數(單位:系統時鐘周期,自動計算)
      #define WS2812_T0H          (uint32_t)(0.4 * WS2812_CLK_FREQ)  // 0碼高電平(≈0.4us)
      #define WS2812_T1H          (uint32_t)(0.8 * WS2812_CLK_FREQ)  // 1碼高電平(≈0.8us)
      #define WS2812_BIT_CYCLE    (uint32_t)(1.25 * WS2812_CLK_FREQ) // 單bit總周期(≈1.25us)
      #define WS2812_T0L          (WS2812_BIT_CYCLE - WS2812_T0H)    // 0碼低電平
      #define WS2812_T1L          (WS2812_BIT_CYCLE - WS2812_T1H)    // 1碼低電平
      #define WS2812_RESET_CYCLES (uint32_t)((WS2812_RESET_US * WS2812_CLK_FREQ) / 1000) // 復位周期數
      
      // 緩沖區長度計算(前導復位+數據+后導復位)
      #define WS2812_BUF_LEN      (WS2812_RESET_CYCLES + WS2812_LED_NUM * 24 + WS2812_RESET_CYCLES/2)
      
      /**
       * @brief  初始化WS2812緩沖區(填充復位信號)
       * @param  buf: 緩沖區指針(需提前定義為WS2812_BUF_LEN長度)
       */
      void ws2812_buf_init(uint32_t *buf);
      
      /**
       * @brief  設置單個LED的RGB顏色
       * @param  buf: 緩沖區指針
       * @param  led_idx: LED索引(0~WS2812_LED_NUM-1)
       * @param  g: 綠色分量(0-255)
       * @param  r: 紅色分量(0-255)
       * @param  b: 藍色分量(0-255)
       */
      void ws2812_set_single(uint32_t *buf, uint8_t led_idx, uint8_t g, uint8_t r, uint8_t b);
      
      /**
       * @brief  填充所有LED為同一顏色
       * @param  buf: 緩沖區指針
       * @param  g: 綠色分量(0-255)
       * @param  r: 紅色分量(0-255)
       * @param  b: 藍色分量(0-255)
       */
      void ws2812_fill_all(uint32_t *buf, uint8_t g, uint8_t r, uint8_t b);
      
      /**
       * @brief  發送WS2812數據(啟動DMA和PWM)
       * @param  buf: 緩沖區指針
       */
      void ws2812_send(uint32_t *buf);
      
      /**
       * @brief  初始化WS2812硬件(定時器+GPIO)
       */
      void ws2812_hw_init(void);
      
      #endif

      3.main函數:

      #include "CH59x_common.h"
      
      #include "pwm_ws2812.h"
      
      // 定義WS2812緩沖區(按宏定義長度分配)
      __attribute__((aligned(4))) uint32_t PwmBuf[WS2812_BUF_LEN];
      
      void DebugInit(void)
      {
          GPIOA_SetBits(GPIO_Pin_9);
          GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU);
          GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA);
          UART1_DefInit();
      }
      
      int main()
      {
          SetSysClock(CLK_SOURCE_PLL_60MHz);
          DebugInit();
          PRINT("WS2812 Test @ChipID=%02X\n", R8_CHIP_ID);
      
          // 初始化WS2812硬件和緩沖區
          ws2812_hw_init();
          ws2812_buf_init(PwmBuf);
      PRINT("WS2812_BUF_LEN=%d\n",WS2812_BUF_LEN);
          // 測試流程:依次顯示黃→青→紫→逐個點亮
          ws2812_fill_all(PwmBuf, 0xFF, 0xFF, 0x00); // 黃色
          for(uint16_t i=0;i<WS2812_BUF_LEN;i++){
              PRINT("%d ",PwmBuf[i]);
          }
          PRINT("\n");
          ws2812_send(PwmBuf);
          DelayMs(1000);
      
          ws2812_fill_all(PwmBuf, 0xFF, 0x00, 0xFF); // 青色
          ws2812_send(PwmBuf);
          DelayMs(1000);
      
          ws2812_fill_all(PwmBuf, 0x00, 0xFF, 0xFF); // 紫色
          ws2812_send(PwmBuf);
          DelayMs(1000);
      
          while(1) // 無限循環,持續律動
          {
              // 1. 從左到右:目標色依次點亮,背景色保持不變
              for(uint8_t j = 0; j < WS2812_LED_NUM; j++)
              {
                  // 每次循環先重置所有LED為背景色(避免殘留之前的目標色)
                  ws2812_fill_all(PwmBuf, 0x55, 0xAA, 0xFF);
                  // 將當前位置j的LED設為目標色
                  ws2812_set_single(PwmBuf, j, 0xAA, 0x55, 0x00);
                  // 發送數據,更新LED顯示
                  ws2812_send(PwmBuf);
                  // 控制律動速度,數值越小越快(可根據需求調整,如300ms)
                  DelayMs(300);
              }
      
              // 2. 從右到左:目標色依次熄滅(恢復背景色),模擬“往回走”
              for(int8_t j = WS2812_LED_NUM - 2; j >= 0; j--) // 從倒數第二個開始(最后一個已點亮,無需重復)
              {
                  // 重置所有LED為背景色
                  ws2812_fill_all(PwmBuf, 0x55, 0xAA, 0xFF);
                  // 將當前位置j的LED設為目標色
                  ws2812_set_single(PwmBuf, j, 0xAA, 0x55, 0x00);
                  // 發送數據,更新LED顯示
                  ws2812_send(PwmBuf);
                  // 保持與“從左到右”相同的速度,確保律動流暢
                  DelayMs(300);
              }
          }
      }
      posted on 2025-11-01 11:25  WCH藍牙應用分享  閱讀(7)  評論(0)    收藏  舉報

      主站蜘蛛池模板: 亚洲中文字幕一区二区| 国产精品午夜无码AV天美传媒| 久青草久青草视频在线观看| 四虎永久精品免费视频| 亚洲国产欧美在线看片一国产| 丰满人妻一区二区三区色| 免费视频成人片在线观看| 免费国产一区二区不卡| 蜜桃视频一区二区三区四| 国产精品中文字幕久久| 国产成人欧美一区二区三区| 老司机性色福利精品视频| 亚洲自在精品网久久一区| 97免费在线观看视频| 202丰满熟女妇大| 国产福利视频区一区二区| 99久久99久久久精品久久| 欧美日韩一区二区三区视频播放| 三级国产三级在线| 中文字幕 制服 亚洲 另类| 黄色特级片一区二区三区| 天天躁夜夜躁狠狠喷水| 欧美巨大极度另类| 中文字幕日韩精品亚洲一区| 丰满少妇内射一区| 狠狠色综合久久狠狠色综合| 人妻丝袜无码专区视频网站| 开心五月激情综合久久爱| 亚洲欧美日韩愉拍自拍美利坚| 国产成人精品97| 久久久久国产精品熟女影院| 色成人亚洲| 东方av四虎在线观看| 女人被狂躁到高潮视频免费软件| 日韩av不卡一区二区在线| 国产精品熟女一区二区三区| 99久久精品免费看国产电影| 亚洲AV无码久久精品日韩| 亚洲悠悠色综合中文字幕| 公与淑婷厨房猛烈进出视频免费 | 在线观看AV永久免费|