0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

任意单片机基于simulink模型开发方式

CHANBAEK 来源: 想啥做啥 作者: 想啥做啥 2023-11-30 15:27 次阅读

导言-一个基于模型的例子

使用Arduinosimulink中搭建的LED闪烁的一个例子如图1所示,相比之前C语言代码实现的方式,这里没有写一行代码就实现了LED闪烁。读者有没有感觉这种开发方式即简单又方便,要实现什么功能就直奔主题,不用一行一行的敲代码、排查代码错误。图1只是arduino其中的I/O输出外设,在图2中还有其它很多外设可以使用,再结合matlab强大的功能,读者可以实现很多实际应用。

图片

图1 Arduino-simulink的LED闪烁模型

图片

图2 simulink中arduino其它外设的模型

任意单片机基于模型开发方式

并不是每一个芯片厂商都有足够的人力和资金投入到主流开发软件的生态适配,目前除了市面上用的比较火的几款单片机(STM32、TMS320F28xx、S32K等)和Arduino平台可以直接使用Matlab的硬件支持包直接开发外,其它单片机没办法直接使用,这里给大家介绍一种万能的方式,可以在任意单片机上使用基于Simulink模型开发方式。

1、8051单片机上运行Simulink模型代码

第1步:搭建Simulink模型

如图3 所示,,这里使用了三个库,分别是“Delay(延时模型)”、“Logical Operator-NOT(逻辑操作-非模型)”和“out(输出端口模型)”,这里的输出端口为了方便代码移植将名字改为LED。

图片

图3 LED闪烁simulink模型

第2步:设置模型生成参数并生成代码

如图4所示,点击按钮“Model Configuration Parameters”对simulink进行设置。

图片

图4 simulink设置按钮

如图5所示,在弹出的“Configuration Parameters:xxxx”窗口中找到“Solver”栏,并点击设置运行参数,按照图中的设置,完成后点击“Apply”。

图片

图5 “Solver”栏参数设置

如图6所示,在“Hardware Implementtation”栏中设置硬件参数,按照图中的设置进行操作,完成后点击“Apply”。

图片

图6 “Hardware Implementtation”栏参数设置

如图7所示,点击“Code Generation”栏,设置代码生成参数,完成后点击“Apply”。

图片

图7 “Code Generation”参数设置

如图8所示,点开“Code Generation”左边的“>”符号,在子栏目中找到“Code Style”项设置代码生成风格,完成后点击“Apply”。

图片

图8 “Code Style”栏设置

如图9所示,点开“Code Generation”左边的“>”符号,在子栏目中找到“Code Placement”中设置“File packaging format”参数,完成后点击“Apply”,到这一步,所有参数都设置完成,然后点击“OK”按钮。

图片

图9 “Code Placement”栏设置

如图10所示,点击按钮“Build Model”生成代码。

图片

图10 点击生成模型代码

代码生成根据电脑性能不同,需要的时间也不一样,稍等一会儿,弹出“Code Generation Report”窗口报告,如图11所示,在这个窗口中可以看到整个模型生成了三个文件,分别是“ert_main.c”、"LED_Blink.c"和"LED_Blink.h",然后在LED_Blink.slx文件所在的目录下多了一个“LED_Blink_ert_rtw”名字的文件夹,生成的三个文件也包含在当中;看这三个代码有点像之前讲的模块化编程方式命名。

图片

图11 LED_Blink模型代码生成报告

第3步:将simulink生产的代码添加到8051单片机工程中

这一步也是整个过程中最关键部分,也是在很多资料中一直没讲清楚的部分,将生成的代码移植到51单片机工程中去。先新建一个名字(其它名字也可以,只要正确建立Keil工程即可)为“LED_Blink”的Keil工程,工程的存放路径放在刚刚模型生成代码"Blink→LED_Blink_ert_rtw“文件夹下,如图12所示。

图片

图12 在生成模型文件夹下建一个Keil工程

打开刚刚建立的Keil工程,将ert_main.c和LED_Blink.c文件添加到”Source Group 1“中,如图13所示。

图片

图13 模型代码添加

在刚刚添加的文件中双击打开ert_main.c,在下面代码位置处加入8051单片机的内容,代码如下所示:

