发 帖  
原厂入驻New

【大联大品佳 NXP i.MX RT1050试用体验】基于统NXP i.MX RT1050巡检机器人控制系统

2020-10-18 20:51:00  158 试用体验 机器人 控制系统
分享
0
本帖最后由 mameng 于 2020-10-26 14:49 编辑

   经过两个多月的项目开发,终于可以完结了。本项目是基于统NXP i.MX RT1050 FreeRTOS 和开源的GUI软件做了一个机器人控制系。区园巡检机器人已经开发完毕,本文主要讲解控制系统开发。
系统结构图:
架构.png

  
   所需要的硬件如下:
   IMXRT1050 EVKB开发板 配开发板的4.3寸触控式LCD萤幕,分辨率为480x272的分辨率。型号为: RK043FN02H-CT  ,庆科emw3080低功耗无线模组物联网串口转wIFi模块。


    上.jpg
下.jpg
巡检机器人:
机器人.jpg
     巡检机器人通过IP摄像头局域网把视频传到监控显示器,难点在于设计一个远程无线控制机器人控制系统。具有远程显示机器人运动状态,位置,巡行速度,有误异常,外接传感器状态等。
     经过上几篇试用,已经对 IMXRT1050-EVKB  开发板资源掌握的差不多了。RT1052功能强大,板载接口丰富,适合项目原型开发。本项目难点在于移植frertoshe和GUI显示系统开发。对比当前主流的嵌入式 GUI 主要有:emWin(uCGUI),TouchGFX,Embedded Wizard GUI,uGFX 和 microchip GUI。
     TouchGF,被ST收购,以界面华丽,流畅以及强劲的 TouchGFX Designer(即将发布正式版)著称。 官方地址:http://touchgfx.com/en/ 。 TouchGFX 是要收费的,
     Embeded Wizard GUI 也是这两年才发布的嵌入式 GUI,同样以华丽,流畅的界面和强劲的GUIBuilder 著称。 官方地址:http://www.embedded-wizard.de/    Embeded Wizard GUI IDE 也是要收费的,免费的教育版本不能商用,需要翻墙才能下载。
      很早就注意到LittlevGL,LittlevGL 是一个免费的开源图形库,提供了创建嵌入式 GUI 所需的一切,具有易于使用的组件,美观的视觉效果和低内存占用等特点。支持触摸屏操作,移植简单方便,开发者一直在不断完善更新。
    LittlevGL 自带了丰富的控件:窗口、按键、标签、list、图表等,还可以自定义控件;支持很多特效:透明、阴影、自动显示隐藏滚动条、界面切换动画、图标打开关闭动画、平滑的拖拽控件、分层显示、反锯齿、仅耗少量内存的字体等等。
    LittlevGL 系统包括应用程序,LVGL图形库以及Driver特定驱动程序,其中应用程序创建GUI,并处理特定任务的应用程序。应用程序可以与图形库进行通信并创建GUI,它包含HAL硬件抽象层接口,用于注册显示和输入设备驱动程序。Driver 除了应用中用到的特定驱动程序,它包含用于驱动显示的功能,另外可选的是包含读取触摸板或者按键输入驱动程序。根据MCU的不同,有两种典型的显示硬件设置。一个内置LCD/TFT驱动,另一个没有内置驱动。在这两种情况下,都需要一个帧缓冲区来存储屏幕的当前图像。
    I.MXRT1050/1060有TFT/lcd驱动程序,则可以通过RGB接口直接连接MCU液晶显示器。在这种情况下,帧缓冲器可以在内部RAM中(如果MCU有足够的RAM)或者在外部RAM中(如果MCU具有存储器扩展接口)。入手相当方便。
        目前LittlevGL  源码下载地址。
https://github.com/lvgl/lvgl/blob/master/lvgl.h
https://gitee.com/mirrors/lvgl
  移植过程分析:
   1,修改屏幕分辨率
如果需要根据实际屏幕支持不同大小的分辨率,需要修改参数为如下设置。
  在lv_conf_internal.h中修改分辨率大小。
