打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

LiSun

打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

ws2812x数据传输时间
T0H 0 码,高电平时间 220ns~380ns
T0L 0 码,低电平时间 580ns~1.6µs
T1H 1 码,高电平时间 580ns~1.6µs
T1L 1 码,低电平时间 220ns~420µs
RES 帧单位,低电平时间 >280µs 以上

对于ARM_M平台 @24M
1个NOP:(1/24000000)100010001000==41.67ns
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();
5个NOP 41.67
5 = 208.35ns (加上代码执行时间,勉强达到ws2812x标准)

对于n76e003平台 @16M
1个nop 占用87ns
while(1) 占用194ns
函数调用 占用570ns

注:

  1. 点亮白灯或混色造成灯光无改变,则需要检测供电是否充足,接外部电池则满足需求。
  2. 多个灯光出现颜色不对,则先检测供电问题。
  3. 这个例子是按照24M写的,其他频率请重新计算

[单片机框架] [app_led] [WS2812x] 利用软定时器实现WS2812x闪烁和呼吸等灯光模式

伪代码:

    temp[0] = 0xF0;
    temp[1] = 0x3B;
    temp[2] = 0x0F;
    onewire_send_data(0, temp, 3);
/********************************************************************************
* @file    onewire.c
* @author  jianqiang.xue
* @Version V1.0.0
* @Date    2020-12-07
* @brief   可用于ws2812x等
ws2812x数据传输时间
T0H 0 码,高电平时间  220ns~380ns
T0L 0 码,低电平时间  580ns~1.6µs
T1H 1 码,高电平时间  580ns~1.6µs
T1L 1 码,低电平时间  220ns~420µs
RES 帧单位,低电平时间 >280µs 以上

对于ARM_M平台 @16M
1个NOP:(1/24000000)*1000*1000*1000==41.67ns
__NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \
对于n76e003平台 @16M
1个nop      占用87ns
while(1)    占用194ns
函数调用     占用570ns

注:1.如果点亮白灯或混色造成灯光无改变,则需要检测供电是否充足,接外部电池则满足需求。
2. 如果多个灯光出现颜色不对,则先检测供电问题。
********************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "bsp_gpio.h"

#include "sys_api.h"
#include "os_api.h"

#include "onewire.h"
#include "business_gpio.h"
#include "business_function.h"

/* Private Define ------------------------------------------------------------*/
#if 1
#define T0_BIT_SIGNAL(GPIOX, PIN)                     \
    GPIOX->ODSET=PIN;                                 \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \
    GPIOX->ODCLR=PIN;                                 \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \

#define T1_BIT_SIGNAL(GPIOX, PIN)                     \
    GPIOX->ODSET=PIN;                                 \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \
    GPIOX->ODCLR=PIN;                                 \
    __NOP(); __NOP(); __NOP(); __NOP(); __NOP();      \

#define RESET_SIGNAL(GPIOX, PIN)                      \
    bsp_gpio_set_pin(GPIOX, PIN, BSP_GPIO_PIN_RESET); \
    delay(500);                                       \

#endif
/* Private Function Prototypes -----------------------------------------------*/

static void delay(uint16_t cnt)
{
    while (cnt--)
    {
        __NOP();
    }
}