#include < stddef.h >
#include < stdio.h >                     /* This ert_main.c example uses printf/fflush */
#include "LED_Blink.h"                 /* Model's header file */
#include "rtwtypes.h"


#include < REGX52.H >                   /* 添加51单片机头文件 */




/*********** 变量定义 *************/


#define MAIN_CLOCK      12000000
#define SYSTEM_DELAY    1000        /* 系统周期1ms */


#define LED_TASK_TIME   500         /* SYSTEM_DELAY*0.500 = 500ms任务 */




uint16_T LED_Task_Count = LED_TASK_TIME;  /* 任务定时器变量 */


void SYSTEM_T0_Init( void );              /* 定时器0初始化函数 */

添加单片机代码

然后在ert_main.c文件中添加定时器初始化代码,如下所示:

void SYSTEM_T0_Init( void )
{
    /* 定时器0配置为16位定时器,当溢出时手工重装 */
    /* 清除所有有关T0的位 (T1不变) */
    TMOD &= 0xF0; 
    /* 设置所需的T0相关位 (T1 不变) */
    TMOD |= 0x01; 


    /* 停止定时器0 */
    TR0 = 0;        

    /* 设置定时器重装值 */
    /* 我们这里设置1ms产生一次中断 */
    /* 定时器低8位赋值 */
    TL0  = 65536 -(MAIN_CLOCK/SYSTEM_DELAY/12);      
    /* 定时器高8位赋值 */
    TH0  = (65536-(MAIN_CLOCK/SYSTEM_DELAY/12)) >>8; 

    /* 启动T0 */
    TR0  = 1;

    /* 使能定时器T0中断 */
    ET0  = 1;
}

在ert_main.c中编写定时器中断代码,如下所示:

/*************************************
** 函 数 名:SYSTEM_Tick_Update() interrupt 1
** 输入参数:none
** 返 回 值:none
** 说    明:定时器T0中断入口函数
**************************************/
void SYSTEM_Tick_Update( void ) interrupt 1
{

    /* 停止定时器0 */
    TR0 = 0;        


    /* 设置定时器重装值 */
    /* 我们这里设置1ms产生一次中断 */
    /* 定时器低8位赋值 */
    TL0  = 65536 -(MAIN_CLOCK/SYSTEM_DELAY/12);      
    /* 定时器高8位赋值 */
    TH0  = (65536-(MAIN_CLOCK/SYSTEM_DELAY/12)) >>8; 


    /* 启动T0 */
    TR0  = 1;


    /* LED Task 任务计时器*/
    LED_Task_Count--;
}

定时器中断函数代码

在main主函数中对代码进行修改,如下所示:

int_T main()
{


    /* Initialize model */
    LED_Blink_initialize();

    /* 定时器0 初始化 */
    SYSTEM_T0_Init();

    /* 使能总中断,这样定时器0才会启动 */ 
    EA = 1;


    /* Attach rt_OneStep to a timer or interrupt service routine with
     * period 0.2 seconds (the model's base sample time) here.  The
     * call syntax for rt_OneStep is
     *
     *  rt_OneStep();
     */
      while (rtmGetErrorStatus(LED_Blink_M) == (NULL)) {
    /*  Perform other application tasks here */
    if(LED_Task_Count<=0)
       {
            LED_Task_Count = LED_TASK_TIME;

            rt_OneStep();

            /*输入/输出接口放置位置*/ 
            P1_0 = LED_Blink_Y.LED;

       }
    }


    /* Disable rt_OneStep() here */


    /* Terminate model */
    LED_Blink_terminate();
    return 0;
}

main函数中代码

第4步:编译Keil工程并运行代码

点击Keil编译按钮编译代码,然后将代码烧录到实际芯片中或使用Pretous仿真验证代码。到这里大家就完成了在51单片机上实现LED闪烁Simulink模型代码移植的例子,LED闪烁的频率实际由宏定义#define LED_TASK_TIME 500来控制,在8051单片机上运行该代码时LED将以500ms的周期翻转。

2、simulink生成模型代码剖析

