usmart.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569
  1. #include "usmart.h"
  2. #include "usart.h"
  3. #include "sys.h"
  4. #include "delay.h"
  5. //////////////////////////////////////////////////////////////////////////////////
  6. //本程序只供内部使用,未经作者许可,不得用于其它任何用途
  7. //ALIENTEK STM32开发板
  8. //版本:V3.1
  9. //版权所有,盗版必究。
  10. //Copyright(C) 鲁泰电气 2011-2021
  11. //All rights reserved
  12. //********************************************************************************
  13. //升级说明
  14. //V1.4
  15. //增加了对参数为string类型的函数的支持.适用范围大大提高.
  16. //优化了内存占用,静态内存占用为79个字节@10个参数.动态适应数字及字符串长度
  17. //V2.0
  18. //1,修改了list指令,打印函数的完整表达式.
  19. //2,增加了id指令,打印每个函数的入口地址.
  20. //3,修改了参数匹配,支持函数参数的调用(输入入口地址).
  21. //4,增加了函数名长度宏定义.
  22. //V2.1 20110707
  23. //1,增加dec,hex两个指令,用于设置参数显示进制,及执行进制转换.
  24. //注:当dec,hex不带参数的时候,即设定显示参数进制.当后跟参数的时候,即执行进制转换.
  25. //如:"dec 0XFF" 则会将0XFF转为255,由串口返回.
  26. //如:"hex 100" 则会将100转为0X64,由串口返回
  27. //2,新增usmart_get_cmdname函数,用于获取指令名字.
  28. //V2.2 20110726
  29. //1,修正了void类型参数的参数统计错误.
  30. //2,修改数据显示格式默认为16进制.
  31. //V2.3 20110815
  32. //1,去掉了函数名后必须跟"("的限制.
  33. //2,修正了字符串参数中不能有"("的bug.
  34. //3,修改了函数默认显示参数格式的修改方式.
  35. //V2.4 20110905
  36. //1,修改了usmart_get_cmdname函数,增加最大参数长度限制.避免了输入错误参数时的死机现象.
  37. //2,增加USMART_ENTIM2_SCAN宏定义,用于配置是否使用TIM2定时执行scan函数.
  38. //V2.5 20110930
  39. //1,修改usmart_init函数为void usmart_init(u8 sysclk),可以根据系统频率自动设定扫描时间.(固定100ms)
  40. //2,去掉了usmart_init函数中的uart_init函数,串口初始化必须在外部初始化,方便用户自行管理.
  41. //V2.6 20111009
  42. //1,增加了read_addr和write_addr两个函数.可以利用这两个函数读写内部任意地址(必须是有效地址).更加方便调试.
  43. //2,read_addr和write_addr两个函数可以通过设置USMART_USE_WRFUNS为来使能和关闭.
  44. //3,修改了usmart_strcmp,使其规范化.
  45. //V2.7 20111024
  46. //1,修正了返回值16进制显示时不换行的bug.
  47. //2,增加了函数是否有返回值的判断,如果没有返回值,则不会显示.有返回值时才显示其返回值.
  48. //V2.8 20111116
  49. //1,修正了list等不带参数的指令发送后可能导致死机的bug.
  50. //V2.9 20120917
  51. //1,修改了形如:void*xxx(void)类型函数不能识别的bug。
  52. //V3.0 20130425
  53. //1,新增了字符串参数对转义符的支持。
  54. //V3.1 20131120
  55. //1,增加runtime系统指令,可以用于统计函数执行时间.
  56. //用法:
  57. //发送:runtime 1 ,则开启函数执行时间统计功能
  58. //发送:runtime 0 ,则关闭函数执行时间统计功能
  59. ///runtime统计功能,必须设置:USMART_ENTIMX_SCAN 为1,才可以使用!!
  60. //V3.2 20140828
  61. //1,修改usmart_get_aparm函数,加入+/-符号的支持
  62. //2,修改usmart_str2num函数,支持负数转换
  63. //V3.3 20160506
  64. //修正usmart_exe函数在USMART_ENTIMX_SCAN为0的时候,报错的bug
  65. /////////////////////////////////////////////////////////////////////////////////////
  66. TIM_HandleTypeDef TIM4_Handler; //定时器句柄
  67. //系统命令
  68. u8 *sys_cmd_tab[]=
  69. {
  70. "?",
  71. "help",
  72. "list",
  73. "id",
  74. "hex",
  75. "dec",
  76. "runtime",
  77. };
  78. //处理系统指令
  79. //0,成功处理;其他,错误代码;
  80. u8 usmart_sys_cmd_exe(u8 *str)
  81. {
  82. u8 i;
  83. u8 sfname[MAX_FNAME_LEN];//存放本地函数名
  84. u8 pnum;
  85. u8 rval;
  86. u32 res;
  87. res=usmart_get_cmdname(str,sfname,&i,MAX_FNAME_LEN);//得到指令及指令长度
  88. if(res)return USMART_FUNCERR;//错误的指令
  89. str+=i;
  90. for(i=0;i<sizeof(sys_cmd_tab)/4;i++)//支持的系统指令
  91. {
  92. if(usmart_strcmp(sfname,sys_cmd_tab[i])==0)break;
  93. }
  94. switch(i)
  95. {
  96. case 0:
  97. case 1://帮助指令
  98. Usart_Send_Str_Data("\r\n");
  99. #if USMART_USE_HELP
  100. Usart_TX_Set(1); //设置为发送模式
  101. delay_us(100);
  102. //**********************************************
  103. //
  104. //**********************************************
  105. printf("------------------------USMART V3.3------------------------ \r\n");
  106. printf(" USMART是由ALIENTEK开发的一个灵巧的串口调试互交组件,通过 \r\n");
  107. printf("它,你可以通过串口助手调用程序里面的任何函数,并执行.因此,你可\r\n");
  108. printf("以随意更改函数的输入参数(支持数字(10/16进制,支持负数)、字符串\r\n"),
  109. printf("、函数入口地址等作为参数),单个函数最多支持10个输入参数,并支持\r\n"),
  110. printf("函数返回值显示.支持参数显示进制设置功能,支持进制转换功能.\r\n");
  111. printf("技术支持:www.openedv.com\r\n");
  112. printf("USMART有7个系统命令(必须小写):\r\n");
  113. printf("?: 获取帮助信息\r\n");
  114. printf("help: 获取帮助信息\r\n");
  115. printf("list: 可用的函数列表\r\n\n");
  116. printf("id: 可用函数的ID列表\r\n\n");
  117. printf("hex: 参数16进制显示,后跟空格+数字即执行进制转换\r\n\n");
  118. printf("dec: 参数10进制显示,后跟空格+数字即执行进制转换\r\n\n");
  119. printf("runtime:1,开启函数运行计时;0,关闭函数运行计时;\r\n\n");
  120. printf("请按照程序编写格式输入函数名及参数并以回车键结束.\r\n");
  121. printf("--------------------------ALIENTEK------------------------- \r\n");
  122. //**********************************************
  123. //
  124. //**********************************************
  125. Usart_TX_Set(0); //设置为接收模式
  126. #else
  127. Usart_Send_Str_Data("\r\n\r\n");
  128. #endif
  129. break;
  130. case 2://查询指令
  131. Usart_TX_Set(1); //设置为发送模式
  132. delay_us(100);
  133. printf("\r\n");
  134. printf("-------------------------函数清单--------------------------- \r\n");
  135. Usart_TX_Set(0); //设置为接收模式
  136. for(i=0;i<usmart_dev.fnum;i++)
  137. {
  138. Usart_TX_Set(1); //设置为发送模式
  139. delay_us(100);
  140. printf("%s\r\n",usmart_dev.funs[i].name);
  141. Usart_TX_Set(0); //设置为接收模式
  142. }
  143. Usart_Send_Str_Data("\r\n\r\n");
  144. break;
  145. case 3://查询ID
  146. Usart_TX_Set(1); //设置为发送模式
  147. delay_us(100);
  148. printf("\r\n");
  149. printf("-------------------------函数 ID --------------------------- \r\n");
  150. Usart_TX_Set(0); //设置为接收模式
  151. for(i=0;i<usmart_dev.fnum;i++)
  152. {
  153. usmart_get_fname((u8*)usmart_dev.funs[i].name,sfname,&pnum,&rval);//得到本地函数名
  154. Usart_TX_Set(1); //设置为发送模式
  155. delay_us(10);
  156. printf("%s id is:\r\n0X%08X\r\n",sfname,usmart_dev.funs[i].func); //显示ID
  157. Usart_TX_Set(0); //设置为接收模式
  158. }
  159. Usart_Send_Str_Data("\r\n\r\n");
  160. break;
  161. case 4://hex指令
  162. Usart_Send_Str_Data("\r\n\r\n");
  163. usmart_get_aparm(str,sfname,&i);
  164. if(i==0)//参数正常
  165. {
  166. i=usmart_str2num(sfname,&res); //记录该参数
  167. if(i==0) //进制转换功能
  168. {
  169. Usart_TX_Set(1); //设置为发送模式
  170. delay_us(100);
  171. printf("HEX:0X%X\r\n",res); //转为16进制
  172. Usart_TX_Set(0); //设置为接收模式
  173. }else if(i!=4)return USMART_PARMERR;//参数错误.
  174. else //参数显示设定功能
  175. {
  176. Usart_Send_Str_Data("16进制参数显示!\r\n");
  177. usmart_dev.sptype=SP_TYPE_HEX;
  178. }
  179. }else return USMART_PARMERR; //参数错误.
  180. Usart_Send_Str_Data("\r\n\r\n");
  181. break;
  182. case 5://dec指令
  183. Usart_Send_Str_Data("\r\n\r\n");
  184. usmart_get_aparm(str,sfname,&i);
  185. if(i==0)//参数正常
  186. {
  187. i=usmart_str2num(sfname,&res); //记录该参数
  188. if(i==0) //进制转换功能
  189. {
  190. Usart_TX_Set(1); //设置为发送模式
  191. delay_us(100);
  192. printf("DEC:%lu\r\n",res); //转为10进制
  193. Usart_TX_Set(0); //设置为接收模式
  194. }else if(i!=4)return USMART_PARMERR;//参数错误.
  195. else //参数显示设定功能
  196. {
  197. Usart_Send_Str_Data("10进制参数显示!\r\n");
  198. usmart_dev.sptype=SP_TYPE_DEC;
  199. }
  200. }else return USMART_PARMERR; //参数错误.
  201. Usart_Send_Str_Data("\r\n\r\n");
  202. break;
  203. case 6://runtime指令,设置是否显示函数执行时间
  204. Usart_Send_Str_Data("\r\n\r\n");
  205. usmart_get_aparm(str,sfname,&i);
  206. if(i==0)//参数正常
  207. {
  208. i=usmart_str2num(sfname,&res); //记录该参数
  209. if(i==0) //读取指定地址数据功能
  210. {
  211. if(USMART_ENTIMX_SCAN==0)
  212. {
  213. Usart_TX_Set(1); //设置为发送模式
  214. delay_us(100);
  215. printf("\r\nError! \r\nTo EN RunTime function,Please set USMART_ENTIMX_SCAN = 1 first!\r\n");//报错
  216. Usart_TX_Set(0); //设置为接收模式
  217. }
  218. else
  219. {
  220. usmart_dev.runtimeflag=res;
  221. if(usmart_dev.runtimeflag)
  222. {
  223. Usart_TX_Set(1); //设置为发送模式
  224. delay_us(100);
  225. printf("Run Time Calculation ON\r\n");
  226. Usart_TX_Set(0); //设置为接收模式
  227. }
  228. else
  229. {
  230. Usart_TX_Set(1); //设置为发送模式
  231. delay_us(100);
  232. printf("Run Time Calculation OFF\r\n");
  233. Usart_TX_Set(0); //设置为接收模式
  234. }
  235. }
  236. }else return USMART_PARMERR; //未带参数,或者参数错误
  237. }else return USMART_PARMERR; //参数错误.
  238. Usart_Send_Str_Data("\r\n\r\n");
  239. break;
  240. default://非法指令
  241. return USMART_FUNCERR;
  242. }
  243. return 0;
  244. }
  245. ////////////////////////////////////////////////////////////////////////////////////////
  246. //移植注意:本例是以stm32为例,如果要移植到其他mcu,请做相应修改.
  247. //usmart_reset_runtime,清除函数运行时间,连同定时器的计数寄存器以及标志位一起清零.并设置重装载值为最大,以最大限度的延长计时时间.
  248. //usmart_get_runtime,获取函数运行时间,通过读取CNT值获取,由于usmart是通过中断调用的函数,所以定时器中断不再有效,此时最大限度
  249. //只能统计2次CNT的值,也就是清零后+溢出一次,当溢出超过2次,没法处理,所以最大延时,控制在:2*计数器CNT*0.1ms.对STM32来说,是:13.1s左右
  250. //其他的:TIM4_IRQHandler和Timer4_Init,需要根据MCU特点自行修改.确保计数器计数频率为:10Khz即可.另外,定时器不要开启自动重装载功能!!
  251. #if USMART_ENTIMX_SCAN==1
  252. //复位runtime
  253. //需要根据所移植到的MCU的定时器参数进行修改
  254. void usmart_reset_runtime(void)
  255. {
  256. __HAL_TIM_CLEAR_FLAG(&TIM4_Handler,TIM_FLAG_UPDATE);//清除中断标志位
  257. __HAL_TIM_SET_AUTORELOAD(&TIM4_Handler,0XFFFF); //将重装载值设置到最大
  258. __HAL_TIM_SET_COUNTER(&TIM4_Handler,0); //清空定时器的CNT
  259. usmart_dev.runtime=0;
  260. }
  261. //获得runtime时间
  262. //返回值:执行时间,单位:0.1ms,最大延时时间为定时器CNT值的2倍*0.1ms
  263. //需要根据所移植到的MCU的定时器参数进行修改
  264. u32 usmart_get_runtime(void)
  265. {
  266. if(__HAL_TIM_GET_FLAG(&TIM4_Handler,TIM_FLAG_UPDATE)==SET)//在运行期间,产生了定时器溢出
  267. {
  268. usmart_dev.runtime+=0XFFFF;
  269. }
  270. usmart_dev.runtime+=__HAL_TIM_GET_COUNTER(&TIM4_Handler);
  271. return usmart_dev.runtime; //返回计数值
  272. }
  273. //下面这两个函数,非USMART函数,放到这里,仅仅方便移植.
  274. //定时器4中断服务程序
  275. void TIM4_IRQHandler(void)
  276. {
  277. if(__HAL_TIM_GET_IT_SOURCE(&TIM4_Handler,TIM_IT_UPDATE)==SET)//溢出中断
  278. {
  279. usmart_dev.scan(); //执行usmart扫描
  280. __HAL_TIM_SET_COUNTER(&TIM4_Handler,0);; //清空定时器的CNT
  281. __HAL_TIM_SET_AUTORELOAD(&TIM4_Handler,100);//恢复原来的设置
  282. }
  283. __HAL_TIM_CLEAR_IT(&TIM4_Handler, TIM_IT_UPDATE);//清除中断标志位
  284. }
  285. //使能定时器4,使能中断.
  286. void Timer4_Init(u16 arr,u16 psc)
  287. {
  288. //定时器4
  289. __HAL_RCC_TIM4_CLK_ENABLE();
  290. HAL_NVIC_SetPriority(TIM4_IRQn,3,3); //设置中断优先级,抢占优先级3,子优先级3
  291. HAL_NVIC_EnableIRQ(TIM4_IRQn); //开启ITM4中断
  292. TIM4_Handler.Instance=TIM4; //通用定时器4
  293. TIM4_Handler.Init.Prescaler=psc; //分频
  294. TIM4_Handler.Init.CounterMode=TIM_COUNTERMODE_UP; //向上计数器
  295. TIM4_Handler.Init.Period=arr; //自动装载值
  296. TIM4_Handler.Init.ClockDivision=TIM_CLOCKDIVISION_DIV1;
  297. HAL_TIM_Base_Init(&TIM4_Handler);
  298. HAL_TIM_Base_Start_IT(&TIM4_Handler); //使能定时器4和定时器4中断
  299. }
  300. #endif
  301. ////////////////////////////////////////////////////////////////////////////////////////
  302. //初始化串口控制器
  303. //sysclk:系统时钟(Mhz)
  304. void usmart_init(u8 sysclk)
  305. {
  306. #if USMART_ENTIMX_SCAN==1
  307. Timer4_Init(1000,(u32)sysclk*100-1);//分频,时钟为10K ,100ms中断一次,注意,计数频率必须为10Khz,以和runtime单位(0.1ms)同步.
  308. #endif
  309. usmart_dev.sptype=1; //十六进制显示参数
  310. }
  311. //从str中获取函数名,id,及参数信息
  312. //*str:字符串指针.
  313. //返回值:0,识别成功;其他,错误代码.
  314. u8 usmart_cmd_rec(u8*str)
  315. {
  316. u8 sta,i,rval;//状态
  317. u8 rpnum,spnum;
  318. u8 rfname[MAX_FNAME_LEN];//暂存空间,用于存放接收到的函数名
  319. u8 sfname[MAX_FNAME_LEN];//存放本地函数名
  320. sta=usmart_get_fname(str,rfname,&rpnum,&rval);//得到接收到的数据的函数名及参数个数
  321. if(sta)return sta;//错误
  322. for(i=0;i<usmart_dev.fnum;i++)
  323. {
  324. sta=usmart_get_fname((u8*)usmart_dev.funs[i].name,sfname,&spnum,&rval);//得到本地函数名及参数个数
  325. if(sta)return sta;//本地解析有误
  326. if(usmart_strcmp(sfname,rfname)==0)//相等
  327. {
  328. if(spnum>rpnum)return USMART_PARMERR;//参数错误(输入参数比源函数参数少)
  329. usmart_dev.id=i;//记录函数ID.
  330. break;//跳出.
  331. }
  332. }
  333. if(i==usmart_dev.fnum)return USMART_NOFUNCFIND; //未找到匹配的函数
  334. sta=usmart_get_fparam(str,&i); //得到函数参数个数
  335. if(sta)return sta; //返回错误
  336. usmart_dev.pnum=i; //参数个数记录
  337. return USMART_OK;
  338. }
  339. //usamrt执行函数
  340. //该函数用于最终执行从串口收到的有效函数.
  341. //最多支持10个参数的函数,更多的参数支持也很容易实现.不过用的很少.一般5个左右的参数的函数已经很少见了.
  342. //该函数会在串口打印执行情况.以:"函数名(参数1,参数2...参数N)=返回值".的形式打印.
  343. //当所执行的函数没有返回值的时候,所打印的返回值是一个无意义的数据.
  344. void usmart_exe(void)
  345. {
  346. u8 id,i;
  347. u32 res;
  348. u32 temp[MAX_PARM];//参数转换,使之支持了字符串
  349. u8 sfname[MAX_FNAME_LEN];//存放本地函数名
  350. u8 pnum,rval;
  351. id=usmart_dev.id;
  352. if(id>=usmart_dev.fnum)return;//不执行.
  353. usmart_get_fname((u8*)usmart_dev.funs[id].name,sfname,&pnum,&rval);//得到本地函数名,及参数个数
  354. Usart_TX_Set(1); //设置为发送模式
  355. delay_us(100);
  356. printf("\r\n%s(",sfname);//输出正要执行的函数名
  357. Usart_TX_Set(0); //设置为接收模式
  358. for(i=0;i<pnum;i++)//输出参数
  359. {
  360. if(usmart_dev.parmtype&(1<<i))//参数是字符串
  361. {
  362. Usart_TX_Set(1); //设置为发送模式
  363. delay_us(100);
  364. printf("%c",'"');
  365. printf("%s",usmart_dev.parm+usmart_get_parmpos(i));
  366. printf("%c",'"');
  367. Usart_TX_Set(0); //设置为接收模式
  368. temp[i]=(u32)&(usmart_dev.parm[usmart_get_parmpos(i)]);
  369. }else //参数是数字
  370. {
  371. temp[i]=*(u32*)(usmart_dev.parm+usmart_get_parmpos(i));
  372. if(usmart_dev.sptype==SP_TYPE_DEC)
  373. {
  374. Usart_TX_Set(1); //设置为发送模式
  375. delay_us(100);
  376. printf("%ld",temp[i]);//10进制参数显示
  377. Usart_TX_Set(0); //设置为接收模式
  378. }
  379. else
  380. {
  381. Usart_TX_Set(1); //设置为发送模式
  382. delay_us(100);
  383. printf("0X%X",temp[i]);//16进制参数显示
  384. Usart_TX_Set(0); //设置为接收模式
  385. }
  386. }
  387. if(i!=pnum-1)
  388. {
  389. Usart_TX_Set(1); //设置为发送模式
  390. delay_us(100);
  391. printf(",");
  392. Usart_TX_Set(0); //设置为接收模式
  393. }
  394. }
  395. Usart_TX_Set(1); //设置为发送模式
  396. delay_us(100);
  397. printf(")");
  398. Usart_TX_Set(0); //设置为接收模式
  399. #if USMART_ENTIMX_SCAN==1
  400. usmart_reset_runtime(); //计时器清零,开始计时
  401. #endif
  402. switch(usmart_dev.pnum)
  403. {
  404. case 0://无参数(void类型)
  405. res=(*(u32(*)())usmart_dev.funs[id].func)();
  406. break;
  407. case 1://有1个参数
  408. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0]);
  409. break;
  410. case 2://有2个参数
  411. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1]);
  412. break;
  413. case 3://有3个参数
  414. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2]);
  415. break;
  416. case 4://有4个参数
  417. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3]);
  418. break;
  419. case 5://有5个参数
  420. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4]);
  421. break;
  422. case 6://有6个参数
  423. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
  424. temp[5]);
  425. break;
  426. case 7://有7个参数
  427. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
  428. temp[5],temp[6]);
  429. break;
  430. case 8://有8个参数
  431. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
  432. temp[5],temp[6],temp[7]);
  433. break;
  434. case 9://有9个参数
  435. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
  436. temp[5],temp[6],temp[7],temp[8]);
  437. break;
  438. case 10://有10个参数
  439. res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
  440. temp[5],temp[6],temp[7],temp[8],temp[9]);
  441. break;
  442. }
  443. #if USMART_ENTIMX_SCAN==1
  444. usmart_get_runtime();//获取函数执行时间
  445. #endif
  446. if(rval==1)//需要返回值.
  447. {
  448. if(usmart_dev.sptype==SP_TYPE_DEC)
  449. {
  450. Usart_TX_Set(1); //设置为发送模式
  451. delay_us(100);
  452. printf("=%lu;\r\n",res);//输出执行结果(10进制参数显示)
  453. Usart_TX_Set(0); //设置为接收模式
  454. }
  455. else
  456. {
  457. Usart_TX_Set(1); //设置为发送模式
  458. delay_us(100);
  459. printf("=0X%X;\r\n",res);//输出执行结果(16进制参数显示)
  460. Usart_TX_Set(0); //设置为接收模式
  461. }
  462. }
  463. else
  464. {
  465. Usart_TX_Set(1); //设置为发送模式
  466. delay_us(100);
  467. printf(";\r\n"); //不需要返回值,直接输出结束
  468. Usart_TX_Set(0); //设置为接收模式
  469. }
  470. if(usmart_dev.runtimeflag) //需要显示函数执行时间
  471. {
  472. Usart_TX_Set(1); //设置为发送模式
  473. delay_us(100);
  474. printf("Function Run Time:%d.%1dms\r\n",usmart_dev.runtime/10,usmart_dev.runtime%10);//打印函数执行时间
  475. Usart_TX_Set(0); //设置为接收模式
  476. }
  477. }
  478. //usmart扫描函数
  479. //通过调用该函数,实现usmart的各个控制.该函数需要每隔一定时间被调用一次
  480. //以及时执行从串口发过来的各个函数.
  481. //本函数可以在中断里面调用,从而实现自动管理.
  482. //如果非ALIENTEK用户,则USART_RX_STA和USART_RX_BUF[]需要用户自己实现
  483. void usmart_scan(void)
  484. {
  485. u8 sta,len;
  486. if(USART3_RX_STA&0x8000)//串口接收完成?
  487. {
  488. len=USART3_RX_STA&0x3fff; //得到此次接收到的数据长度
  489. USART3_RX_BUF[len]='\0'; //在末尾加入结束符.
  490. sta=usmart_dev.cmd_rec(USART3_RX_BUF);//得到函数各个信息
  491. if(sta==0)usmart_dev.exe(); //执行函数
  492. else
  493. {
  494. len=usmart_sys_cmd_exe(USART3_RX_BUF);
  495. if(len!=USMART_FUNCERR)sta=len;
  496. if(sta)
  497. {
  498. switch(sta)
  499. {
  500. case USMART_FUNCERR:
  501. Usart_TX_Set(1); //设置为发送模式
  502. delay_us(100);
  503. printf("函数错误!\r\n");
  504. Usart_TX_Set(0); //设置为接收模式
  505. break;
  506. case USMART_PARMERR:
  507. Usart_TX_Set(1); //设置为发送模式
  508. delay_us(100);
  509. printf("参数错误!\r\n");
  510. Usart_TX_Set(0); //设置为接收模式
  511. break;
  512. case USMART_PARMOVER:
  513. Usart_TX_Set(1); //设置为发送模式
  514. delay_us(100);
  515. printf("参数太多!\r\n");
  516. Usart_TX_Set(0); //设置为接收模式
  517. break;
  518. case USMART_NOFUNCFIND:
  519. Usart_TX_Set(1); //设置为发送模式
  520. delay_us(100);
  521. printf("未找到匹配的函数!\r\n");
  522. Usart_TX_Set(0); //设置为接收模式
  523. break;
  524. }
  525. }
  526. }
  527. USART3_RX_STA=0;//状态寄存器清空
  528. }
  529. }
  530. #if USMART_USE_WRFUNS==1 //如果使能了读写操作
  531. //读取指定地址的值
  532. u32 read_addr(u32 addr)
  533. {
  534. return *(u32*)addr;//
  535. }
  536. //在指定地址写入指定的值
  537. void write_addr(u32 addr,u32 val)
  538. {
  539. *(u32*)addr=val;
  540. }
  541. #endif