查看: 5247|回复: 3

[分享] 逐飞LPC55S69 IOT开发板之开箱及及对Seekfree 库的初次印象

[复制链接]
  • TA的每日心情

    2025-5-29 09:38
  • 签到天数: 632 天

    连续签到: 1 天

    [LV.9]以坛为家II

    94

    主题

    1639

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4470

    热心会员

    最后登录
    2025-6-10
    发表于 2020-12-10 16:12:28 | 显示全部楼层 |阅读模式
            今天收到了购买的逐飞LPC55S69 IOT开发板。唉,还是有点忍不住叹气,当时有点脑袋发热就买了。我主要对其不满的是,板上连最小板标配的IIC 的EEPROM和SPI 的FLASH都没有。不带仿真器就算了,连这2基本的外设都没,你让我怎么更新字库,大点的空间开销会不会不够。叹气归叹气,自己种的苦果,含泪也要吃完。CMSIS-DAP 是ARM官方推出的仿真通讯协议,理论通吃M系列。这下仿真烧写器,倒是有现成的。 SSSS.jpg
          买板子的主要目的就是在LPC55S69上面移植GUI,并看下效果如何。150M的频率其实也并不是很高,但是属性低分辨率应该也还行吧。废话不多说,开始工作。先连接好CMSIS-DAP的SWD和串口和板上的SWD和串口0对应的连接起来。逐飞LPC55S69 IOT的这块板,它自己有二次封装了官方的SDK,那就用它封装的库先看看吧,毕竟这也是板子附加值的一部分呢。
          打开GPIO模拟SPI驱动LCD的例子:
    Z1.png
    编译,直接对main里面ili9341_init()右击go to definition,WTF,怎么没反应。之前在网上看到谁MDK的AC6编译器对中文并不是那么友好,只要是支持的编码格式与之前的发生了变化。我把路径改成英文,再次go to definition,这下可以跳转了。我们跳转到GPIO的控制定义代码:
    1. #define ILI9341_SCLK_PIN                {PIO1, PIN02}                                                                                        // 在这里指定 SCLK_PIN        默认 P1.02
    2. #define ILI9341_RST_PIN                        {PIO1, PIN03}                                                                                        // 在这里指定 RST_PIN        默认 P1.03
    3. #define ILI9341_SDIN_PIN                {PIO0, PIN26}                                                                                        // 在这里指定 SDIN_PIN        默认 P0.26
    4. #define ILI9341_CS_PIN                        {PIO1, PIN01}                                                                                        // 在这里指定 CS_PIN                默认 P1.01
    5. #define ILI9341_DC_PIN                        {PIO1, PIN04}                                                                                        // 在这里指定 DC_PIN                默认 P1.04

    6. #define ili9341_sclk(n)                        zf_gpio_output(sclk_pin[0], sclk_pin[1], n)
    7. #define ili9341_rst(n)                        zf_gpio_output(rst_pin[0], rst_pin[1], n)
    8. #define ili9341_sdin(n)                        zf_gpio_output(sdin_pin[0], sdin_pin[1], n)
    9. #define ili9341_cs(n)                        zf_gpio_output(cs_pin[0], cs_pin[1], n)
    10. #define ili9341_dc(n)                        zf_gpio_output(dc_pin[0], dc_pin[1], n)

    11. static uint16_t point_color = BLACK;                        // 默认画点颜色
    12. static uint16_t back_color = WHITE;                                // 背景色

    13. static const uint8_t sclk_pin[2] = ILI9341_SCLK_PIN;
    14. static const uint8_t rst_pin[2] = ILI9341_RST_PIN;
    15. static const uint8_t sdin_pin[2] = ILI9341_SDIN_PIN;
    16. static const uint8_t cs_pin[2] = ILI9341_CS_PIN;
    17. static const uint8_t dc_pin[2] = ILI9341_DC_PIN;
    复制代码
    发现它将一个引脚变量配置成了个2个元素的一维数值,并将元素分别于端口和引脚关联起来。先#define ILI9341_SCLK_PIN,然后又把ILI9341_SCLK_PIN赋给sclk_pin[2] ,然后最终#define ili9341_sclk(n)        zf_gpio_output(sclk_pin[0], sclk_pin[1], n)。
    但是真没看出这样有啥优点,个人觉得还有点绕。直接一步到位也挺好的。 #define ili9341_sclk(n)   zf_gpio_output(PIO1, PIN02, n) 。


    原本NXP官方库里面,对引脚写的函数:
    1. static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output)
    2. {
    3.     base->B[port][pin] = output;
    4. }
    复制代码
    Seekfree库里面的:
    1. void zf_gpio_output (group_index_list group_index, pin_index_list pin_index, bool level)
    2. {
    3.         if(level)
    4.         {
    5.                 GPIO->SET[group_index] |=                                                                                                                         // 对应管脚置位寄存器
    6.                         (0x00000001 << pin_index);                                                                                                                // 对应管脚 bit 写 1 置位
    7.         }
    8.         else
    9.         {
    10.                 GPIO->CLR[group_index] |=                                                                                                                                // 对应管脚复位寄存器
    11.                         (0x00000001 << pin_index);                                                                                                                // 对应管脚 bit 写 1 复位
    12.         }
    13. }
    复制代码
    我们查看到2者控制的寄存器并不一样,我们定位到GPIO的结构体:
    1. /** GPIO - Register Layout Typedef */
    2. typedef struct {
    3. <font color="#ff0000">  __IO uint8_t B[2][32];                           /**< Byte pin registers for all port GPIO pins, array offset: 0x0, array step: index*0x20, index2*0x1 */</font>
    4.        uint8_t RESERVED_0[4032];
    5.   __IO uint32_t W[2][32];                          /**< Word pin registers for all port GPIO pins, array offset: 0x1000, array step: index*0x80, index2*0x4 */
    6.        uint8_t RESERVED_1[3840];
    7.   __IO uint32_t DIR[2];                            /**< Direction registers for all port GPIO pins, array offset: 0x2000, array step: 0x4 */
    8.        uint8_t RESERVED_2[120];
    9.   __IO uint32_t MASK[2];                           /**< Mask register for all port GPIO pins, array offset: 0x2080, array step: 0x4 */
    10.        uint8_t RESERVED_3[120];
    11.   __IO uint32_t PIN[2];                            /**< Port pin register for all port GPIO pins, array offset: 0x2100, array step: 0x4 */
    12.        uint8_t RESERVED_4[120];
    13.   __IO uint32_t MPIN[2];                           /**< Masked port register for all port GPIO pins, array offset: 0x2180, array step: 0x4 */
    14.        uint8_t RESERVED_5[120];
    15. <font color="#ff0000">  __IO uint32_t SET[2];                            /**< Write: Set register for port. Read: output bits for port, array offset: 0x2200, array step: 0x4 */</font>
    16.        uint8_t RESERVED_6[120];
    17. <font color="#ff0000">  __O  uint32_t CLR[2];                            /**< Clear port for all port GPIO pins, array offset: 0x2280, array step: 0x4 */</font>
    18.        uint8_t RESERVED_7[120];
    19.   __O  uint32_t NOT[2];                            /**< Toggle port for all port GPIO pins, array offset: 0x2300, array step: 0x4 */
    20.        uint8_t RESERVED_8[120];
    21.   __O  uint32_t DIRSET[2];                         /**< Set pin direction bits for port, array offset: 0x2380, array step: 0x4 */
    22.        uint8_t RESERVED_9[120];
    23.   __O  uint32_t DIRCLR[2];                         /**< Clear pin direction bits for port, array offset: 0x2400, array step: 0x4 */
    24.        uint8_t RESERVED_10[120];
    25.   __O  uint32_t DIRNOT[2];                         /**< Toggle pin direction bits for port, array offset: 0x2480, array step: 0x4 */
    26. } GPIO_Type;
    复制代码
    我们打开参考手册:
    B寄存器的介绍(按BYTE读写GPIO):
    Z2.png
    W寄存器(按字或者半字读写GPIO)
    Z4.png
    SET、CLR、NOT寄存器的介绍:
    Z3.png
    这样一比较,两者功能几乎一样,但是B寄存器一个BYTE对应一个引脚,写寄存器时仅最后一个Bit有效。但SET、CLR、NOT每一个BIT对应引脚。
    为啥这样设计,也没想明白何种场合会用到。当然直接对B寄存器控制,代码会比较简洁一点。
    在读取GPIO引脚上也能很好的体现:
    NXP:
    1. static inline void GPIO_PinWrite(GPIO_Type *base, uint32_t port, uint32_t pin, uint8_t output)
    2. {
    3.     base->B[port][pin] = output;
    4. }
    复制代码
    Seekfree:
    1. bool zf_gpio_read (group_index_list group_index, pin_index_list pin_index)
    2. {
    3.         uint32_t data = GPIO->PIN[group_index];                                                                                                                        // 读取对应组别状态寄存器
    4.         return ((uint8_t)(data >> pin_index) & 0x00000001);                                                                                        // 返回对应管脚状态
    5. }
    复制代码

    这里的延时函数,没有向通常一样用systick ,而是用了utick。LPC55S69一共有3个systick也是够变态。utick虽然跟主时钟不是完全同步,有少许延时,但也够用了。而且我觉得utick这个定时器设定的其实还是挺巧妙的。可能我少见多怪。
    Z11.png
    没有重载数据的寄存器,但时CTL寄存器里面最高位为REPEAT标志,0:运行一次 1:重复运行。
    这里Uticks时钟设置为1M,一次计数就是1us。由于被REPEAT标志占了一位,实际存放延时的只有31位。2^31=2147483648us,
    即  2147s,所以下面才对输入的延时最大值做了限制。
    1. <blockquote>//-------------------------------------------------------------------------------------------------------------------
    复制代码
    //-------------------------------------------------------------------------------------------------------------------
    //        @brief                延时函数
    //        @param                delay_count                延时操作数
    //        Sample usage:                                delay( delay_count );
    //-------------------------------------------------------------------------------------------------------------------
    void delay (uint32_t delay_count)
    {
    #ifndef RT_THREAD
            if(delay_count > 2000)
                    delay_count = 2000*1000000;
            else
                    delay_count *= 1000000;

            zf_utick_settick_no_interrupt(delay_count, UTICK_MODE_SINGLE);
            while(!(zf_utick_get_status() & UTICK_STAT_INTR_MASK)){}
            zf_utick_clear_status();
    #else
            rt_thread_mdelay(delay_count*1000);

    #endif
    }

    //-------------------------------------------------------------------------------------------------------------------
    //        @brief                延时函数 ms 级别
    //        @param                delay_count                延时 ms 数
    //        Sample usage:                                delay_ms( 1000 );
    //-------------------------------------------------------------------------------------------------------------------
    void delay_ms (uint32_t delay_count)
    {
    #ifndef RT_THREAD
            if(delay_count > 2000000)
                    delay_count = 2000000*1000;
            else
                    delay_count *= 1000;
            zf_utick_settick_no_interrupt(delay_count, UTICK_MODE_SINGLE);
            while(!(zf_utick_get_status() & UTICK_STAT_INTR_MASK)){}
            zf_utick_clear_status();
    #else
            rt_thread_mdelay(delay_count);
    #endif
    }

    怎么越写越远了,NXP库写的还是很标准的,跟参考手册对得上。上次用个国产的,把我给气的。下载例程,看看屏的刷新速度:
    e.gif
    看起来还不错啊,不知道是因为刷单色的还是啥的,明天弄个正常图片看下。
    整体而言,逐飞LPC55S69 IOT开发板的板子做工啥的还是不错的,库做的虽然有点瑕疵,但整体还是挺好的。
    提个建议:下次再搞开发板,能不能,给板子做4个定位孔,并上好螺柱。












    哎...今天够累的,签到来了~
    回复

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 21:59
  • 签到天数: 1876 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112726
    最后登录
    2025-9-4
    发表于 2020-12-12 11:37:07 | 显示全部楼层
    支持一下,当初双十一我也是差点脑头一热准备出手的,看到手头还有很多全新的评估板,就作罢了……
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

  • TA的每日心情

    2025-5-29 09:38
  • 签到天数: 632 天

    连续签到: 1 天

    [LV.9]以坛为家II

    94

    主题

    1639

    帖子

    2

    版主

    Rank: 7Rank: 7Rank: 7

    积分
    4470

    热心会员

    最后登录
    2025-6-10
     楼主| 发表于 2020-12-12 17:32:26 | 显示全部楼层
    stm1024 发表于 2020-12-12 11:37
    支持一下,当初双十一我也是差点脑头一热准备出手的,看到手头还有很多全新的评估板,就作罢了…… ...

    你那是明智之举啊~~
    哎...今天够累的,签到来了~
    回复 支持 反对

    使用道具 举报

  • TA的每日心情
    奋斗
    昨天 21:59
  • 签到天数: 1876 天

    连续签到: 1 天

    [LV.Master]伴坛终老

    203

    主题

    3万

    帖子

    64

    超级版主

    Rank: 8Rank: 8

    积分
    112726
    最后登录
    2025-9-4
    发表于 2020-12-16 16:31:07 | 显示全部楼层
    胤幻1988 发表于 2020-12-12 17:32
    你那是明智之举啊~~

    给你一个后悔的机会:5块包邮,让给我,哈哈。
    该会员没有填写今日想说内容.
    回复 支持 反对

    使用道具 举报

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

    本版积分规则

    关闭

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

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

    GMT+8, 2025-9-5 09:15 , Processed in 0.087812 second(s), 23 queries , MemCache On.

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.

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