3665|3

205

帖子

0

TA的资源

纯净的硅(初级)

楼主
 

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)

 

此帖出自GD32 MCU论坛

最新回复

楼主有keil的工程模板以及相关时钟配置吗     详情 回复 发表于 2023-6-17 09:29
点赞 关注(1)
个人签名We are a team and we work as a team !
 

回复
举报

6587

帖子

0

TA的资源

五彩晶圆(高级)

沙发
 

这么顺利,说明楼主的基于USART0进行的Letter-shell的移植比较成功,有一定实力

此帖出自GD32 MCU论坛
 
 
 

回复

205

帖子

0

TA的资源

纯净的硅(初级)

板凳
 
Jacktang 发表于 2021-12-13 23:33 这么顺利,说明楼主的基于USART0进行的Letter-shell的移植比较成功,有一定实力

此帖出自GD32 MCU论坛
 
个人签名We are a team and we work as a team !
 
 

回复

3

帖子

0

TA的资源

一粒金砂(初级)

4
 

楼主有keil的工程模板以及相关时钟配置吗

 

此帖出自GD32 MCU论坛
 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
推荐帖子
Luminary系列所有型号的选型工具

Luminary的函数库和图形库,上面集成的东西很丰富,很多工程师都会喜欢。 可以按着对外设的需求,来选。想要USB,就点“USB ...

单片机操作2.4寸TFT彩屏的源码与大家共享!含SD驱动!

元旦在淘宝上,花39个银子,淘了块2.4寸的TFT彩屏模块,,用店主提供的代码,用STC的51单片机,驱动起来,也显示图片了,发帖庆祝 ...

[Open Source]YS18-3荧光管电子时钟100%开源放送(软件源工程及代码.硬件原理图)

YS18-3的荧光管电子时钟曾是饱含了我所有期待的完美的荧光管电子时钟,它的功能比较完备,也受到了很多DIYer的关注与支持。 ...

Helper2416开发板移植ucgui(嵌入式linux运行ucgui)

本帖最后由 Gyroxp 于 2015-1-30 17:28 编辑 一些简单的应用,使用ucgui作为图形界面可能更加方便快捷。得益于ucgui良好 ...

求推荐:想买本C8051F单片机的书!

需要用C8051F580单片机开发产品。我做软件,C语言。 想买本 这方面的书。求推荐! 谢谢!

MSP430F149 I/O口控制

所谓IO口控制就是控制单片机的端口输出0或1,或者读出端口的状态,也就是输入和输出。 先说输出。想让MSP430单片机的端口 ...

无线连接技术选择指南

选择合适的无线连接技术从一开始就是一个关键的设计决策。这决定了应用的协议互操作性、距离、稳健性和用例。本选择指南将引导 ...

【花雕动手做】有趣好玩的音乐可视化系列小项目(16)--热干胶棒棒灯

偶然心血来潮,想要做一个声音可视化的系列专题。这个专题的难度有点高,涉及面也比较广泛,相关的FFT和FHT等算法也相当复杂,不 ...

颁奖:是德科技感恩月—遇见KeysightCare - 贵重仪器安全避坑指南

颁奖:是德科技感恩月—遇见KeysightCare - 贵重仪器安全避坑指南 名单详见下方列表。本颁奖贴只公布获奖名单,礼品 ...

【STM32U5A5ZJ开发板】USB设备及VCP通讯测试

STM32U5A5ZJ 上的USB是自带PHY的OTG USB设备,不但具有电源管理还具有设备管理功能,使用的接口也是Type C接口。 794377 ...

关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表