搜索
bottom↓
回复: 0
打印 上一主题 下一主题

《ATK-DFPGL22G之FPGA开发指南_V1.0》第二十六章 USMART调试实验

[复制链接]

出0入234汤圆

跳转到指定楼层
1
发表于 2023-7-1 10:40:11 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
1)实验平台:正点原子 DFZU2EG_4EV MPSoC开发板
2)购买链接:https://item.taobao.com/item.htm?&id=692368045899
3)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-340252-1-1.html
4)正点原子官方B站:https://space.bilibili.com/394620890
5)正点原子FPGA交流群:994244016




第二十六章 USMART调试实验


USMART调试组件是正点原子开发的一款灵巧的串口调试交互组件,其功能类似Linux的Shell,支持通过串口调用程序中的任意函数,对调试代码有很大的帮助。通过本章的学习,读者将学习到USMART调试组件的使用。
本章分为如下几个小节:
26.1 硬件设计
26.2 程序设计
26.3 下载验证


26.1硬件设计
26.1.1 例程功能

1. 通过USMART调用程序中的函数,实现对LCD、LED和延时操作
2. LED0闪烁,指示程序正在运行
26.1.2 硬件资源
1. LED
        LED0 - PB5
2. USART1(PA9、PA10连接至板载USB转串口芯片上)
3. 定时器4
4. 正点原子 2.8/3.5/4.3/7/10寸TFTLCD模块(仅限MCU屏,16位8080并口驱动)
26.1.3 原理图
本章实验使用的USMART组件为应用软件,因此没有对应的连接原理图。
26.2 程序设计
26.2.1 USMART组件

使用USMART组件需要先进行相应的移植操作,USMART组件的移植也非常简单,只需要实现usmart_port.c文件中的5个函数即可完成移植。
第一个函数为usmart_get_input_string(),该函数用于USMART获取串口输入的数据流,该函数的实现,如下所示:
/**
* @brief     获取输入数据流(字符串)
* @note      USMART通过解析该函数返回的字符串以获取函数名及参数等信息
* @param     无
* @retval
* @arg       0,  没有接收到数据
* @arg       其他,数据流首地址(不能是0)
*/
char *usmart_get_input_string(void)
{
    uint8_t len;
    char *pbuf = 0;

    if (g_usart_rx_sta & 0x8000)        /* 串口接收完成 */
    {
        len = g_usart_rx_sta & 0x3fff;  /* 得到此次接收到的数据长度 */
        g_usart_rx_buf[len] = '\0';     /* 在末尾加入结束符 */
        pbuf = (char*)g_usart_rx_buf;
        g_usart_rx_sta = 0;             /* 开启下一次接收 */
    }

    return pbuf;
}
从上面的代码中可以看出,该函数就是从SYSTEM文件夹USART驱动中获取USART1输入的数据。
剩余的四个函数,在宏USMART_ENTIMX_SCAN开启后才需要定义,该宏用于使能runtime统计等功能。
第二个函数为usmart_timx_reset_time(),该函数用于复位runtime,该函数的实现,如下所示:
/**
* @brief       复位runtime
* @note        需要根据所移植到的MCU的定时器参数进行修改
* @param       无
* @retval      无
*/
void usmart_timx_reset_time(void)
{
    TMR_ClearIntFlag(USMART_TIMX, TMR_INT_UPDATE);  /* 清除中断标志位 */
    TMR_ConfigAutoreload(USMART_TIMX, 0xFFFF);      /* 将重装载值设置到最大 */
    TMR_ConfigCounter(USMART_TIMX, 0);              /* 清空定时器的CNT */
    usmart_dev.runtime = 0;
}
该函数复位了runtime功能和用于runtime功能的相关TMR。
第三个函数为usmart_timx_get_time(),用于runtime功能获取时间,该函数的实现,如下所示:
/**
* @brief       获得runtime时间
* @note        需要根据所移植到的MCU的定时器参数进行修改
* @param       无
* @retval      执行时间,单位:0.1ms,最大延时时间为定时器CNT值的2倍*0.1ms
*/
uint32_t usmart_timx_get_time(void)
{
/* 在运行期间,产生了定时器溢出 */
    if (TMR_ReadIntFlag(USMART_TIMX, TMR_INT_UPDATE) == SET)
    {
        usmart_dev.runtime += 0XFFFF;
    }
    usmart_dev.runtime += TMR_ReadCounter(USMART_TIMX);
    return usmart_dev.runtime;                                 /* 返回计数值 */
}
应为该函数能够处理一次定时器的溢出情况,因此能获取到的时间上限为定时器计数最大值的两倍。
第四个函数为usmart_timx_init(),用于初始化用于runtime功能的定时器,该函数的实现,如下所示:
/**
* @brief       定时器初始化函数
* @param       arr:自动重装载值
*              psc:定时器分频系数
* @retval      无
*/
void usmart_timx_init(uint16_t arr, uint16_t psc)
{
    TMR_BaseConfig_T tmr_init_struct;
   
    USMART_TIMX_CLK_ENABLE();
   
    tmr_init_struct.countMode = TMR_COUNTER_MODE_UP;    /* 向上计数器 */
    tmr_init_struct.clockDivision = TMR_CLOCK_DIV_1;
    tmr_init_struct.period = arr;                       /* 自动装载值 */
    tmr_init_struct.division = psc;                     /* 分频系数 */
    TMR_ConfigTimeBase(USMART_TIMX, &tmr_init_struct);
    NVIC_EnableIRQRequest(USMART_TIMX_IRQn, 3, 0);
   
    TMR_EnableInterrupt(USMART_TIMX, TMR_INT_UPDATE);
    TMR_Enable(USMART_TIMX);
}
可以看到,该函数初始化了一个用于runtime功能的定时器,同时使能了该定时器的更新中断。
第五个函数就是用于runtime功能的定时器的中断服务函数,该函数的实现,如下所示:
/**
* @brief       USMART定时器中断服务函数
* @param       无
* @retval      无
*/
void USMART_TIMX_IRQHandler(void)
{
    if (TMR_ReadIntFlag(USMART_TIMX, TMR_INT_UPDATE) == SET)/* 溢出中断 */
    {
        usmart_dev.scan();                                  /* 执行usmart扫描 */
        TMR_ConfigCounter(USMART_TIMX, 0);                  /* 清空定时器的CNT */
        TMR_ConfigAutoreload(USMART_TIMX, 100);             /* 恢复原来的设置 */
    }
   
    TMR_ClearIntFlag(USMART_TIMX, TMR_INT_UPDATE);          /* 清除中断标志位 */
}
以上就是移植USMART组件时需要实现的五个函数,至此USMART组件的移植也就基本完成了,接下来便可在usart_config.c文件中的usmart_nametab数组中添加需要调试的函数。
26.2.2 实验应用代码
本实验的应用代码,如下所示:
/**
* @brief       LED状态设置
* @param       无
* @retval      无
*/
void led_set(uint8_t sta)
{
    LED1(sta);
}

