您的位置:首页 > 其它

关于正点原子开发的基于stm32的USMART部分源码分析

2017-12-24 21:11 465 查看
/********主程序(程序示例1)*******/
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "lcd.h"
#include "usmart.h"
void led_set(u8 sta)
{
LED1=sta;
}
//函数参数调用测试函数
void test_fun(void(*ledset)(u8),u8 sta)
{
ledset(sta);
}

int main(void)
{

NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
delay_init(168);      //初始化延时函数
uart_init(115200);		//初始化串口波特率为115200
usmart_dev.init(84); 	//初始化USMART
LED_Init();					  //初始化LED
LCD_Init();           //初始化LCD
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"Explorer STM32F4");
LCD_ShowString(30,70,200,16,16,"USMART TEST");
LCD_ShowString(30,90,200,16,16,"ATOM@ALIENTEK");
LCD_ShowString(30,110,200,16,16,"2014/5/5");
while(1)
{
LED0=!LED0;
delay_ms(500);
}
}


/******usmart_dev结构体变量定义(程序示例2)*******/
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),//函数数量
0,	  	//参数数量
0,	 	//函数ID
1,		//参数显示类型,0,10进制;1,16进制
0,		//参数类型.bitx:,0,数字;1,字符串
0,	  	//每个参数的长度暂存表,需要MAX_PARM个0初始化
0,		//函数的参数,需要PARM_LEN个0初始化
};
/********结构体成员函数usmart_dev.init()的实现(程序示例3)*********/
//初始化串口控制器
//sysclk:系统时钟(Mhz)
void usmart_init(u8 sysclk)
{
#if USMART_ENTIMX_SCAN==1
 Timer4_Init(1000,(u32)sysclk*100-1);//分频,时钟为10K ,100ms中断一次,注意,计数频率必须为10Khz,以和runtime单位(0.1ms)同步.
#endif
 usmart_dev.sptype=1; //十六进制显示参数
} 
/***********结构体的定义(程序示例4)********/
//函数名列表 
struct _m_usmart_nametab
{
 void* func;   //函数指针
 const u8* name;  //函数名(查找串) 
};
struct _m_usmart_dev
{
 struct _m_usmart_nametab *funs; //函数名指针
 void (*init)(u8);    //初始化
 u8 (*cmd_rec)(u8*str);   //识别函数名及参数
 void (*exe)(void);     //执行
 void (*scan)(void);             //扫描
 u8 fnum;         //函数数量
 u8 pnum;                        //参数数量
 u8 id;       //函数id
 u8 sptype;      //参数显示类型(非字符串参数):0,10进制;1,16进制;
 u16 parmtype;     //参数的类型
 u8  plentbl[MAX_PARM];    //每个参数的长度暂存表
 u8  parm[PARM_LEN];     //函数的参数
 u8 runtimeflag;     //0,不统计函数执行时间;1,统计函数执行时间,注意:此功能必须在USMART_ENTIMX_SCAN使能的时候,才有用
 u32 runtime;     //运行时间,单位:0.1ms,最大延时时间为定时器CNT值的2倍*0.1ms
};


今天刚看完正点原子开发的基于stm32的USMART源码,个人觉得比较有意思。首先介绍下我们的主角吧:USMART,USMART是基于USART(Universal Synchronous/Asynchronous Receiver/Transmitter)的一个辅助程序调试的一个程序。我用的板子是正点原子stm32F407的一款板子,程序是基于该板子和固件库的。为啥他们要管这个程序叫"USMART"呢?本人以为可能有两方面的原因吧,一方面该程序是基于USART的,另一方面是将USMART拆分成  U+SMART(你很机智)。当然,我没有并没有去问他们的设计人员,只是我的个人臆想。

先说一下这个程序的移植吧,这个程序包括五个主要文件(usmart.c、usmart.h、usmart_str.c、usmart_str.h和usmart_config.c),关于这个工程的其他文件在此就不赘述了。

主程序程序示例1(main.c文件)里边主要说一下void test_fun(void(*ledset)(u8),u8 sta)这个函数吧,这个函数的特别之处在于它的第一个参数是一个函数指针。这就是USMART得以实现的关键。第二个看一下usmart_dev.init(84)这个函数,这个函数的特别之处在于这是一个结构体成员函数。我们找到usmart_dev这个成员变量定义程序--程序示例2(usmart_config.c文件),等号后边是对该结构体变量的赋值。举个例子,usmart_init是函数名赋值,看定义我们就能找到该函数的实现,看程序示例3(usmart.c文件)。刚才只是说了结构体变量——usmart_dev——的定义,然后我们接着顺藤摸瓜看下关于该结构体的定义(程序示例4)。这个程序重点看下函数名列表这个结构体,这个结构体变量会与usmart_config.c中的struct
_m_usmart_nametab usmart_nametab[]={}结构体数组进行比。对至此我们大概就了解了将串口发送的数据与相应的函数进行匹配。

这个过程还需要定时器的配合,定时器的作用是在定时中断里实现对USMART的扫描来获取串口数据,从而调用相关函数。



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  stm32 USMART
相关文章推荐