void onewire_init(void)
{
#if BS_WS2812_CH0_EN
    BS_ONEWIRE_CH0_GPIO_CLK_ENABLE();
    bsp_gpio_init_output(ONEWIRE_CH0_PORT, ONEWIRE_CH0_PIN, BSP_GPIO_PIN_OUT_PP);
    bsp_gpio_set_pin(ONEWIRE_CH0_PORT, ONEWIRE_CH0_PIN, BSP_GPIO_PIN_RESET);
#endif
#if BS_WS2812_CH1_EN
    BS_ONEWIRE_CH1_GPIO_CLK_ENABLE();
    bsp_gpio_init_output(ONEWIRE_CH1_PORT, ONEWIRE_CH1_PIN, BSP_GPIO_PIN_OUT_PP);
    bsp_gpio_set_pin(ONEWIRE_CH1_PORT, ONEWIRE_CH1_PIN, BSP_GPIO_PIN_RESET);
#endif
#if BS_WS2812_CH2_EN
    BS_ONEWIRE_CH2_GPIO_CLK_ENABLE();
    bsp_gpio_init_output(ONEWIRE_CH2_PORT, ONEWIRE_CH2_PIN, BSP_GPIO_PIN_OUT_PP);
    bsp_gpio_set_pin(ONEWIRE_CH2_PORT, ONEWIRE_CH2_PIN, BSP_GPIO_PIN_RESET);
#endif
#if BS_WS2812_CH3_EN
    BS_ONEWIRE_CH3_GPIO_CLK_ENABLE();
    bsp_gpio_init_output(ONEWIRE_CH3_PORT, ONEWIRE_CH3_PIN, BSP_GPIO_PIN_OUT_PP);
    bsp_gpio_set_pin(ONEWIRE_CH3_PORT, ONEWIRE_CH3_PIN, BSP_GPIO_PIN_RESET);
#endif
}

void onewire_deinit(void)
{
#if BS_WS2812_CH0_EN
    bsp_gpio_deinit(ONEWIRE_CH0_PORT, ONEWIRE_CH0_PIN);
#endif
#if BS_WS2812_CH1_EN
    bsp_gpio_deinit(ONEWIRE_CH1_PORT, ONEWIRE_CH1_PIN);
#endif
#if BS_WS2812_CH2_EN
    bsp_gpio_deinit(ONEWIRE_CH2_PORT, ONEWIRE_CH2_PIN);
#endif
#if BS_WS2812_CH3_EN
    bsp_gpio_deinit(ONEWIRE_CH3_PORT, ONEWIRE_CH3_PIN);
#endif
}
bool flag = false;
void onewire_send_data(uint8_t ch, uint8_t *data, uint8_t len)
{
    uint8_t temp = 0;
    if (ch == 0)
    {
#if BS_WS2812_CH0_EN
        if (flag)
        {
            return;
        }
        flag = true;
        uint32_t val = SysTick->CTRL;
        SysTick->CTRL &= ~0x00000003; // 禁用 SysTick 中断
        sys_disable_irq();
        RESET_SIGNAL(ONEWIRE_CH0_PORT, ONEWIRE_CH0_PIN);
        for (uint8_t n = 0; n < BS_WS2812_CH0_NUM; n++)
        {
            for (uint8_t i = 0; i < len; i++)
            {
                temp = data[i];
                for (uint8_t j = 0; j < 8; j++)
                {
                    if (temp & 0x80)
                    {
                        T1_BIT_SIGNAL(ONEWIRE_CH0_PORT, ONEWIRE_CH0_PIN)
                    }
                    else
                    {
                        T0_BIT_SIGNAL(ONEWIRE_CH0_PORT, ONEWIRE_CH0_PIN);
                    }
                    temp <<= 1;
                }
            }
        }
        RESET_SIGNAL(ONEWIRE_CH0_PORT, ONEWIRE_CH0_PIN);
        SysTick->CTRL = val;
        sys_enable_irq();
        flag = false;
#endif
    }
}

/********************************************************************************
* @file    onewire.h
* @author  jianqiang.xue
* @Version V1.0.0
* @Date    2020-11-23
* @brief   NULL
********************************************************************************/
#ifndef __ONEWIRE_H
#define __ONEWIRE_H

/* Includes ------------------------------------------------------------------*/
#include <stdint.h>
/* Public Function Prototypes ------------------------------------------------*/

void onewire_init(void);
void onewire_deinit(void);
void onewire_send_data(uint8_t ch, uint8_t *data, uint8_t len);
#endif /* __ONEWIRE_H */

posted on 2022-08-13 11:00  xuejianqiang  阅读(108)  评论(0编辑  收藏  举报
打造一个通用性MCU架构,支持CX32/AT32/NRF51/NRF52等。 OS支持RTX4/RTX5/FreeRtos。 采用VsCode+GCC组合,VsCode+KEIL5,超强开发方式。 QQ群:524408033