关于正点原子USMART的一些理解
功能简介:
有点类似shell指令一样,Linux下的shell是通过输入指令,然后shell脚本去按path路径去寻找相应指令,运行最先找到的那个指令文件。这里实现的机制则是通过串口输入指令,单片串口接受并分析指令,然后匹配对应的指令然后运行并反馈。到这里,这个程序倒是开拓了我的思路,以前没想过使用串口来控制单片机的,最多就是收发一些字符串。由于原子哥的视频长度有限,也可能是他们不想在语法上花费过多时间,所以讲解的就比较的简略,下面我将根据其运行的过程以及一些语法上做出一些解释。
流程分析
1.定时器中断的扫描函数
void TIM4_IRQHandler(void)
{ if(TIM_GetITStatus(TIM4,TIM_IT_Update)==SET)//溢出中断{usmart_dev.scan(); //执行usmart扫描 TIM_SetCounter(TIM4,0); //清空定时器的CNTTIM_SetAutoreload(TIM4,100);//恢复原来的设置 } TIM_ClearITPendingBit(TIM4,TIM_IT_Update); //清除中断标志位
}
原子哥在视频中说过这个的实现过程是通过定时器中断执行这个usmart的扫描函数,下面再看看扫描函数中的具体逻辑,如果在一个工程里面难以寻找到一个中断函数,可以在启动文件中寻找。
2.扫描函数
void usmart_scan(void)
{u8 sta,len; if(USART_RX_STA&0x8000)//串口接收完成?{ len=USART_RX_STA&0x3fff; //得到此次接收到的数据长度USART_RX_BUF[len]='\0'; //在末尾加入结束符. sta=usmart_dev.cmd_rec(USART_RX_BUF);//得到函数各个信息if(sta==0)usmart_dev.exe(); //执行函数 else { len=usmart_sys_cmd_exe(USART_RX_BUF);if(len!=USMART_FUNCERR)sta=len;if(sta){switch(sta){case USMART_FUNCERR:printf("函数错误!\r\n"); break; case USMART_PARMERR:printf("参数错误!\r\n"); break; case USMART_PARMOVER:printf("参数太多!\r\n"); break; case USMART_NOFUNCFIND:printf("未找到匹配的函数!\r\n"); break; }}}USART_RX_STA=0;//状态寄存器清空 }
}
USART_RX_STA是设定一个标志字节,bit7,6是判断是否接受完成并且接受数据是否正确,bit0~5则是接受的字符串长度,可以看出扫描函数的逻辑很简单就是接受数据然后判断数据,然后执行,接下来就是如何对命令进行处理以及运行命令
2.1 usmart处理串口数据
u8 usmart_cmd_rec(u8*str)
{u8 sta,i,rval;//状态 u8 rpnum,spnum;u8 rfname[MAX_FNAME_LEN];//暂存空间,用于存放接收到的函数名 ,//#define MAX_FNAME_LEN 30 u8 sfname[MAX_FNAME_LEN];//存放本地函数名sta=usmart_get_fname(str,rfname,&rpnum,&rval);//得到接收到的数据的函数名及参数个数 if(sta)return sta;//错误for(i=0;i<usmart_dev.fnum;i++){sta=usmart_get_fname((u8*)usmart_dev.funs[i].name,sfname,&spnum,&rval);//得到本地函数名及参数个数if(sta)return sta;//本地解析有误 if(usmart_strcmp(sfname,rfname)==0)//相等{if(spnum>rpnum)return USMART_PARMERR;//参数错误(输入参数比源函数参数少)usmart_dev.id=i;//记录函数ID.break;//跳出.} }if(i==usmart_dev.fnum)return USMART_NOFUNCFIND; //未找到匹配的函数sta=usmart_get_fparam(str,&i); //得到函数参数个数 if(sta)return sta; //返回错误usmart_dev.pnum=i; //参数个数记录return USMART_OK;
}
这里有函数usmart_get_fname(str,rfname,&rpnum,&rval);//得到接收到的数据的函数名及参数个数,其原形是
u8 usmart_get_fname(u8str,u8fname,u8 *pnum,u8 *rval)
这里可以是对指针的一种经典用法,传入两个字符串的地址,然后进行操作,常见一些字符串操作函数,比如大家常用strpcy()之类的,传入参数,修改参数的用法还有更多更复杂的用法,但是其核心原理就是通过指针去修改指针所指向的内存区域,指针指向谁就修改谁,n级指针修改n-1级指针的内存区域,所以遇到指针多画内存的四区模型以后可能会更新,这里挖一个小坑。下面我们先介绍一下这个函数的具体逻辑,
//从str中得到函数名 串口接受到的数据,也就是指令名
//*str:源字符串指针
//*fname:获取到的函数名字指针
//*pnum:函数的参数个数
//*rval:是否需要显示返回值(0,不需要;1,需要)
//返回值:0,成功;其他,错误代码.
u8 usmart_get_fname(u8*str,u8*fname,u8 *pnum,u8 *rval)
{u8 res;u8 fover=0; //括号深度u8 *strtemp;u8 offset=0; u8 parmnum=0;u8 temp=1;u8 fpname[6];//void+X+'/0'u8 fplcnt=0; //第一个参数的长度计数器u8 pcnt=0; //参数计数器u8 nchar;//if(((pcnt&0x7f)==4)&&(*strtemp!='*'))break;//最后一个字符,必须是*//个人感觉这句话应该使用 || //if(((pcnt&0x7f)==4)||(*strtemp ='*'))break;//这样当读完五个字符或者最后一个读是‘*’ 表示指针才算是把参数类型读完整了/*****************************///判断函数是否有返回值strtemp=str;while(*strtemp!='\0')//没有结束{if(*strtemp!=' '&&(pcnt&0X7F)<5)//最多记录5个字符{ if(pcnt==0)pcnt|=0X80;//置位最高位,标记开始接收返回值类型if(((pcnt&0x7f)==4)&&(*strtemp!='*'))break;//最后一个字符,必须是*fpname[pcnt&0x7f]=*strtemp;//记录函数的返回值类型pcnt++;}else if(pcnt==0X85)break;strtemp++; } if(pcnt)//接收完了{fpname[pcnt&0x7f]='\0';//加入结束符if(usmart_strcmp(fpname,"void")==0)*rval=0;//不需要返回值else *rval=1; //需要返回值pcnt=0;} /*****************************///这一块就很简单了,就是跳过空格,不要被循环条件所迷惑了,主要就是跳过所有空格和'*' 主要看offset的值,他会是函数名的前一个位置res=0;strtemp=str;while(*strtemp!='('&&*strtemp!='\0') //此代码找到函数名的真正起始位置{ strtemp++;res++;if(*strtemp==' '||*strtemp=='*'){nchar=usmart_search_nextc(strtemp); //获取下一个字符if(nchar!='('&&nchar!='*')offset=res; //跳过空格和*号}} /*****************************/strtemp=str;if(offset)strtemp+=offset+1;//跳到函数名开始的地方 res=0;nchar=0;//是否正在字符串里面的标志,0,不在字符串;1,在字符串;while(1){if(*strtemp==0){res=USMART_FUNCERR;//函数错误break;}else if(*strtemp=='('&&nchar==0)fover++;//括号深度增加一级 else if(*strtemp==')'&&nchar==0){if(fover)fover--;else res=USMART_FUNCERR;//错误结束,没收到'('if(fover==0)break;//到末尾了,退出 }else if(*strtemp=='"')nchar=!nchar;//根据括号判断函数名是否接受完,一个字符一个字符的传递if(fover==0)//函数名还没接收完{if(*strtemp!=' ')//空格不属于函数名{*fname=*strtemp;//得到函数名fname++;}}else //已经接受完了函数名了.{if(*strtemp==','){temp=1; //使能增加一个参数pcnt++; }else if(*strtemp!=' '&&*strtemp!='('){if(pcnt==0&&fplcnt<5) //当第一个参数来时,为了避免统计void类型的参数,必须做判断.{fpname[fplcnt]=*strtemp;//记录参数特征.fplcnt++;}temp++; //得到有效参数(非空格)}if(fover==1&&temp==2)//temp {temp++; //防止重复增加parmnum++; //参数增加一个}}strtemp++; } if(parmnum==1)//只有1个参数.{fpname[fplcnt]='\0';//加入结束符if(usmart_strcmp(fpname,"void")==0)parmnum=0;//参数为void,表示没有参数.}*pnum=parmnum; //记录参数个数*fname='\0'; //加入结束符return res; //返回执行结果
}
重点先记住几个参数的意义,
关于正点原子USMART的一些理解相关推荐
- 正点原子USMART组件移植
文章目录 一.打开Cube,建立工程 二.系统配置 三.配置测试IO 四.在 Clock Configuration中: 五.工程输出配置 六.开始移植 七.组件分析 MCU:正点原子阿波罗开发板 I ...
- 正点原子USMART使用
USMART是正点原子开发的stm32调试工具,可以通过串口调用相应函数并执行. 1.USMART组件移植 USMART组件共五个文件分别为 usmart.c---------负责与外部互交等 usm ...
- 正点原子USMART 调试组件实验学习笔记(一)
目录 1.简介 2.USMART 组件的移植 1.简介 USMART 是由 ALIENTEK 开发的一个灵巧的串口调试互交组件,通过它你可以通过串口 助手调用程序里面的任何函数,并执行.因此,你可以随 ...
- 正点原子USMART调试学习笔记(二)
软件设计 keilkill.bat,是一个批处理文件,双击,可以删除 MDK 编译过程中产生的中间文件, 从而大大减少整个工程所占用的空间,节省硬盘空间,方便传输. 由于 USMART 默认提供了 S ...
- STM32 USMART源码理解
本文是基于正点原子USMART源码理解. 该组件由 ALIENTEK 开发提供,功能类似 linux 的 shell(RTT 的 finsh 也属于此类).USMART 最主要 的功能就是通过串口调用 ...
- dev c++怎么调试_「正点原子NANO STM32开发板资料连载」第十八章 USMART 调试组件...
1)实验平台:ALIENTEK NANO STM32F411 V1开发板2)摘自<正点原子STM32F4 开发指南(HAL 库版>关注官方微信号公众号,获取更多资料:正点原子 第十八章 U ...
- 【正点原子STM32连载】 第二十六章 USMART调试组件实验 摘自【正点原子】MiniPro STM32H750 开发指南_V1.1
1)实验平台:正点原子MiniPro H750开发板 2)平台购买地址:https://detail.tmall.com/item.htm?id=677017430560 3)全套实验源码+手册+视频 ...
- 正点原子 在ADC实验中添加USMART,通过串口查看电压值
结合了实验十七和实验十四.由于没有买LCD的板子,所以通过串口调试来查看电压值. 目录 一.准备工作:头文件 二.添加一些代码 三.开始调试 一.准备工作:头文件 1.首先将实验十四的USMART文件 ...
- 正点原子中 IIC 例程中SDA_IN()和SDA_OUT()函数理解
在学习正点原子IIC例程时遇到SDA_IN()和SDA_OUT()两个端口模式配置函数,代码如下: //IO口方向设置 #define SDA_IN() {GPIOB->MODER&=~ ...
最新文章
- 海尔、南方电网:这个AI引擎,装它!
- centos 6 上安装l7 filter尝试过滤xunlei
- 三大工厂模式的优缺点
- php+tp框架+API,【路由】利用Thinkphp路由实现API开发版本管理
- 【离散数学】树的基本概念和结论
- java代码的接口_Java代码--简单接口的实现
- Docker学习总结(50)——Docker 微服务优雅关闭
- 数字游戏---巧妙解答
- MyDAL - is null is not null 条件 使用
- Ansible--常用模块
- Spring 菜鸟教程 异常 集锦
- 计算机的用户账户,计算机用户名是什么意思(如何修改和设置用户名)
- 科学网肖波:海外博后申请的一点经验与看法
- 2012中国互联网公司、全球互联网公司最新市值排名(2012.12.06)
- win7的计算机功能在那打开,win7系统照相机功能在哪?win7系统打开照相机功能的方法...
- 全国大学生“高教杯”成图大赛——图错了如何修改
- 热爱可抵岁月漫长,温柔可挡艰难时光—2020年终总结
- 智慧水务信息化平台建设,实现供水一体化管控
- 应用统计学考研要考计算机,应用统计专业考研经验贴
- 半衰期用能量宽度来表示