Keil+ARM内核下C+汇编混合编程驱动WS2812

使用某些主频比较低的芯片时比如航顺的HK32F030M系列的芯片时,该芯片的主频使用最高32M的内部RC振荡器,没有PLL,没有DMA,对于WS2812这类对时钟频率要求比较高的IC有些困难。虽然使用一些技巧也是可以驱动的,比如直接使用寄存器操作,减少不必要的开销等。

为了将驱动负担降低到底,我尝试使用汇编的方式驱动WS2812,并且取得成功,在MCU工作在32M的状况下,成功将刷新时钟上到800k。

下面介绍一下具体方法。在正常工程中,添加一个新文件(Add New Item),文件类型选择asm (*.s)

;//驱动WS2812的引脚 ,高速翻转达到200ns,
;/*传入参数:
;1.引脚的地址
;2.一个灯的32位数据
;*/
;LED0 EQU  0x48000C18 PD4
    
    AREA DriveWS2812,CODE ,READONLY    
    EXPORT F_DriveWS2812;导出函数
F_DriveWS2812
    PUSH {R0,R1,R2,R3,R4,R5,R6,R7, LR};R2,,R3,R4,R5,R6,R7
    MOVS R7,R1;LSL#8;将参数2的值先向左移8位到数据的24bit高位位置
    MOVS R4,#0x01
    LSLS R4,R4,#23;0x800000
    MOVS R3,#0;R3用于24位计数
    MOVS R5,R0;
    ADDS R5,#0x10;BSx地址改变到BRx地址, 用于复位
    MOVS R6,#0x10;操作寄存器用的值输出Gpio_Pin_4
LOOP
    ADDS R3,R3,#1
    CMP R3,#24
    BHI LOOP_END
    ANDS R7,R7,R4;和0x800000做与后比较

    CMP R7,#0
    BLS DAT0;大于
    STR R6,[R0];输出1
    LSLS R1,R1,#1
    MOVS R7,R1    
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    STR R6,[R5] ;输出0
    B LOOP
DAT0
    STR R6,[R0];输出1    
    LSLS R1,R1,#1
    MOVS R7,R1
    STR R6,[R5] ;输出0
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    NOP
    B LOOP
LOOP_END
    POP {R0,R1,R2,R3,R4,R5,R6,R7,PC};,R2,R3,R4,R5,R6,R7

    
    END

调用方法

{
uint32_t j;
GPIO_INIT();

j=0;
for(i=0;i<32;i++){//驱动灯珠的数量32
    F_DriveWS2812(LEDPIN,j);//汇编函数调用
}
    j++;//颜色

Delay(500);//帧间隔

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

csaaa2005

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值