/**
* @brief       测试函数参数调用
* @param       无
* @retval      无
*/
void test_fun(void (*ledset)(uint8_t), uint8_t sta)
{
    ledset(sta);
}

int main(void)
{
    NVIC_ConfigPriorityGroup(NVIC_PRIORITY_GROUP_4);  /* 设置中断优先级分组为组4 */
    sys_apm32_clock_init(15);                         /* 配置系统时钟 */
    delay_init(120);                                  /* 初始化延时功能 */
    usart_init(115200);                               /* 初始化串口 */
    usmart_dev.init(120);                             /* 初始化USMART */
    led_init();                                       /* 初始化LED */
    lcd_init();                                       /* 初始化LCD */
   
    lcd_show_string(30, 50, 200, 16, 16, "APM32", RED);
    lcd_show_string(30, 70, 200, 16, 16, "USMART TEST", RED);
    lcd_show_string(30, 90, 200, 16, 16, "ATOM@ALIENTEK", RED);
   
    while (1)
    {
        LED0_TOGGLE();
        delay_ms(500);
    }
}
从上面的代码中可以看出,main()函数中初始化了USMART组件,并且另外定义了两个函数,分别为:函数led_set()和函数test_fun(),这两个函数都被添加到了usmart_config.c文件的usmart_nametab数组中,用于测试USMART组件,同时也添加了LCD操作和延时等函数,读者也可以添加自行编写的函数进行测试和调试。
26.3 下载验证
在完成编译和烧录操作后,便可通过串口调试助手“体验”USMART组件,例如通过串口调试助手发送“led_set(0)\r\n”或“led_set(1)\r\n”,即可看到板载的LED1亮起或熄灭,也可使用同样的方式调用LCD的操作函数操作LCD进行显示
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 14:35

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表