完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
本文介绍一种通过Matlab脚本写入C代码的方法,以实现通过管理表格文件就可以生成具有一定规律的C代码,从而减少人工手写代码的工作量。
1 问题引入 在MBD中,并非所有的代码都适合通过Simulink模型生成。通常来说,会用Simulink模型搭建控制算法,然后将其生成代码。 而一些与配置相关的功能,则会通过人工手写C代码的方式完成。譬如EEPROM配置代码,CAN帧配置代码等,往往通过直接手写会比Simulink建模更加容易实现。 这种手写代码有几个特点: 改动比较频繁。如果需求经常变,那么配置的代码就会经常变。 具有一定规律。比方说很多EEPROM变量按照同种方式赋值给结构体,或者CAN信号按照某种规律装填到某一帧里面 人工手写容易出错。代码看起来眼花缭乱,一不留神就会写错。 所以针对这些问题,博主比较喜欢通过Excel表格,把CAN、EEPROM这些变量的属性管理起来,然后通过脚本读取表格,自动写入C文件和头文件。每次需求变更的时候,只要更新好表格在运行脚本,那然后生成C文件只是一瞬间的事情。 2 需求示例 由于CAN、HWIO和EEPROM的代码在汽车软件团队中的保密级别比较高,所以就没法通过这些来举例了。博主打算通过比较常见的stm32f103的GPIO配置代码,来说明整个流程和思路。 熟悉stm32GPIO配置的博友肯定对下面的led.c的C代码不会陌生,因为这是经典的跑马灯实验中初始化LED灯的C代码。 #include “led.h” void LED_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOE, &GPIO_InitStructure); } 函数主体中包含了使能时钟和引脚的GPIO配置等,其模式都比较固定。 上述C代码中配置了三个引脚PB5,PB6和PE5。可以归纳为一张Excel表格led.xlsx如下: 通过Matlab脚本解析这张表格,提取出GPIO信息,就可以写出对应的led.c文件。 博友如果想运行下面的脚本,可以在Matlab当前路径先新建一个led.xlsx表格,并拷贝下面的表格内容。 [tr]GPIOGPIO_PinGPIO_ModeGPIO_Speed[/tr] BGPIO_Pin_5GPIO_Mode_Out_PPGPIO_Speed_50MHz BGPIO_Pin_6GPIO_Mode_Out_PPGPIO_Speed_50MHz EGPIO_Pin_5GPIO_Mode_Out_PPGPIO_Speed_50MHz 3 示例脚本 这一章节直接把整个生成C文件的函数都贴出来,下一章会一点点的解释博主的思路。 function ManualCode() %% step1 读取表格信息 [~,~,Excel_Cell] = xlsread(‘led.xlsx’,‘led’); CodeText = ‘’; %% step2 将代码内容写入变量CodeText中 %#include头文件 CodeText = [CodeText,‘#include “led.h”’,newline,newline]; %函数以及结构体 CodeText = [CodeText,‘void LED_Init(void)’,newline,‘{’,newline,‘ GPIO_InitTypeDef GPIO_InitStructure;’,newline,newline]; %使能端口时钟 RCCParamater = ‘’; for row = 2:size(Excel_Cell,1) Paramater = [‘RCC_APB2Periph_GPIO’,Excel_Cell{row,1}]; if ~contains(RCCParamater,Paramater) RCCParamater = [RCCParamater,Paramater,‘|’]; end end RCCParamater = RCCParamater(1:end-1); CodeText = [CodeText,‘ RCC_APB2PeriphClockCmd(’,RCCParamater,‘, ENABLE);’,newline,newline]; %端口配置 for row = 2:size(Excel_Cell,1) CodeText = [CodeText,‘ GPIO_InitStructure.GPIO_Pin = ’,Excel_Cell{row,2},‘;’,newline]; CodeText = [CodeText,‘ GPIO_InitStructure.GPIO_Mode = ’,Excel_Cell{row,3},‘;’,newline]; CodeText = [CodeText,‘ GPIO_InitStructure.GPIO_Speed = ’,Excel_Cell{row,4},‘;’,newline]; CodeText = [CodeText,‘ GPIO_Init(GPIO’,Excel_Cell{row,1},‘, &GPIO_InitStructure);’,newline,newline]; end CodeText = [CodeText,‘}’,newline]; %% step3 将变量CodeText写入led.c文件中 fid = fopen(‘led.c’,‘w’); fprintf(fid,CodeText); fclose(fid); end 4 脚本说明 4.1 step1 读取表格信息 第一步很简单,通过xlsread函数把led.xlsx的表格信息读出来,存放在一个单元数组Excel_Cell中。 然后建了一个空的字符串变量CodeText,在后面用于不断地写入C文件内容的信息,最后再一股脑地存到文件中。 4.2 step2 将代码内容写入变量CodeText中 这个step是主体部分,会从头到尾一点一点地写C文件的内容。 4.2.1 头文件、函数名、定义结构体 头文件、函数名和定义结构体都是固定的代码,直接写在CodeText变量中就行了。 脚本运行到这一步,就已经把头文件、函数名、定义结构体写进了CodeText变量中。 4.2.2 使能端口时钟 使能端口时钟这行代码就和表格的第一列相关了。可以看出一共有B和E两种GPIO引脚。 所以代码中的参数应该把B和E都带上。 Matlab脚本中对第一列进行循环和判断,写入CodeText变量。 4.2.3 端口配置 表格的B,C,D列都是端口配置相关信息,通过一个for循环依次写入。写完以后在变量后面再加个花括号}。 4.3 step3 将变量CodeText写入led.c文件中 用fopen函数和fprintf函数,把包含文件内容的CodeText字符串写到led.c文件中,就完成了这个代码自动写入的过程。 5 总结 本文的例子比较简单,也几乎没有涉及字符串操作,只是展现了一个基本思路。基本思路就是通过表格管理代码中的一些关键信息,然后通过脚本识别表格的信息,自动写出C文件或头文件。 这个方法的特点是,在前期制作表格模板以及写脚本的过程中需要花费很多时间去调试并改进。等到后期不断迭代之后,脚本工具会非常成熟,只需要维护表格模板,就可以快速地生成某种格式的手写代码。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1780 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1621 浏览 1 评论
1081 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
728 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1679 浏览 2 评论
1938浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
731浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
570浏览 3评论
596浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
556浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-24 04:55 , Processed in 0.889976 second(s), Total 77, Slave 61 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号