02.GD32L233C-START模板工程 & WS2812B驱动实现之GPIO
[复制链接]
1、模板工程
不管是在GD官方的驱动库程序(GD32L23x_Firmware_Library_V1.0.0),还是对应的开发板资源包(GD32L23x_Demo_Suites_V1.1.0)中,都提供了基础GD32L233x系列的基础工程和各个外设的基础例程,方便熟悉、验证我们需要使用到的外设功能、基于开发板的程序,可以让我们快速的上手,以最快的速度投入开发;
参照官方的提供的KEIL模板工程,重新新建立了一个适用于自己的通用工程模板,基于开发板的硬件原理图,将LED、KEY和USART0这几个外设进行了配置,添加了自编的TASK任务调度程序;为了方便调试,基于USART0实现了Letter-shell的移植和应用,示意图如下所示:
程序编译无误后,下载到开发板,复位并运行;通过CH340的USB接口,结合电脑终端软件,开发板上电后打印如下所示的信息,并且4个LED灯间隔闪烁,按下和抬起按键都会有相应的状态信息输出:
2、实现功能
在GD32L233C-START模板工程的基础上实现通过GPIO来驱动WS2812B灯带,显示炫彩的效果。
WS2812B的控制时序图和逻辑如下图所示,具体的可以参考第5小节的数据手册:
3、代码实现
/*******************************************************************************
* @file WS2812B.c
* @author King
* [url=home.php?mod=space&uid=252314]@version[/url] V1.00
* [url=home.php?mod=space&uid=311857]@date[/url] 13-Dec-2021
* [url=home.php?mod=space&uid=159083]@brief[/url] ......
*******************************************************************************/
/* Define to prevent recursive inclusion -------------------------------------*/
#define __WS2812B_C__
/* Includes ------------------------------------------------------------------*/
#include "WS2812B.h"
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Exported variables --------------------------------------------------------*/
/* Exported function prototypes ----------------------------------------------*/
/*******************************************************************************
* @brief
* @param
* @retval
* [url=home.php?mod=space&uid=1020061]@attention[/url] *******************************************************************************/
static void WS2812B_Write0(void)
{
GPIO_BOP(WS2812B_GPIO_PORT) = WS2812B_GPIO_PIN; /* 420ns */
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();
GPIO_BC(WS2812B_GPIO_PORT) = WS2812B_GPIO_PIN; /* 870ns */
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void WS2812B_Write1(void)
{
GPIO_BOP(WS2812B_GPIO_PORT) = WS2812B_GPIO_PIN; /* 720ns */
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();
GPIO_BC(WS2812B_GPIO_PORT) = WS2812B_GPIO_PIN; /* 620ns */
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
__nop();__nop();__nop();__nop();
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void WS2812B_WriteByte(uint8_t Data)
{
for(uint8_t i = 0; i < 8; i++)
{
if(Data & (0x80 >> i))
{
WS2812B_Write1();
}
else
{
WS2812B_Write0();
}
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void WS2812B_Write24Bits(uint8_t R, uint8_t G, uint8_t B)
{
WS2812B_WriteByte(G);
WS2812B_WriteByte(R);
WS2812B_WriteByte(B);
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void WS2812B_DisplayAllRed(void)
{
uint8_t i = 0;
for(i = 0; i < 60; i++)
{
WS2812B_Write24Bits(255, 0, 0);
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void WS2812B_DisplayAllGreen(void)
{
uint8_t i = 0;
for(i = 0; i < 60; i++)
{
WS2812B_Write24Bits(0, 255, 0);
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void WS2812B_DisplayAllBlue(void)
{
uint8_t i = 0;
for(i = 0; i < 60; i++)
{
WS2812B_Write24Bits(0, 0, 255);
}
}
static uint8_t RGB_TAB[255][3];
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void RGB_Gradient(uint8_t R1, uint8_t G1, uint8_t B1,
uint8_t R2, uint8_t G2, uint8_t B2, uint8_t Step)
{
float R_STEP = (float)(((int)R2 - (int)R1) / Step);
float G_STEP = (float)(((int)G2 - (int)G1) / Step);
float B_STEP = (float)(((int)B2 - (int)B1) / Step);
for(uint8_t i = 0; i < Step; i++)
{
RGB_TAB[i][0] = (uint8_t)((uint32_t)(R1 + R_STEP * i) % 256);
RGB_TAB[i][1] = (uint8_t)((uint32_t)(G1 + G_STEP * i) % 256);
RGB_TAB[i][2] = (uint8_t)((uint32_t)(B1 + B_STEP * i) % 256);
}
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
static void WS2812B_DisplayFullColor(void)
{
static uint8_t Index = 0;
#if 0
uint8_t R_TAB[65] =
{
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 220,
200, 180, 160, 140, 120, 100, 80, 60, 40, 20, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 20, 40, 60, 80, 100, 120, 140,
160, 180, 200, 220, 240
};
uint8_t G_TAB[65] =
{
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 40, 60,
80, 100, 120, 140, 160, 180, 200, 220, 240, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255
};
uint8_t B_TAB[65] =
{
0, 20, 40, 60, 80, 100, 120, 140, 160, 180, 200, 220, 240, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 240, 220, 200, 180, 160, 140,
120, 100, 80, 60, 40, 20, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0
};
for(uint8_t i = 0; i < 60; i++)
{
WS2812B_Write24Bits(R_TAB[Index], G_TAB[Index], B_TAB[Index]);
Index = (Index + 1) % 65;
}
#else
uint8_t Step = 31, Mode = 1;
switch(Mode)
{
case 0: RGB_Gradient(0x00,0x00,0x00, 0x00,0x00,0xFF, Step); break;
case 1: RGB_Gradient(0x00,0x00,0x00, 0x00,0xFF,0x00, Step); break;
case 2: RGB_Gradient(0x00,0x00,0x00, 0xFF,0x00,0x00, Step); break;
default: break;
}
for(uint8_t i = 0; i < 60; i++)
{
WS2812B_Write24Bits(RGB_TAB[Index][0], RGB_TAB[Index][1], RGB_TAB[Index][2]);
Index = (Index + 1) % Step;
}
#endif
}
/*******************************************************************************
* @brief
* @param
* @retval
* @attention
*******************************************************************************/
void WS2812B_Init(void)
{
rcu_periph_clock_enable(WS2812B_GPIO_CLK);
gpio_mode_set(WS2812B_GPIO_PORT, GPIO_MODE_OUTPUT, GPIO_PUPD_NONE, WS2812B_GPIO_PIN);
gpio_output_options_set(WS2812B_GPIO_PORT, GPIO_OTYPE_PP, GPIO_OSPEED_50MHZ, WS2812B_GPIO_PIN);
WS2812B_DisplayAllRed(); SysTick_DelayMS(500);
WS2812B_DisplayAllGreen(); SysTick_DelayMS(500);
WS2812B_DisplayAllBlue(); SysTick_DelayMS(500);
TASK_Append(TASK_ID_WS2812B, WS2812B_DisplayFullColor, 50);
}
/******************* (C) COPYRIGHT 2021 *************************END OF FILE***/
4、运行结果
5、工程源码
Template.zip
(390.35 KB, 下载次数: 23)
WS2812B-MINI.pdf
(512.64 KB, 下载次数: 17)
|