| 虚拟硬件体验: 【AiCube-ISP-V6.96E 版 | 调试仿真接口 | 擎天柱-LED-DIP40】
 使用串口DMA方式, 同步I/O状态方便观察
 
   
   
 
   
 首先使用自发自收的例程体验了一下数据流显示
 
   
 然后基于命令串,做了一个DMA-UART方案的自动IO状态同步程序:
 先看一下效果:
 
 
 
 那么要怎么添加这个IO同步显示的功能呢?
 程序采用分体式文件,只需要将io_sync.c和io_sync.h添加到工程中。
 
   然后在主程序中引用io_sync.h,并添加一行
 
   进行初始化即可,之后就完全不用管了,DMA会自动重复触发
 函数的具体介绍在.h文件中
 
   以下是测试程序和独立的.c/.h文件
 
  io_sync文件.zip
(1.69 KB, 下载次数: 177) 
  IO端口同步到STC-ISP测试程序.zip
(88.67 KB, 下载次数: 177) 
 
 以下是具体的实现方式:
 首先,基于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[0 + 6] = P0;
    io_sync_buf[1 + 6] = P1;
    io_sync_buf[2 + 6] = P2;
    io_sync_buf[3 + 6] = P3;
    io_sync_buf[4 + 6] = P4;
    io_sync_buf[5 + 6] = P5;
    DMA_UR1T_STA = 0x00;
    DMA_UR1T_CR = 0xc0; // 拉起下次发送
}
 DMA和中断就自动完成了这个过程
 
 
 
 
 
 
 |