STC15点亮WS2812灯珠(C结合汇编)

WS2812自带5050灯珠,只需要一个IO口就能够驱动LED灯带,十分方便。但是,由于需要800K的PWM信号,对大部分单片机来说,压力非常大,通常单片机的硬件PWM只支持到100K左右。

好不容易在网上找了个例子,为了满足处理速度,预先将字节转化为比特,需要24字节的缓冲区,而且只能适用于1灯珠的情况。

http://www.ndiy.cn/forum.php?mod=viewthread&tid=36302&page=1#pid730724

本着DIY折腾的精神,用嵌入汇编的方式重写了驱动,最后发现更笨,需要发三次,有机会再改进。

/*发送24位字符(包含RGB信息各8位)*/
// 24M

void WS2812_SendRGB(uchar r, uchar g, uchar b) {
#pragma ASM
    CLR      WS5050_DI
;    // [email protected]
    MOV R6,#160
NEXT:
    DJNZ R6,NEXT

;---- green
    MOV      R6,#8
    MOV      A,R5
R_LOOP_PHASE0:
    SETB    WS5050_DI
    NOP
    NOP
    RLC      A
    JC        R_BIT_1
    CLR        WS5050_DI
    NOP
    NOP
    NOP
    SJMP    R_PHASE3
R_BIT_1:
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    CLR        WS5050_DI
R_PHASE3:
    NOP
    NOP
    DJNZ    R6,R_LOOP_PHASE0

;---- red
    MOV      R6,#8
    MOV      A,R7
G_LOOP_PHASE0:
    SETB    WS5050_DI
    NOP
    NOP
    RLC      A
    JC        G_BIT_1
    CLR        WS5050_DI
    NOP
    NOP
    NOP
    SJMP    G_PHASE3
G_BIT_1:
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    CLR        WS5050_DI
G_PHASE3:
    NOP
    NOP
    DJNZ    R6,G_LOOP_PHASE0

;---- blue
    MOV      R6,#8
    MOV      A,R3
B_LOOP_PHASE0:
    SETB    WS5050_DI
    NOP
    NOP
    RLC      A
    JC        B_BIT_1
    CLR        WS5050_DI
    NOP
    NOP
    NOP
    SJMP    B_PHASE3
B_BIT_1:
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    CLR        WS5050_DI
B_PHASE3:
    NOP
    NOP
    DJNZ    R6,B_LOOP_PHASE0

NOP
    SETB    WS5050_DI
#pragma ENDASM
    r = 0;
    g = 0;
    b = 0;
}

时间: 2024-10-06 13:45:57

STC15点亮WS2812灯珠(C结合汇编)的相关文章

TQ2440按键点亮LED灯的裸机程序

一,说到做ARM的裸机程序,很多人马上就会联想到一个名为ADS的开发工具,但是我们在linux下同样也可以做ARM的裸机程序,下面来说说其具体实施过程: 步骤一:编辑代码,这个没什么好说的. 步骤二:编译代码,编译代码分为三个方面的内容:1.链接脚本 2.用命令行确定链接时的文件顺序 3.用命令行编译.这三部分的内容可以全部写成一个Makefile文件,编译的时候执行make命令就可以了. 步骤三:把编译后的".bin"文件烧写进开发板,重新上电观察效果. 二,TQ2440按键点亮LE

点亮流水灯--位移法

点亮流水灯之位移法 1 #include <reg51.h> 2 #include <stdio.h> 3 //延时函数 4 void delay(){ 5 int i=10000; 6 //用while循环来做兜底循环 7 while(i--); 8 } 9 //主函数 10 void main(void) 11 { 12 int i; 13 char p; 14 while(1) 15 { 16 //点亮第一盏灯 17 P2=0xfe; 18 //调用延时函数 19 delay

第二章之在BL1中点亮LED灯

1,u-boot中第一个入口在./arch/arm/cpu/armv7/start.S 翻到153行:如下图 前面都是进行一些基本设置,不用管. cpu_init_cp15设置协处理器, cpu_init_crit则跳转到其它地方,所以要点板子上电点灯要在152行之前. 2,通过板子资料,通过设置GPIO点亮LED灯,因为了 start.S是用汇编语言写的,所以点亮LED灯也要用汇编语言 代码如下: 1 gpin_out: 2 ldr r11,=0xE0200280 3 ldr r12,=0x0

点亮流水灯--数组法

/* Main.c file generated by New Project wizard * * Created: 周一 五月 8 2017 * Processor: 80C51 * Compiler: Keil for 8051 */ #include <reg51.h> #include <stdio.h> //延时函数 void delay(){ int i=10000; //用while循环来做兜底循环 while(i--); } //主函数 void main(voi

1.2.第一个实验——点亮LED灯

1.2.第一个实验--点亮LED灯 预备知识: (1)位.字节.IO端口.IO口 字节是内存管理的最小单位,一个字节是八位,每一位可以存放一个二进制位(0或者1).一个IO端口包括一组IO口,一般一组是八个,一个端口就是一组IO引脚.一个IO口对应一个二进制位,一个IO端口对应一个字节. (2)二进制和十六进制的转换 一个十六进制位等于四个二进制位,比如0xff对应二进制是1111 1111 实验目的:点亮八颗LED灯 实验过程分析: (1)八颗LED分别由八位二进制位来控制,二进制位是1时LE

TI CC2530基础实验(普通GPIO操作——按一下按键亮一下灯)

有关CC2530的GPIO基本知识.普通GPIO操作有关寄存器的介绍.IAR Embedded Workbench IDE软件使用:TI CC2530基础实验(普通GPIO操作--点亮led灯) 电路原理图: 分析:需要按一下按键亮一下灯,并且不采用中断方式,即我们需要实时去监测按下是否被按下(P0_4为低电平表示按下,高电平表示松开). 设置: 灯LED1对应的P1_0引脚为普通I/O.方向为输出 按键S1对应的P0_4引脚为普通I/O.方向为输入 程序: /*****************

LED灯珠散热的计算方法

LED灯珠散热的计算方法 来源: 时间:2014-09-23 13:55 [编辑:lufieliu] [字体:大 中 小] 我来说两句 一.热对LED的影响 1.LED是冷光源吗? (1)LED的发光原理是电子与空穴经过复合直接发出光子,过程中不需要热量.LED可以称为冷光源. (2)LED的发光需要电流驱动.输入LED的电能中,只有约15%有效复合转化为光,大部分(约85%)因无效复合而转化为热. (3)LED发光过程中会产生热量,LED并非不会发热的冷光源. 2.热对LED性能和结构的影响

树莓派点亮LED灯需要几行代码?3行。小孩子都能学会

目录 点亮LED灯 硬件连接 代码 闪烁的LED灯 呼吸灯 其他 点亮LED灯 硬件连接 找一个LED灯,连接如上图,注意长短引脚,经过这些年的狂轰乱炸,大家对于这个应该不漠视,毕竟Arduino都进教材了. 代码 我们先来看图形化的版本: from gpiozero import LED led = LED(17) led.on() 是的你没有看错,树莓派点亮LED只需要3行代码.只需要像Python的turtle编程一样导入需要用到的LED类,然后生成一个表示连接在17号GPIO引脚的LED

三、点亮LED灯

目标:让LED每秒闪烁1次 材料: 1.SAGOO UNO板1块 2.USB线1根 步骤: 1.用USB线连接Arduino板和PC,电源LED灯亮: 2.启动Arduino IDE软件,打开“File"->"Examples"->"01.Basics"->"Blink"; 3.点击“编译Verify"->"下载Upload"; 4.看到电路板上L标示的LED灯每秒闪烁. 原理图 代