本章介绍一个十分重要的辅助调试工具:USMART调试组件。功能类似Linux的shell(RTT的finsh也属于此类)。USMART最主要的功能就是通过串口调用单片机里面的函数,并执行,对我们调试代码是很有帮助的。
由于 USMART 默认提供了 STM32 的 TIM4 中断初始化设置代码,我们只需要在 usmart.h里面设置 USMART_ENTIMX_SCAN 为 1,即可完成 TIM4 的设置,通过 TIM4 的中断服务函数,调用 usmart_dev.scan()(就是 usmart_scan 函数),实现 usmart 的扫描。
在主程序里面还得执行 usmart 的初始化,另外还需要针对你自己想要被 USMART 调用的函数在 usmart_config.c 里面进行添加。
可以通过修改test_fun的第二个参数来调试DS1是否点亮,不需要再修改代码-编译-下载了,直接通过串口发送给单片机即可执行,调试很方便。
带有函数参数的函数的调用,我们将 led_set 函数作为 test_fun 的参数,通过在 test_fun 里面调用 led_set 函数,实现对 DS1(LED1)的控制。前面说过,我们要调用带有函数参数的函数,就必须先得到函数参数的入口地址(id),通过输入 id 指令,我们可以得到 led_set 的函数入口地址是:0X0800022D(注意:这个地址要以实际串口输出结果为准),所以,我们在串口输入:test_fun(0X0800022D,0),就可以控制 DS1 亮了。
一个函数A调用另一个函数B作为参数时,必须先得到这个函数B的入口地址,也就是这个函数B的首地址,然后将这个首地址作为函数A的参数来使用。
#include "led.h"
#include "delay.h"
#include "key.h"
#include "sys.h"
#include "lcd.h"
#include "usart.h"
#include "usmart.h"
//LED状态设置函数
void led_set(u8 sta)
{
LED1=sta;
}
//函数参数调用测试函数
void test_fun(void(*ledset)(u8),u8 sta)
{
ledset(sta);
}
int main(void)
{
delay_init(); //延时函数初始化
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
uart_init(115200); //串口初始化为115200
LED_Init(); //LED端口初始化
LCD_Init();
usmart_dev.init(SystemCoreClock/1000000); //初始化USMART
POINT_COLOR=RED;
LCD_ShowString(30,50,200,16,16,"WarShip STM32 ^_^");
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,"2015/1/14");
while(1)
{
LED0=!LED0;
delay_ms(500);
}
}
#include "usmart.h"
#include "usmart_str.h"
////////////////////////////用户配置区///////////////////////////////////////////////
//这下面要包含所用到的函数所申明的头文件(用户自己添加)
#include "delay.h"
#include "sys.h"
#include "lcd.h"
extern void led_set(u8 sta);
extern void test_fun(void(*ledset)(u8),u8 sta);
//函数名列表初始化(用户自己添加)
//用户直接在这里输入要执行的函数名及其查找串
struct _m_usmart_nametab usmart_nametab[]=
{
#if USMART_USE_WRFUNS==1 //如果使能了读写操作
(void*)read_addr,"u32 read_addr(u32 addr)",
(void*)write_addr,"void write_addr(u32 addr,u32 val)",
#endif
(void*)delay_ms,"void delay_ms(u16 nms)",
(void*)delay_us,"void delay_us(u32 nus)",
(void*)LCD_Clear,"void LCD_Clear(u16 Color)",
(void*)LCD_Fill,"void LCD_Fill(u16 xsta,u16 ysta,u16 xend,u16 yend,u16 color)",
(void*)LCD_DrawLine,"void LCD_DrawLine(u16 x1, u16 y1, u16 x2, u16 y2)",
(void*)LCD_DrawRectangle,"void LCD_DrawRectangle(u16 x1, u16 y1, u16 x2, u16 y2)",
(void*)LCD_Draw_Circle,"void Draw_Circle(u16 x0,u16 y0,u8 r)",
(void*)LCD_ShowNum,"void LCD_ShowNum(u16 x,u16 y,u32 num,u8 len,u8 size)",
(void*)LCD_ShowString,"void LCD_ShowString(u16 x,u16 y,u16 width,u16 height,u8 size,u8 *p)",
(void*)led_set,"void led_set(u8 sta)",
(void*)test_fun,"void test_fun(void(*ledset)(u8),u8 sta)",
(void*)LCD_ReadPoint,"u16 LCD_ReadPoint(u16 x,u16 y)",
};
///////////////////////////////////END///////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////
//函数控制管理器初始化
//得到各个受控函数的名字
//得到函数总数量
struct _m_usmart_dev usmart_dev=
{
usmart_nametab, //函数名列表
usmart_init, //初始化串口控制器
usmart_cmd_rec, //获取函数名,id,及参数信息,返回值:0,识别成功
usmart_exe, //usamrt执行函数
usmart_scan, //usmart扫描函数
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初始化
};
在这个文件中添加用户需要调用和调试的函数,即可在串口调试助手里调用函数并执行。