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)
{
}
}
我修改了一下代码,打包了工程 工程如下:
帮检查下这个演示程序
【新提醒】SPI DMA 输出控制WS2812三基色彩灯程序,不加反相器, 8H系列/32G系列系列 - QSPI/3组SPI/I2S/I2C,一线制温湿度传感器 国芯技术交流网站 - AI32位8051交流社区 (stcaimcu.com)
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 15:53
帮检查下这个演示程序
晚上烧录上看看 8h不是有nop(n)快捷函数,为什么写那么多nop。 soma 发表于 2024-8-29 17:55
8h不是有nop(n)快捷函数,为什么写那么多nop。
学到了,我还不知道呢. 我是用逻辑分析仪调的 嵌入式之路 发表于 2024-8-29 17:34
晚上烧录上看看
试了,稳定的很, 我用的DIP40, 明天补上个视频 //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_);
}