jinglixixi 发表于 2022-4-17 10:29

【AT-START-F425测评】WS2812彩色灯环的显示驱动

本帖最后由 jinglixixi 于 2022-4-17 21:42 编辑

<p style="text-align:justify">通常驱动W2812的方法是参照它的时序要求,以GPIO口来模拟它的时序进行驱动,</p>

<p>但对于主频较低的MCU来说则较难达到它的时序要求。</p>

<p>对于AT32F425来说,还可以利用它的SPI和DMA来驱动WS2812灯带,并按时序的要求将主频设为80MHz。</p>

<p>在该驱动方式下,其显示效果如图1和图2所示。</p>

<p>图1 显示效果1</p>

<p>&nbsp;</p>

<p>图2 显示效果2</p>

<p>&nbsp;</p>

<p>在实现WS2812的驱动过程中,要涉及一个变换处理函数,它需要将8位的二进制色彩值转换为一个4字节的32位二进制数,其中某位为&ldquo;1&rdquo;时,就转换为0xe(高电平占优);为&ldquo;0&rdquo;,则转换为0x8(低电平占优)。</p>

<p>尽管是使用SPI来驱动WS2812,但WS2812只有一个数据引脚,故其该引脚的配置函数为:</p>

<p>static void gpio_config(void)</p>

<p>{</p>

<p>&nbsp;&nbsp;gpio_init_type gpio_initstructure;</p>

<p>&nbsp;&nbsp;crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);</p>

<p>&nbsp;&nbsp;gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE15, GPIO_MUX_0);</p>

<p>&nbsp;&nbsp;gpio_default_para_init(&amp;gpio_initstructure);</p>

<p>&nbsp;&nbsp;gpio_initstructure.gpio_pull&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;= GPIO_PULL_DOWN;</p>

<p>&nbsp;&nbsp;gpio_initstructure.gpio_mode&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;= GPIO_MODE_MUX;</p>

<p>&nbsp;&nbsp;gpio_initstructure.gpio_pins&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;= GPIO_PINS_15;</p>

<p>&nbsp;&nbsp;gpio_init(GPIOB, &amp;gpio_initstructure);</p>

<p>}</p>

<p>也就是说将WS2812与PB15相连接就可以了,实现演示效果的主程序为:</p>

<pre>
<code class="language-cpp">int main(void)
{
int8_t mod;
system_clock_config();
at32_board_init();
delay_us(100);
gpio_config();
spi_config();
int8_t dir = {0};
for(uint32_t i = 0; i &lt; sizeof(WS2812_rgb_buf); i++)
{
      for(uint32_t j = 0; j &lt; 3; j++)
      {
            WS2812_rgb_buf = i * (j + 2);
            dir = j + 2;
      }
}
while(1)
{
      dma_channel_enable(DMA1_CHANNEL5, TRUE);
      while(!dma_flag_get(DMA1_FDT5_FLAG));
      dma_flag_clear(DMA1_FDT5_FLAG);
      dma_channel_enable(DMA1_CHANNEL5, FALSE);
      DMA1_CHANNEL5-&gt;dtcnt = sizeof(WS2812_bit_buf);
      DMA1_CHANNEL5-&gt;maddr = (uint32_t)WS2812_bit_buf;
      delay_ms(10);
      uint8_t *buf = (uint8_t *)WS2812_rgb_buf;
      for(uint32_t i = 0; i &lt; sizeof(WS2812_rgb_buf); i++)
   {
         for(uint32_t j = 0; j &lt; 3; j++)
          {
               *buf += dir;
               if((*buf &gt;= 255)||(*buf == 0))
               {
                         dir = -dir;
               }
               buf++;
         }
      }
      rgb_to_buf(&amp;WS2812_rgb_buf,&amp;WS2812_bit_buf);
}
}
</code></pre>

<p>&nbsp;</p>

lugl4313820 发表于 2022-4-17 11:52

<p>WS2812的驱动LED灯,很经典呀,好似这个可以做动态显示图像的,是这个吗?</p>

jinglixixi 发表于 2022-4-17 21:36

lugl4313820 发表于 2022-4-17 11:52
WS2812的驱动LED灯,很经典呀,好似这个可以做动态显示图像的,是这个吗?

<p>没错,点位数多的效果比较好,否则显示的内容受限。</p>
页: [1]
查看完整版本: 【AT-START-F425测评】WS2812彩色灯环的显示驱动