STC8G1K08A的主频为24MHz,一个_nop_()大概耗时是63+ns,其实我计算的结果应该是44ns,因为1/24 000 000 约等于是40ns,但是我拿着40一个_nop_()的结果去写代码,发现好像不对劲,最后定位在了一个_nop_()大概耗时是60+ns。

0.3us那就是需要五个_nop_()来延时,但是以防万一,这里用的是四个,比较时间范围是0.2~0.35us。

0.6us就用十个_nop_()就行。

然后RESET码因为80us算是时间比较长的,就用STC烧录软件提供的延时代码就行。

#include "STC8G_H_Delay.h"
#include "STC8G_H_GPIO.h"
 
#define WS2812B_IN P32
 
// 复位
void WS2812B_SendReset(void) {
    unsigned char data i, j;
    WS2812B_IN = 0;  // 拉低80us
    i = 2;
    j = 219;
    do {
        while (--j)
            ;
    } while (--i);
}
 
// 发送1码
void WS2812B_SendOne(void) {
    WS2812B_IN = 1;     // 拉高延时1us
    _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
    WS2812B_IN = 0;     // 拉低延时0.3us
    _nop_();_nop_();_nop_();_nop_();
}
 
// 发送0码
void WS2812B_SendZero(void) {
    WS2812B_IN = 1;     // 拉高延时0.3us
    _nop_();_nop_();_nop_();_nop_();
    WS2812B_IN = 0;     // 拉低延时1us
     _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
}
// 纯红光
void WS2812B_SendRed(void) {
    unsigned char i;
    WS2812B_SendReset();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendOne();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
}
// 纯绿光
void WS2812B_SendGreen(void) {
    unsigned char i;
    WS2812B_SendReset();
    for (i = 0; i < 8; ++i)
        WS2812B_SendOne();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
}
// 纯蓝光
void WS2812B_SendBlue(void) {
    unsigned char i;
    WS2812B_SendReset();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendZero();
    for (i = 0; i < 8; ++i)
        WS2812B_SendOne();
}
 
 
void main(void) {
    P3_MODE_OUT_PP(GPIO_Pin_2);     // 设置P32为推挽输出
 
    while (1) {
        WS2812B_SendRed();
        delay_ms(1000);
        WS2812B_SendBlue();
        delay_ms(1000);
        WS2812B_SendGreen();
        delay_ms(1000);
    }
}