查看: 1097|回复: 0

[分享] 灯厂们背后的MCU,看LPC如何花式点灯(之四)

[复制链接]
  • TA的每日心情
    开心
    2024-3-26 15:16
  • 签到天数: 266 天

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32014
    最后登录
    2024-4-9
    发表于 2020-10-15 17:58:39 | 显示全部楼层 |阅读模式
    灯厂们背后的MCU,看LPC如何花式点灯(之四)



    前期索引:



    本期介绍如何使用LPC55S69片上的SCT实现驱动WS2812灯带。


    SCT作为LPC系列非常有特色的一个定时器来讲,虽然做WS2812灯控不太划算,但是用WS2812作为例子稍微了解下如何使用SCT是完美的方法。


    在NXP官方的SCT cookbook里也专门有一章讲WS2811的驱动例子的,WS2811的时序和WS2812差不多,当然WS2813也是... 所以攻城狮一直很想用SCT试试,刚好这次一把抓了。


    SCT用来做WS2812的控制有一点不太好,就是需要中断的介入,虽然开销不大,总归没有EZH之类的完全不占资源来的舒服。所以这里还是以学习为主。

    SCT介绍


    SCT是NXP独创的一种定时器,结合了状态机的概念。所以这个SCT定时器既可以完成普通的定时器功能,也可以具有状态机的功能,帮助用户自动切换不同的状态而无需MCU内核参与。具体的使用方面,NXP提供了一份cookbook,里边详细的介绍了SCT可以实现哪些功能,带死区的PWM,多通道PWM,RC5编解码等等。具体搜索AN11538即可。
    6.png
    SCT功能框图

    SCT实现WS281x的优点


    使用cookbook中的例程实现WS281x的控制还是比较简单的,例程使用SCTimer/PWM定时器的半组(16bit)定时器(原理是SCT是一个32bit的定时器,可以拆分成2组16bit的定时器),6个事件(events)和12个状态,基本上这个SCT除了驱动WS281x外还有额外50%的能力去干别的,前提是16bit定时器够用的情况下。
    按照cookbook介绍,使用SCT的好处有
    仅使用了其中1个16bit定时器,另外一个16bit定时器还可以做其他用途

    使用了预分频将SCT的时钟降到最低,以降低功耗

    自动的发送24bit的RGB数据,具有双缓冲的功能

    每帧(既一个WS281x灯颗粒)产生一次中断,为CPU留足了时间处理下一帧的数据

    数据发送完成后SCT自动挂起

    自动产生RESET信号

    SCT针对WS281x的配置

    我们通过配置CONFIG.UNIFY=0来实现拆分SCT为两个16bit定时器。

    匹配寄存器


    MATCH0/MATCHREL0用来控制WS281x的频率,对WS2812来讲就是800kHz
    MATCH1/MATCHREL1用来设置T1H的时间
    MATCH2/MATCHREL2用来设置T0H的时间
    也许你们忘了什么是T1H,什么是T0H,这里放张图恢复下记忆
    7.png

    输入和输出

    给WS281x数据信号的管脚可以是任意SCTx_OUTx,只要我们按照代码要求设置好对应状态下的输出SET和CLR的寄存器即可。
    这里cookbook的实例还用了一个辅助用的输出功能,用来实现双缓冲区机制,也可以把这个输出功能设置到任意SCT输出,也可以不引到实际的物理引脚,具体看用户使用情况。
    我们这次的例子,使用SCT0_OUT5既PIO0_26为WS2812的DATA IN数据输入信号,SCT0_OUT4既PIO1_3为辅助观测的信号输出。
    状态

    利用SCT状态机的机制,可以帮助我们自动的完成WS281x数据的循环发送。由于芯片配置的原因,一些LPC的SCT最多只有15个状态(比如LPC1500),所以我们不得不考虑采用2次burst传输12bits数据(使用了12个状态)方式,完成一个WS281x RGB的数据。
    每个bit传输完成后,状态机会从状态11开始向下做状态迁移。最后一个bit传输完成后,SCT状态机会迁移到状态0,状态机自动切换到状态11并开始下一次12bit的数据传输。状态11意味发送的是最高位(MSB),状态0发送的是最后一个bit(LSB)。
    根据状态机的设置,每当开始传输一个新的bit的时候,SCT的Data OUT输出为高电平,此时SCT的两个匹配寄存器会先设置定时器的T0H(MATCH1,EV13)和T1H(MATCH2,EV14)触发事件,这个触发事件会自动清除Data输出(既输出0)。如果没有新的事件(Event)发生则Data输出信号一直为0。
    为了实现双buffer的机制,这里我们需要另外一个事件来决定在另外一个12个状态里每个状态传输的bit是0还是1。这里官方的例子用的是事件12。
    8.png
    SCT状态配合WS281x信号传输
    SCT如何操作生成
    WS281x的时序


    关于如何操作SCT生成时序,各位可以参考如下步骤:
    配置SCT为Split模式,既16bit计数,分成2个SCTimer


    配置匹配寄存器
    a. MATCHREL0 = 系统时钟/DATA_SPEED - 1
    b. MATCHREL1 = 32% x 系统时钟/DATA_SPEED - 1
    c. MATCHREL2 = 68% x 系统时钟/DATA_SPEED - 1

    配置事件:
    a. 事件 15: MATCH0, 所有状态,DATA = 1 和 STATE += 31
    b. 事件 14: MATCH2, 除了0状态外的所有状态, DATA = 0
    c. 事件 13: MATCH1, 所有状态,DATA = 0
    d. 事件 12: MATCH1 && AUX==0, 所有的状态 [11:0]需要输出逻辑1的, DATA = 1
    e. 事件 11: MATCH1 && AUX==1, 所有的状态 [11:0]需要输出逻辑1的, DATA = 1
    f. 事件 10: MATCH2,状态0, IRQ, AUX = 翻转,STATE = 12


    传输一组数据

    暂停SCT定时器
    预先复位SCT定时器,将WS281x复位的时间值赋值给COUNT_H,以产生复位的低电平信号。

    设置STATE_L 为 12。

    将发送的数据分成2个12bit的数据配置到Event12和Event11的状态寄存器中,确保这两个寄存器的bits[31:12]为0.

    启动定时器L

    中断处理

    当一帧(12bit)的数据传输完成后,会触发一次中断。

    如果是最后一帧,则停止定时器

    读取g_WS2812SCTCount,如果是奇数(既24bit数据头12bit传输完成),则把下次传输的24bit数据拆成2个12bit。如果是偶数(既24bit数据后12bit传输完成),则把上次拆分的2个12bit数据分别配置进Event12和Event11

    中断中配置Event12和Event11
    9.png
    输出的波形

    10.png
    实际的点灯代码


    实际的点灯代码的API,我这边将SPI,EZH,双核,SCT都是统一的,main函数里边的内容一样,参考EZH那篇(之二)末尾介绍的API即可。




    签到签到
    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /4 下一条

    Archiver|手机版|小黑屋|恩智浦技术社区

    GMT+8, 2024-4-24 05:26 , Processed in 0.122595 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

    快速回复 返回顶部 返回列表