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);
}
}
评论