虚拟硬件体验:
【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文件
io_sync文件.zip
(1.69 KB, 下载次数: 53)
IO端口同步到STC-ISP测试程序.zip
(88.67 KB, 下载次数: 46)
以下是具体的实现方式:
首先,基于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和中断就自动完成了这个过程
|