云计算百科
云计算领域专业知识百科平台

SDCC+Ai8051U控制WS2812灯带!

取色器

菜鸟教程取色器

参考时序

代码:

#include "Ai8051U.h"
#include <stdint.h>
#include <stdlib.h>

// —– WS2812B 配置 —–
uint16_t count = 0; // 全局计数变量(未使用)
#define WS2812Pin P10 // 数据引脚 P1.0
#define LED_COUNT 32 // LED数量(替换原length变量,更语义化)
// —– —————–

// 全局变量:GRB格式颜色数据(3字节/LED)
__xdata uint8_t ws2812b_data[3 * LED_COUNT];

#define HIRC 40000000UL
#define FOSC 40000000UL
#define SYSCLK FOSC
#define MAIN_Fosc FOSC

void delay_us(uint16_t us)
{
do
{
__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");
__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");
__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");
__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");
__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");
__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");__asm__("nop");
} while (–us);
}

void delay_ms(uint16_t ms)
{
uint16_t i;

do
{
i = MAIN_Fosc / 10000;
while (–i);
} while (–ms);
}

// 1T模式时序修正(40MHz=25ns/周期)
// 0 bit: 高0.4us(16个NOP)、低0.85us(34个NOP)
// 1 bit: 高0.85us(34个NOP)、低0.4us(16个NOP)
// Reset: 低电平>50us
void WS2812B_SendData(uint8_t *data, uint16_t led_num)
{
EA = 0; // 关闭总中断,避免时序被打断
uint16_t total_bytes = led_num * 3; // 总字节数(GRB*LED数)

for(uint16_t i = 0; i < total_bytes; i++)
{
for(int8_t j = 7; j >= 0; j–) // 高位优先发送
{
if(data[i] & (1 << j)) // 发送1 bit
{
WS2812Pin = 1;
NOP(34); // 高电平0.85us (34*25ns=850ns)
WS2812Pin = 0;
NOP(16); // 低电平0.4us (16*25ns=400ns)
}
else // 发送0 bit
{
WS2812Pin = 1;
NOP(16); // 高电平0.4us
WS2812Pin = 0;
NOP(34); // 低电平0.85us
}
}
}
EA = 1; // 开启总中断

// 发送复位信号(低电平>50us)
// WS2812Pin = 0;
// delay_us(50); // 50us (2000*25ns=50000ns)
}

// ===== 颜色填充函数 =====
/**
* @brief 填充单一颜色(GRB格式)
* @param green 绿色分量(0-255)
* @param red 红色分量(0-255)
* @param blue 蓝色分量(0-255)
*/
void WS2812B_FillSolidColor(uint8_t green, uint8_t red, uint8_t blue)
{
for(uint16_t i = 0; i < LED_COUNT; i++)
{
uint16_t idx = i * 3;
ws2812b_data[idx] = green; // G分量
ws2812b_data[idx+1] = red; // R分量
ws2812b_data[idx+2] = blue; // B分量
}
// 发送颜色数据到灯带
WS2812B_SendData(ws2812b_data, LED_COUNT);
}

/**
* @brief 填充随机颜色(每个LED颜色不同)
*/
void WS2812B_FillRandomColor(void)
{
// 初始化随机种子(读取P3口电平,避免每次随机序列相同)
srand(count|P10);

for(uint16_t i = 0; i < LED_COUNT; i++)
{
uint16_t idx = i * 3;
ws2812b_data[idx] = rand() % 256; // 随机G
ws2812b_data[idx+1] = rand() % 256; // 随机R
ws2812b_data[idx+2] = rand() % 256; // 随机B
}
WS2812B_SendData(ws2812b_data, LED_COUNT);
}

void main(void)
{
P1M0 = 0x01;
P1M1 = 0x00;
WTST = 0x00; // 关闭看门狗

while (1)
{
// 1. 显示纯红色
WS2812B_FillSolidColor(0, 255, 0);
delay_ms(1000);

// 2. 显示纯绿色
WS2812B_FillSolidColor(255, 0, 0);
delay_ms(1000);

// 3. 显示纯蓝色
WS2812B_FillSolidColor(0, 0, 255);
delay_ms(1000);

// 4. 显示随机颜色
WS2812B_FillRandomColor();
delay_ms(2000);

count = (count>9999)?0:count+1;
}
}

赞(0)
未经允许不得转载:网硕互联帮助中心 » SDCC+Ai8051U控制WS2812灯带!
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!