#define LV_HOR_RES_MAX         480
#define LV_VER_RES_MAX        272
在fsl_elcdif.c中修改LCD屏的配置函数参数如下。
void ELCDIF_RgbModeGetDefaultConfig(elcdif_rgb_mode_config_t *config)
{
    assert(config);
    memset(config, 0, sizeof(*config));
    config->panelWidth = 1024U;
    config->panelHeight = 600U;
    config->hsw = 41;
    config->hfp = 160; //4;
    config->hbp = 160; //8;
    config->vsw = 10;
    config->vfp = 12;//4;
    config->vbp = 23;//2;
    config->polarityFlags = kELCDIF_VsyncActiveLow | kELCDIF_HsyncActiveLow | kELCDIF_DataEnableActiveLow |kELCDIF_DriveDataOnFallingClkEdge;
    config->bufferAddr = 0U;
    config->pixelFormat = kELCDIF_PixelFormatRGB888;
    config->dataBus = kELCDIF_DataBus24Bit;

}
  2.修改显存大小
在单芯片MCU的设计中,不采用外扩RAM的情况下,如何修改I.MXRT的内存大小来适配更大的图像显存。如下为了配置448K TCM的RAM空间,需要在SDK代码里面修改如下部分,在MCUXpresso配置里面设置内存分配大小,OCRAM需要保留最小64K空间,这是由于Boot ROM的要求。
   第一步:startup文件修改
不需要配置GPR14寄存器,它和FlexRAM配置无关,只需要添加如下代码到启动文件中。
LDR     R0, =0x400ac044
LDR     R1, =0xaaaaaaa5     //FlexRAM 配置设置
STR     R1,[R0]
LDR     R0,=0x400ac040
LDR     R1,=0x04
LDR     R3,[R0]
ORR     R2,R1,R3
STR     R2,[R0]
需要注意的是,在使用前修改FlexRAM的配置,因此推荐将上述代码放在reset handler, NXP也提供了FlexRAM相关的使用应用笔记如下。
https://www.nxp.com/docs/en/application-note/AN12077.pdf

    第二步:MPU文件修改
    ARM只指定普通内存支持非对齐访问,而默认的SDK中只将芯片出厂默认内存配置为普通内存,因此需要将BOARD_ConfigMPU里面的配置做如下修改。
/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(4, 0x20000000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_256KB);
/* Region 6 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(5, 0x20200000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_512KB);
/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(6, 0x20040000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_128KB);
/* Region 5 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(7, 0x20060000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64KB);
/* Region 7 setting: Memory with Normal type, not shareable, outer/inner write back */
MPU->RBAR = ARM_MPU_RBAR(8, 0x20280000U);
MPU->RASR = ARM_MPU_RASR(0, ARM_MPU_AP_FULL, 0, 0, 1, 1, 0, ARM_MPU_REGION_SIZE_64KB); //Flexram
    第三步:OCRAM使用的注意事项
    如果数据全部放在OCRAM里面,需要注意清Cache,防止在LCD显示的时候,下一帧的数据将下一帧的数据重叠,导致出现花屏或者是屏幕抖动。一般来说,OCRAM用于存储局部变量、堆和栈。I/DTCM(FlexRAM组配置为TCM)可以直接通过CPU访问,绕过一级L1 cache,因此,建议将关键代码和需要快速处理的数据放在TCM,例如向量表等。
3,文件配置
    LVGL有一个配置头文件lv_conf.h,它设置了库的基本参数,禁用未使用的模块和特性、在编译时调整内存缓存区的大小等等。 复制lvgl目录旁边的lvgl/lv_conf_template.h,并将其重命名为lv_conf.h。打开文件并将开头的“if 0”更改为“#if 1”以启用其内容。当然lv_conf.h也可以复制到其他地方,但是应该将LV_CONF_INCLUDE_SIMPLE定义到编译器选项中(例如,针对gcc编译器 -DLV_CONF_INCLUDE_SIMPLE ),并手动设置include的路径。
  在配置文件中,至少检查这三个配置选项,并根据硬件进行修改。LV_HOR_RES_MAX 最大水平分辨率;LV_VER_RES_MAX 最大垂直分辨率;LV_COLOR_DEPTH 颜色深度,8 适用于RG332,16适用于RGB565或者32 用于RGB888 和ARGB8888。
       最高参考NXP 官方SDK ,有移植好的案例,对开发事倍功半。

  下面展示一下GUI界面:
