查看: 1267|回复: 0

灯厂们背后的MCU,看LPC如何花式点灯(之三)

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

    [LV.8]以坛为家I

    3298

    主题

    6545

    帖子

    0

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    32003
    最后登录
    2024-4-9
    发表于 2020-9-24 13:10:30 | 显示全部楼层 |阅读模式
    灯厂们背后的MCU,看LPC如何花式点灯(之三)


    前期索引:






    本期介绍如何使用LPC55S69片上双核机制实现驱动WS2812灯带。
    可能有大神说了,你完全可以用GPIO模拟WS2812的时序啊,何必用SPI和EZH来做。真么说对的,攻城狮认为这么写一篇单独的GPIO模拟WS2812的时序,不太划算太水了, 所以结合双核的应用来这么一篇。一来介绍了GPIO模拟WS2812,二来双核的工程建立和应用也介绍了,内容比较丰富些。


    双核工程创建


    LPC55S69的双核工程可以很方便的用MCUXpresso Config Tool工具创建。
    11.png
    利用MCUXpresso Config Tool和
    SDK的实例模板 创建一个双核工程


    新创建的工程,由于软件小bug,incbin.s并没有加入core0主核的工程,incbin.s 是一段汇编,用于把core1 固件的bin文件链接到core0的image中。
    注意,Core1的固件是存储在Flash中的,上电的时候,由主核Core0搬运到RAM中,再通知Core1运行。
    12.png
    加入incbin.s

    如何把core1的image
    编译进core0的image中


    首先还是分散加载文件,在生成好的工程中,core0的分散加载文件已经给core1的image默认分配了一个空间,这个空间段的名字是m0code,地址从0x00072000,大小是0x00026000,用户可以根据自己的实际需求修改这个起始地址和重新分配空间的大小。
    13.png
    core0关于core1固件安排的地址空间


    前文我们提到了incbin.s,顾名思义incbin是insert binary的缩写,这个汇编文件,会帮我们把core1工程产生的binary文件core1_image.bin在在core0编译的过程中放到core1在分散加载文件中定义的空间段。
    14.png
    incbin.s如何插入core1的image固件


    当然这么设置完,还不够。最后关于双核的设置还有一点,要在KEIL的工程配置选型卡里,选择“Asm”配置include的路径,将core1的image路径设置进来。
    15.png
    Asm include路径配置

    Core1用来做GPIO
    控制驱动WS2812


    由于Core1的代码比较直观且简单,我们就不用流程图来解释了。大概讲下Core1作为小核使用的过程。
    第一步,调用MCMGR_Init()这个API,来初始化SDK提供的双核机制比如通用事件这类功能。
    第二步,获取Core0启动Core1时传来的参数,这个代码里,Core0传递给Core1的是WS2812TxBuf,这个Buffer里包含的LED数据数组的长度和各个LED显示的RGB数据内容。
    第三步,拉低WS2812 Data的IO口,延时大于50uS以上
    第四步,按照每个WS2812TxBuf里实际RGB数据按照bit,翻转GPIO发出0/1 信号
    第五步,发送完成后,调用MCMGR_TriggerEvent() API触发Core0的中断,通知主核Core1完成了WS2812数据的发送。
    最后,调用MCMGR_StopCore() 把自己这个core1关闭掉。
    注意,代码delay的配置是以96MHz主频来定的,如果改变了MCU的主频,这个值需要修改。
    16.png
    Core1代码

    Core0用来做数据整理
    并且通知Core1发送


    这样做的好处是解放了Core0的资源,不会被各种delay函数浪费了资源。
    Core0调用Core1的资源前,要先初始化SDK的双核管理机制MCMGR_Init(),然后将Core1的Image从Flash复制到其本身定义的RAM区域。
    如果需要Core1在完成时触发中断通知,则用MCMGR_RegisterEvent()注册一个回调函数,在Core1中断发出的时候在Core0的中断处理函数中调用这个回调函数。
    17.png
    core0初始化core1的代码


    Core0启动Core1发送数据的方式比较简单,在整理好数据后,直接调用MCMGR_StartCore() API 即可。这里我们希望Core1和Core0之间是异步执行的,所以在第四个形参里使用的是异步模式。
    18.png
    Core0启动Core1


    实际的点灯代码


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


    文章出处:恩智浦MCU加油站

    签到签到
    回复

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2024-4-19 14:54 , Processed in 0.113753 second(s), 22 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

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