usmart_dev.init(SystemCoreClock/1000000); //初始化USMART
对初始化程序的解析。对应 stm32 战舰的usmart 程序来分析
usmart_dev是_m_usmart_dev结构体的变量, usmart_dev结构体变量的初始化如下
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初始化
};
要想理解上面的初值,就需要看_m_usmart_dev 这个是结构体的声明, _m_usmart_dev的声明如下
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
};
void (*init)(u8);
u8 (*cmd_rec)(u8*str);
void (*exe)(void);
void (*scan)(void);
上面的四句都是函数指针。
所以执行usmart_dev.init(SystemCoreClock/1000000)的时候是执行的是usmart_dev结构体成员中函数指针void (*init)(u8)所指向的函数。而void (*init)(u8)所指向的函数,在结构体变量中已经初始化过(初始化为usmart_init)。
所以执行usmart_dev.init(SystemCoreClock/1000000)相当于执行了usmart_init(SystemCoreClock/1000000);(结构体的成员是函数指针)
函数usmart_init的实现如下
void usmart_init(u8 sysclk)
{
#if USMART_ENTIMX_SCAN==1
Timer2_Init(1000,(u32)sysclk*100-1);//分频,时钟为10K ,100ms中断一次,注意,计数频率必须为10Khz,以和runtime单位(0.1ms)同步.
#endif
usmart_dev.sptype=1; //十六进制显示参数
}
实际内容就是对time2 初始化 ,在time2定的时间内去扫描函数。
time2中断函数实现的如下
void TIM2_IRQHandler(void)
{
if(TIM2->SR&0X0001)//溢出中断
{
usmart_dev.scan(); //执行usmart扫描
TIM2->CNT=0; //清空定时器的CNT
TIM2->ARR=1000; //恢复原来的设置
}
TIM2->SR&=~(1<<0);//清除中断标志位
}
同理执行函数 usmart_dev.scan(); 就是执行了结构体成员变量usmart_scan,
下面是usmart_scan实现方法
void usmart_scan(void)
{
u8 sta,len;
if(USART_RX_STA&0x8000)//串口接收完成?
{
len=USART_RX_STA&0x3fff; //得到此次接收到的数据长度
USART_RX_BUF[len]='