王昱顺 发表于 2024-11-30 14:54:12

虚拟硬件体验:【AIapp-ISP-V6.95D 版 | 调试仿真接口 | 擎天柱-LED-DIP40】

虚拟硬件体验:
【AIapp-ISP-V6.95D 版 | 调试仿真接口 | 擎天柱-LED-DIP40】
使用串口DMA方式, 同步I/O状态方便观察





首先使用自发自收的例程体验了一下数据流显示


然后基于命令串,做了一个DMA-UART方案的自动IO状态同步程序:
先看一下效果:



那么要怎么添加这个IO同步显示的功能呢?
程序采用分体式文件,只需要将io_sync.c和io_sync.h添加到工程中。

然后在主程序中引用io_sync.h,并添加一行

进行初始化即可,之后就完全不用管了,DMA会自动重复触发
函数的具体介绍在.h文件中

以下是测试程序和独立的.c/.h文件




以下是具体的实现方式:
首先,基于DMA的发送完成中断,可以再次启动下一次发送,从而达到自循环的目的
其次,通过控制DMA_UR1_ITV寄存器,即可实现发送每个数据间的自动延时。
以下是核心配置和实现程序:
void DMA_Config(void)
{
    DMA_UR1T_CFG = 0x80; // bit7 1:Enable Interrupt
    DMA_UR1T_STA = 0x00;
    DMA_UR1T_AMT = (12 - 1); // 设置传输总字节数(低8位):n+1
    DMA_UR1T_TXAH = (u8)((u16)&io_sync_buf >> 8);
    DMA_UR1T_TXAL = (u8)((u16)&io_sync_buf);
    DMA_UR1_ITVH = 0xff; // 防止加重系统负担
    DMA_UR1T_CR = 0xc0;         // bit7 1:使能 UART1_DMA, bit6 1:开始 UART1_DMA 自动发送
}

// IO 同步输出初始化函数
//fosc: 主时钟频率,单位为Hz
//brt: 波特率,单位为Hz
//timer: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
void sync_io_init(long fosc, long brt, char timer)
{
    EAXFR = 1;
    _fosc = (long)(fosc); // 定义主时钟(精确计算波特率)
    _brt = (long)(brt);   // 定义波特率
    UART1_config(timer);// 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
    DMA_Config();
    EA = 1;
}

void _uart_tx_dma_io_sync(void) interrupt 50
{
    io_sync_buf = P0;
    io_sync_buf = P1;
    io_sync_buf = P2;
    io_sync_buf = P3;
    io_sync_buf = P4;
    io_sync_buf = P5;
    DMA_UR1T_STA = 0x00;
    DMA_UR1T_CR = 0xc0; // 拉起下次发送
}这样就可以通过一次初始化,将端口状态自动转发到串口,全程无需其他代码参与。
DMA和中断就自动完成了这个过程




王昱顺 发表于 2024-11-30 15:09:35

USB-CDC版本 的 I/O监控:
USB直连,无需 下载器-转串口/USB转串口,无需设置波特率(省心快捷)
程序已经封装为一个.c文件,只需要在程序中引用#include "io_cdc.h"即可使用
使用方式是直接调用io_cdc_sync();即可使用

需要给程序添加的文件有:

以下是示例程序和独立的文件包:


VCC 发表于 2024-11-30 15:23:15

本帖最后由 VCC 于 2024-11-30 15:38 编辑

进行初始化即可,之后就完全不用管了,DMA会自动重复触发

这个最高速率怎么样呢?

是不是可以用这种方式制作一个逻辑分析仪

王昱顺 发表于 2024-11-30 15:34:33

VCC 发表于 2024-11-30 15:23
这个最高速率怎么样呢?

是不是可以用这种方式制作了一个逻辑分析仪


串口方式速率不高吧,而且这个只能看看状态。
USB方式倒是可以通过DMA载入缓冲区数据实现变量监控
你说的这个很有意思,等我研究一下

jwd 发表于 2024-11-30 15:58:21

{:4_250:}

神农鼎 发表于 2024-11-30 16:21:28

估计用的实验箱上的 USB转双串口,可以10Mbps









王昱顺 发表于 2024-11-30 18:03:16

VCC 发表于 2024-11-30 15:23
这个最高速率怎么样呢?

是不是可以用这种方式制作一个逻辑分析仪
目前实现了ADC-DMA到USB

速度相当快,并且全程都是DMA转发
高速CDC数据传输 ADC-DMA到USB-CDC做简易示波器 - FOC,有ICache的 32F12K54 测试版块 国芯技术交流网站 - AI32位8051交流社区

你说的逻辑分析仪用PWM-DMA我觉得很不错,可以通过使用PLL下的PWM来记录高速的逻辑信号。
不过上位机用串口助手可能就不大合适了,数据传输效率有点低(最少8个位才能表示一个1或0),应该需要专用的上位机
或者使用按键触发记录缓存,然后再进行回放的方式也可以

VCC 发表于 2024-11-30 18:07:05

王昱顺 发表于 2024-11-30 18:03
目前实现了ADC-DMA到USB

速度相当快,并且全程都是DMA转发


我对Ai8051U了解得不多

PWM-DMA-USB如何能实现IO口状态读取?我理解里PWM应该是一个输出模块,这是怎么做到的?

王昱顺 发表于 2024-11-30 18:10:39

VCC 发表于 2024-11-30 18:07
我对Ai8051U了解得不多

PWM-DMA-USB如何能实现IO口状态读取?我理解里PWM应该是一个输出模块,这是怎么 ...
事实上,STC的PWM也能做为信号捕获
具体流程是:选定上升沿/下降沿,PWM部分捕获到这个信号的时候会将此刻的PWM计时器值记下,并给出一个中断。
因为PWM部分可以通过PLL使用120Mhz这样的高速信号,所以PWM捕获相比IO直接捕获要更快,并且通过设定PWM-DMA,还可以将每次捕获的值进行存储,这样就得到了一串跳变之间的时间,通过对这段时间的重绘就能得到一个完整的波形了

神农鼎 发表于 2024-12-7 13:13:25

客服学习


while(1)
{
      LED40_ClrBit(2, 0);   // P20 = 0;
      void Delay1000ms(void)      //@40MHz
      {
                unsigned long edata i;

                _nop_();
                _nop_();
                i = 9999998UL;
                while (i)i--;
      }
      
      LED40_SetBit(2, 0);   // P20 = 1;

         LED40_ClrBit(2, 1);   // P21 = 0;
      void Delay1000ms(void)      //@40MHz
      {
                unsigned long edata i;

                _nop_();
                _nop_();
                i = 9999998UL;
                while (i)i--;
      }
      
      LED40_SetBit(2, 1);   // P21 = 1;   

}

页: [1] 2
查看完整版本: 虚拟硬件体验:【AIapp-ISP-V6.95D 版 | 调试仿真接口 | 擎天柱-LED-DIP40】