嵌入式之路 发表于 2024-8-29 14:52:35

8H系列 直接驱动 WS2812

我测量了下24MHz下I/O的翻转速度能到3MHz,所以直接I/O驱动是足够的。废话不多说直接上代码

#include <AI8H.H>
#include <intrins.h>

typedef unsigned char uint8_t;


#define ZERO_CODE() P21=1; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();P21=0;_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
#define ONE_CODE() P21=1; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();P21=0; _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();

#define LED_NUMBER 2
#define BRIGHTNESS 2
#define MAX_BRIGHTNESS 255


void Delay55us(void)      //@24.000MHz
{
    unsigned char data i, j;

    _nop_();
    i = 2;
    j = 180;
    do
    {
      while (--j);
    } while (--i);
}

void reset_all()
{
    uint8_t index;


    for (index = 0; index < 24 * LED_NUMBER; index++)
    {
      ZERO_CODE();
    }


    Delay55us();
}



void Delay1000ms(void)      //@24.000MHz
{
    unsigned char data i, j, k;

    _nop_();
    _nop_();
    i = 122;
    j = 193;
    k = 128;
    do
    {
      do
      {
            while (--k);
      } while (--j);
    } while (--i);
}




void set_led_color(uint8_t led_index, uint8_t green, uint8_t red, uint8_t blue)
{
    uint8_t i;
    uint8_t mask, number;


    green = (green * BRIGHTNESS) / MAX_BRIGHTNESS;
    red = (red * BRIGHTNESS) / MAX_BRIGHTNESS;
    blue = (blue * BRIGHTNESS) / MAX_BRIGHTNESS;


    led_states = green;
    led_states = red;
    led_states = blue;

    for (number = 0; number < LED_NUMBER; number++)
    {

      for (i = 0; i < 8; i++)
      {
            mask = 0x80 >> i;
            if (led_states & mask)
            {
                ONE_CODE();
            }
            else
            {
                ZERO_CODE();
            }
      }
      for (i = 0; i < 8; i++)
      {
            mask = 0x80 >> i;
            if (led_states & mask)
            {
                ONE_CODE();
            }
            else
            {
                ZERO_CODE();
            }
      }
      for (i = 0; i < 8; i++)
      {
            mask = 0x80 >> i;
            if (led_states & mask)
            {
                ONE_CODE();
            }
            else
            {
                ZERO_CODE();
            }
      }
    }
    Delay55us();
}

void main()
{
    P2M0 |= 0x02;
    P2M1 &= ~0x02;

    set_led_color(0, 255, 0, 0);

    set_led_color(1, 0, 255, 0);

    Delay1000ms();
    Delay1000ms();
    Delay1000ms();
    Delay1000ms();
    Delay1000ms();
    reset_all();

    while (1)
    {

    }
}


嵌入式之路 发表于 2024-8-29 15:35:27

我修改了一下代码,打包了工程

嵌入式之路 发表于 2024-8-29 15:35:43

工程如下:

神农鼎 发表于 2024-8-29 15:53:33


帮检查下这个演示程序



【新提醒】SPI DMA 输出控制WS2812三基色彩灯程序,不加反相器, 8H系列/32G系列系列 - QSPI/3组SPI/I2S/I2C,一线制温湿度传感器 国芯技术交流网站 - AI32位8051交流社区 (stcaimcu.com)

DebugLab 发表于 2024-8-29 15:55:40

void WS2812_Reset(void)
{
        WS2812=0;
        Delay_100us();
}

void WS2812_Write_Byte(unsigned char data temp)        //AI8@24MHz 0:340ns+1400ns 1:1000ns+1400ns
{
        unsigned char data i=8;
        while(i)
        {
                temp<<=1;
                WS2812=1;
                NOP(4);
                if(CY)
                {
                        NOP(18);
                }
                WS2812=0;
                NOP(27);
                i--;
        }
}

void WS2812_Write(void)
{
        unsigned char i;
        WS2812_Reset();
        for(i=0;i<LED_Number;i++)
        {
                WS2812_Write_Byte(G);
                WS2812_Write_Byte(R);
                WS2812_Write_Byte(B);
        }
}

嵌入式之路 发表于 2024-8-29 17:34:26

神农鼎 发表于 2024-8-29 15:53
帮检查下这个演示程序




晚上烧录上看看

soma 发表于 2024-8-29 17:55:23

8h不是有nop(n)快捷函数,为什么写那么多nop。

嵌入式之路 发表于 2024-8-29 20:50:23

soma 发表于 2024-8-29 17:55
8h不是有nop(n)快捷函数,为什么写那么多nop。

学到了,我还不知道呢. 我是用逻辑分析仪调的

嵌入式之路 发表于 2024-8-29 20:56:27

嵌入式之路 发表于 2024-8-29 17:34
晚上烧录上看看

试了,稳定的很, 我用的DIP40, 明天补上个视频

cnos 发表于 2024-8-29 22:36:48

//STC8G1K08A 22.1184MHz
//STC8G1K08A 22.1184MHz

void nop(void)
{
}
void sendbyte(unsigned char byte)
{
      unsigned char i;
      i=8;
      EA=0;
                do
                {
                        ws2812pin=1;nop();
                        ws2812pin=byte&0x80;nop();
                        ws2812pin=0;nop();
                        byte=(byte<<1);               //左移位
                }while(--i);
      EA=1;
}
void SetLed(unsigned char R_,G_,B_)
{
      sendbyte(G_);
      sendbyte(R_);
      sendbyte(B_);
}
页: [1] 2 3
查看完整版本: 8H系列 直接驱动 WS2812