1.jpg

2.jpg

3.jpg

   WIFI模组通过配网流程
  WIFI模组通过串口发送AT命令,得到模组回复,关键是判定AT是否成功。
WIFI.jpg
WiFi2.jpg
W3.jpg
/**
*设置需要得到的回复命令
*
*/
int SetNeedRespondData(char workState,char checkType, char *cmd, uint8_t *data, int dataLen, char *state)
{
        
        int flag = 0;
        memset(&gNeedRespond, 0, sizeof(TNeedRespond));
        if(cmd)
        {
                memcpy(gNeedRespond.cmd, cmd, strlen(cmd));
                flag = 1;
        }
        if(data && dataLen > 0)
        {
                memcpy(gNeedRespond.data, data, dataLen);
                gNeedRespond.dataLen = dataLen;
                flag = 1;
        }
        if(state)
        {
                memcpy(gNeedRespond.state, state, strlen(state));
                flag = 1;
        }
        gNeedRespond.workState = workState;
        gNeedRespond.checkType = checkType;
        gNeedRespond.count = 3;
        gNeedRespond.flag = flag;
        return 0;
}


/**
*设置需要得到的回复命令
*
*/
int SetNeedRespondRespondState(char respondState)
{
        
        if(gNeedRespond.flag)
        {
                gNeedRespond.respondState = respondState;
                printf("SetNeedRespondRespondState respondState=%d\r\n",gNeedRespond.respondState);
        }
        return 0;
}


/**
*获取需要回复命令缓存
*
*/
PNeedRespond GetNeedRespondData(void)
{
        
        return &gNeedRespond;
}

/**
*清除需要回复命令缓存
*
*/
void ClearNeedRespondData(void)
{
        
        memset(&gNeedRespond, 0, sizeof(TNeedRespond));
}


  1. case MODULE_WORK_STATE_NEED_CONNECT_AP:
  2.                         {
  3.                                 printf("MODULE_WORK_STATE_NEED_CONNECT_AP \r\n");
  4.                                 needRespond = GetNeedRespondData();
  5.                                 if( needRespond->workState == MODULE_WORK_STATE_NEED_CONNECT_AP)
  6.                                 {
  7.                                         //说明上一次的AT命令发送并且收到了成功的服务
  8.                                         if(needRespond->respondState == RESPONDE_STATE_OK)
  9.                                         {
  10.                                                 gModuleWorkState = MODULE_WORK_STATE_NEED_CHECK_CONNECT_AP_STATE;
  11.                                                 printf("MODULE_WORK_STATE_NEED_CONNECT_AP CMD OK\r\n");
  12.                                                 ClearNeedRespondData();
  13.                                                 break;
  14.                                         }
  15.                                         else if(needRespond->respondState == RESPONDE_STATE_IDEL)
  16.                                         {
  17.                                                 //说明还没收到回复
  18.                                                 break;
  19.                                         }
  20.                                 }
复制代码
https://v.youku.com/v_show/id_XNDkxMTkzNTc0NA==.html?x=&sharefrom=android&sharekey=eca5cd2c358cd171d0e71203a0b7c4fe4
https://v.youku.com/v_show/id_XNDkxMTkzNTc0NA==.html?x=&sharefrom=android&sharekey=eca5cd2c358cd171d0e71203a0b7c4fe4
下位机程序.jpg
mameng 2020-10-19 08:12:51
参考程序:
链接:https://pan.baidu.com/s/1J2QZcbBLvSTpLkyVwEhqog
提取码:mwdg
复制这段内容后打开百度网盘手机App,操作更方便哦
回复

举报

只有小组成员才能发言,加入小组>>

95个成员聚集在这个小组

加入小组

创建小组步骤

关闭

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

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