关于8051单片机怎么搭建简单操作系统框架可以参考网络上其他文章或关注作者的后续文章,这里就不再赘述,如图14所示的LED闪烁模型,实际上就是运行模型生成的rt_OneStep()函数,每个Simulink生成的模型里面都会有这个函数,rt_OneStep()运行完之后所有通过输入端的数据都会在搭建的模型逻辑中处理,然后通过输出端输出处理完后的数据,在LED闪烁模型中,没有输入端,只有输出端,所以模型每运行完一次,里面的逻辑翻转一次输出端口LED状态,即LED_Blink_Y.LED的数据,然后只需将模型输出端口与实际物理端口关联即可,这里关联的是P1_0端口,则最终表现出来的效果就是P1_0状态,即模型每运行一次,P1_0端口电平发生一次翻转,P1_0端口有连接LED,LED就会一直闪烁。

图片

图14 基于模型LED程序执行流程

下面再深入到rt_OneStep()函数详细了解下它到底在里面做了什么事情,是不是与前面所说的一致,rt_OneStep()函数详细内容,函数中的其它内容暂时不管,可以看到里面关键的一步,调用了LED_Blink_step()函数,具体代码如下所示:

void rt_OneStep(void)
{
    static boolean_T OverrunFlag = false;


    /* Disable interrupts here */


    /* Check for overrun */
    if (OverrunFlag) {
        rtmSetErrorStatus(LED_Blink_M, "Overrun");
        return;
    }


    OverrunFlag = true;


    /* Save FPU context here (if necessary) */
    /* Re-enable timer or interrupt here */
    /* Set model inputs here */


    /* Step the model */
    LED_Blink_step();


    /* Get model outputs here */


    /* Indicate task complete */
    OverrunFlag = false;


    /* Disable interrupts here */
    /* Restore FPU context here (if necessary) */
    /* Enable interrupts here */
}

然后再到LED_Blink_step()函数中查看具体内容,在主函数中调用的LED_Blink_Y.LED在该函数中可以找到具体的逻辑。至此,LED闪烁模型的整个代码分析完成。其它模型也可以采用类似的方式来分析,具体代码如下所示:

void LED_Blink_step(void)
{
    boolean_T rtb_Delay;


    /* Delay: '< Root >/Delay' */
    rtb_Delay = LED_Blink_DW.Delay_DSTATE[0];


    /* Outport: '< Root >/LED' incorporates:
     *  Delay: '< Root >/Delay'
     */
    LED_Blink_Y.LED = LED_Blink_DW.Delay_DSTATE[0];


    /* Update for Delay: '< Root >/Delay' incorporates:
     *  Logic: '< Root >/Logical Operator'
     */
    LED_Blink_DW.Delay_DSTATE[0] = LED_Blink_DW.Delay_DSTATE[1];
    LED_Blink_DW.Delay_DSTATE[1] = !rtb_Delay;
}
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 单片机
    +关注

    关注

    6002

    文章

    43982

    浏览量

    620915
  • C语言
    +关注

    关注

    180

    文章

    7534

    浏览量

    128840
  • Simulink
    +关注

    关注

    22

    文章

    513

    浏览量

    61572
  • 模型
    +关注

    关注

    1

    文章

    2707

    浏览量

    47706
  • Arduino
    +关注

    关注

    184

    文章

    6428

    浏览量

    184852
