51单片机移植ALIENTEK的USMART调试组件
时间:10-02
整理:3721RD
点击:
USMART 调试组件由ALIENTEK 开发提供,功能类似 linux 的 shell(RTT 的 finsh 也属于此类)。
USMART 最主要的功能就是通过串口调用单片机里面的任何函数,并执行。因此,你可以随意更
改函数的输入参数(支持数字 (10/16进制,支持负数)、字符串、函数入口地址等作为参数),单个
函数最多支持 10 个输入参数,并支持函数返回值显示,对我们调试代码是很有帮助的。
USMART是用于STM32上的,由于其方便调试,小编将其移植到51单片机中,使用的单片机为
STC12C5A60S2,晶振为11.0592MHZ。在此写下移植过程分享给大家。
先上图,串口调试助手发送函数让单片机控制继电器吸合与断开。
代码工程结构如下图(感谢原子对我学习stm32的帮助,有些习惯受其影响较大):
第一步:新建delay.c和delay.h文件。
delay.c里主要为定时器0初始化和中断函数。定时器0主要作USMART的扫描函数的100ms的定时。
delay.c里还写里一个简单的延时函数。delay.c里的#include "usmart.h"为原子的usmart提供的文件。
delay.h里主要是函数声明,还有u8 u16等类型定义。
delay.c具体代码如下(由于中文编码方式不一样,代码放过来中文注释全是乱码,就删掉了):
- #include "delay.h"
- #include "usmart.h"
- u32 timer0_num=0;
- /**********************************************************************
- ***********************************************************************/
- void Timer0_init()
- {
- TMOD |= 0x02; //?¨ê±?÷0?£ê?2
- TH0=148; //0.1ms
- TL0=148;
- ET0=1; //?¨ê±?÷0?a???D??
- TR0=1; //?a???¨ê±?÷
- EA=1; //?a??×ü?D??
- }
- /**********************************************************************
- ***********************************************************************/
- void delayms(u16 x)
- {
- u16 j;
- while(x--)
- {
- for(j = 0;j < 85;j ++);
- }
- }
- /**********************************************************************
- ***********************************************************************/
- void Timer0_isr() interrupt 1
- {
- timer0_num++;
- if(timer0_num==1000)
- {
- usmart_dev.scan(); //?′DDusmarté¨?è
- timer0_num=0;
- }
- }
- #ifndef __DELAY_H__
- #define __DELAY_H__
- #include "STC12C5A60S2.H"
- #include <intrins.h>
- /* exact-width unsigned integer types */
- typedef unsigned char u8;
- typedef unsigned int u16;
- typedef unsigned long u32;
- /* exact-width signed integer types */
- typedef signed char int8_t;
- typedef signed int int16_t;
- typedef signed long int32_t;
- void Timer0_init();
- void delayms(u16 x);
- #endif
uart.c里主要是串口的初始化和串口中断函数。这里串口使用的是STC12C5A60S2的串口1,
工作模式1,BRT独立波特率发生器(把定时器1节省出来以备以后使用)。串口中断函数
结构参照usmart接口要求来写。
uart.h里主要是参数设定和函数声明。
uart.c具体代码如下:
- #include "uart.h"
- u8 UART_RX_BUF[UART_REC_LEN]={0}; //?óê??o3?,×?′óUSART_REC_LEN??×??ú
- u16 UART_RX_STA=0; //?óê?×′ì?±ê??
- //bit15£? ?óê?íê3é±ê??
- //bit14£? ?óê?μ?0x0d
- //bit13~0£? ?óê?μ?μ?óDD§×??úêy??
- /**********************************************************************
- ***********************************************************************/
- void uart_init(u32 bound)
- {
- SCON=0X50;
- BRT=-(FOSC/bound/32);
- AUXR=0X15;
- ES=1;
- EA=1;
- }
- void uart_isr() interrupt 4 //(?óê?μ?μ?êy?Y±?D?ê?0x0d 0x0a?á?2)
- {
- u8 Res;
- if(RI)
- {
- Res=SBUF;
- if((UART_RX_STA&0x8000)==0)//?óê??′íê3é
- {
- if(UART_RX_STA&0x4000)//?óê?μ?á?0x0d
- {
- if(Res!=0x0a)UART_RX_STA=0;//?óê?′í?ó,??D??aê?
- else UART_RX_STA|=0x8000; //?óê?íê3éá?
- }
- else //?1??ê?μ?0X0D
- {
- if(Res==0x0d)UART_RX_STA|=0x4000;
- else
- {
- UART_RX_BUF[UART_RX_STA&0X3FFF]=Res ;
- UART_RX_STA++;
- if(UART_RX_STA>(UART_REC_LEN-1))UART_RX_STA=0;
- }
- }
- }
- RI=0;
- }
- }
- #ifndef __UART_H__
- #define __UART_H__
- #include "delay.h"
- #include <stdio.h>
- #define FOSC 11059200L //system frequency
- #define BAUD 9600
- #define UART_REC_LEN 200 //?¨ò?×?′ó?óê?×??úêy 200
- void uart_init(u32 bound);
- #endif
usmart_str.c和usmart_str.h。
usmart.h、usmart_str.c基本不需要改动。
usmart_str.h里把#include "stm32f4xx.h"删掉,替换为#include "delay.h"即可。
usmart_config.c是用户自定义,用户添加自己需要调试的函数。下面附上小编修改后的。
- #include "usmart.h"
- #include "usmart_str.h"
- ////////////////////////////ó??§??????///////////////////////////////////////////////
- //?a????òa°üo??ùó?μ?μ?oˉêy?ùéê?÷μ?í·???t(ó??§×??oìí?ó)
- #include "delay.h"
- #include "IO.h"
- //oˉêy??áD±í3?ê??ˉ(ó??§×??oìí?ó)
- //ó??§?±?ó?ú?aà?ê?è?òa?′DDμ?oˉêy???°??2é?ò′?
- struct _m_usmart_nametab usmart_nametab[]=
- {
- (void*)delayms,"void delayms(u16 x);",
- (void*)set_output,"void set_output(u8 i);",
- (void*)reset_output,"void reset_output(u8 i);"
- };
- ///////////////////////////////////END///////////////////////////////////////////////
- /////////////////////////////////////////////////////////////////////////////////////
- //oˉêy????1üàí?÷3?ê??ˉ
- //μ?μ??÷??êü??oˉêyμ???×?
- //μ?μ?oˉêy×üêyá?
- struct _m_usmart_dev usmart_dev=
- {
- usmart_nametab,
- usmart_init,
- usmart_cmd_rec,
- usmart_exe,
- usmart_scan,
- sizeof(usmart_nametab)/sizeof(struct _m_usmart_nametab),//oˉêyêyá?
- 0, //2?êyêyá?
- 0, //oˉêyID
- 1, //2?êy??ê?ààDí,0,10????;1,16????
- 0, //2?êyààDí.bitx:,0,êy×?;1,×?·?′?
- 0, //????2?êyμ?3¤?è?Y′?±í,DèòaMAX_PARM??03?ê??ˉ
- 0, //oˉêyμ?2?êy,DèòaPARM_LEN??03?ê??ˉ
- };
1.删掉#include "usart.h"和 #include "sys.h" ,添加#include "uart.h"
2.添加外部参数声明:
extern u8 UART_RX_BUF[UART_REC_LEN];
extern u16 UART_RX_STA;
extern u32 timer0_num;
3.替换void usmart_reset_runtime(void)函数里的内容
替换为:
timer0_num=0;
usmart_dev.runtime=0;
4.替换u32 usmart_get_runtime(void)函数里的内容
替换为:
usmart_dev.runtime+=timer0_num;
return usmart_dev.runtime; //·μ????êy?μ
5.删掉void TIM4_IRQHandler(void)函数(usmart_dev.scan();已写在delay.c定时器0中断里),
删掉void Timer4_Init(u16 arr,u16 psc)函数。
6.修改void usmart_init(u8 sysclk)函数,要去掉形参,要记得在h文件函数声明里做对应修改。
- void usmart_init()
- {
- #if USMART_ENTIMX_SCAN==1
- Timer0_init();
- #endif
- usmart_dev.sptype=1;
- }
- switch(usmart_dev.pnum)
- {
- case 0://?T2?êy(voidààDí)
- res=(*(u32(*)())usmart_dev.funs[id].func)();
- break;
- case 1://óD1??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0]);
- break;
- case 2://óD2??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1]);
- break;
- case 3://óD3??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2]);
- break;
- case 4://óD4??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3]);
- break;
- case 5://óD5??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4]);
- break;
- case 6://óD6??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
- temp[5]);
- break;
- case 7://óD7??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
- temp[5],temp[6]);
- break;
- case 8://óD8??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
- temp[5],temp[6],temp[7]);
- break;
- case 9://óD9??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
- temp[5],temp[6],temp[7],temp[8]);
- break;
- case 10://óD10??2?êy
- res=(*(u32(*)())usmart_dev.funs[id].func)(temp[0],temp[1],temp[2],temp[3],temp[4],\
- temp[5],temp[6],temp[7],temp[8],temp[9]);
- break;
- }
warning C209: 'function': too few actual parameters
error C208: 'function': too many actual parameters
或者是函数未符合A什么标准的,意思就是未找到定义的函数。
这里修改方式就是屏蔽掉没有在usmart_config.c里用户自定义区里函数的类型,例如小编的
usmart_config.c里的用户自定义区有三个函数
(void*)delayms,"void delayms(u16 x);",
(void*)set_output,"void set_output(u8 i);",
(void*)reset_output,"void reset_output(u8 i);"
这三个函数都只有1个形参,那么对于switch case里面例举的函数类型,只留下case 1,其他全注释掉。
用户区里有什么样结构的函数,case里就保留什么样的结构。
usmart.c修改细节部分:
1.删掉u32 read_addr(u32 addr)和void write_addr(u32 addr,u32 val)函数,直接从#if删到#endif,注意
对应的h文件里函数声明要删掉。不删的话,还可以在usmart.h里将USMART_USE_WRFUNS宏定义为0就 行了。
2.使用printf输出16进制时,为了输出正确,参数要强制类型转换一下,例:
printf("0X%X",(u16)temp);
u16在delay.h里声明的是unsigned int类型。
3.51单片机串口printf输出时,前后要给TI信号。例:
TI=1;
printf("0X%X",(u16)temp);
TI=0;
一大段printf时,不需要每句都加,例:
- TI=1;
- printf("\r\n");
- printf("USMART has 7 system commands\r\n");
- printf("?: get help information\r\n");
- printf("help: get help information\r\n");
- printf("list: available function list\r\n");
- printf("id: available function ID\r\n");
- printf("hex: argument display in hex,hex+space+number\r\n");
- printf("dec: argument display in dec,dec+space+number\r\n");
- printf("runtime:1,enable caculate function runtime;0,disable caculate function runtime\r\n");
- printf("please input the right fuctions with arguments and end with enter!\r\n");
- TI=0;
小编只是把中文的全部改成英文的,如上代码所示。
好材料,先收藏了。
方便留下联系方式吗?可以交流一下吗?最近也想将usmart移植到其他单片机上。
小编,注释乱码是因为编译器编码问题。像keil4的注释在keil5上就乱码,反正我的是这样,不知道你们的。c文件可以先用记事本打开,然后再复制就不会乱码了。
专业PCB快板制造!打样30元起,加急24小时只要50元!^_^有需要可以和我联系,QQ269175760,谢谢!
我把它移植到STC15W4K48S4,也出现了显示长串汉字是会出现乱码,你找到原因了没?
好像是很牛的样子?
大神,你来知道一下呗
我不是什么大神啊
就是一水军而已,
知道谈不上了,互相学习