收藏 人收藏

    评论

    相关推荐

    单片机开发与Linux开发区别 精选资料分享

    编程,这种开发方式主要应用于一些低端的ARM芯片上,其开发过程非常类似单片机,这里不多叙述。还有一种是在
    发表于 07-13 08:14

    单片机开发与Linux开发区别 精选资料推荐

    编程,这种开发方式主要应用于一些低端的ARM芯片上,其开发过程非常类似单片机,这里不多叙述。还有一种是在...
    发表于 07-13 08:46

    使用simulink开发51单片机

    前言:越来越多的嵌入式开发开始采用基于模型的设计,基于模型设计采用的主要开发工具是simulink/stateflow,使用
    发表于 07-15 09:23

    [Simulink] Simulink与51单片机示例 精选资料分享

    工作。时间原因,只用51单片机做了简单的示例,用来说明一下具体的开发方法,示例简单,没有进行建模规范检查,没有test-harness,没有用S-function和TLC写模块,也没有调用KEIL进行...
    发表于 07-22 06:48

    STM32的三种开发方式

    1 STM32的三种开发方式通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的。一般大多数都会选用标准库和HAL库,而极少部分人会通
    发表于 08-05 06:56

    利用Simulink自动生成可以在STM32单片机运行的代码

    刚开始学习利用Simulink自动生成可以在STM32单片机运行的代码,摸索的过程中遇到了很多挫折,希望以这种方式来记录自己的成长与进步,以下的四个案例花了将近4天的时间,经过亲自测试均可正常运行
    发表于 08-17 08:37

    STM32的三种开发方式分享

    STM32的三种开发方式通常新手在入门STM32的时候,首先都要先选择一种要用的开发方式,不同的开发方式会导致你编程的架构是完全不一样的。一般大多数都会选用标准库和HAL库,而极少部分人会...
    发表于 12-01 07:59

    基于单片机的快速代码生成方法

    基于模型设计是国外流行的一种先进的嵌入式系统开发方式,该方式主要利用开发工具Simulink以及Matlab的RTW(Real-TimeWo
    发表于 12-18 16:26 5次下载

    SCADE为嵌入式软件提供了一套基于模型开发方式

    嵌入式技术是计算机发展的趋势之一,被广泛应用于工业和军事领域。SCADE(高安全性的应用程序开发环境)为嵌入式软件提供了一套基于模型开发方式。从嵌入式软件的特点入手,对基于模型的嵌入
    发表于 10-17 10:09 5次下载
    SCADE为嵌入式软件提供了一套基于<b class='flag-5'>模型</b>的<b class='flag-5'>开发方式</b>

    Simulink嵌入式开发--使用simulink开发51单片机(一)

    前言:越来越多的嵌入式开发开始采用基于模型的设计,基于模型设计采用的主要开发工具是simulink/stateflow,使用
    发表于 11-02 19:21 32次下载
    <b class='flag-5'>Simulink</b>嵌入式<b class='flag-5'>开发</b>--使用<b class='flag-5'>simulink</b><b class='flag-5'>开发</b>51<b class='flag-5'>单片机</b>(一)

    记一种兼顾各方优点的51单片机开发方式

    记一种兼顾各方优点的51单片机开发方式1. 需要的软件安装以下软件:keil_c51 (最好是较新的版本,旧版本可能没有生成编译脚本这一功能,无法获得完整的使用体验)VSCode 编辑器
    发表于 11-21 15:21 8次下载
    记一种兼顾各方优点的51<b class='flag-5'>单片机</b><b class='flag-5'>开发方式</b>

    机智云三种APP开发方式介绍

    机智云针对不同开发者的不同需求提供三种APP开发方式,包括集成SDK、使用app开源框架、使用app自动生成,帮助开发者更加快速开发自己的APP。
    的头像 发表于 11-21 15:27 2527次阅读
    机智云三种APP<b class='flag-5'>开发方式</b>介绍

    OpenHarmony应用开发之ETS开发方式Image组件

    今天带大家了解ETS开发方式中的Image组件
    的头像 发表于 07-03 12:06 3073次阅读
    OpenHarmony应用<b class='flag-5'>开发</b>之ETS<b class='flag-5'>开发方式</b>Image组件

    基于模型开发,SImulink建模有哪些优势

    陆续收到粉丝反馈,公司目前新产品开发在走基于模型开发路径,慢慢替代传统手写C代码模式。其实不止电池管理系统(BMS),很多汽车控制器的开发测试都是在用
    的头像 发表于 07-25 15:00 4276次阅读

    先楫hpm_sdk开发方式的优缺点 与单片机传统开发方式的不同点

    最近在跟一些开发者交流过程中,或者开发者群里反馈,感觉先楫单片机开发方式不同于以往的单片机开发方式
    的头像 发表于 09-25 09:16 652次阅读
    先楫hpm_sdk<b class='flag-5'>开发方式</b>的优缺点 与<b class='flag-5'>单片机</b>传统<b class='flag-5'>开发方式</b>的不同点