在开发单片机时候,经常会用到数据交互的知识,采用中断的方式有些浪费CPU的资源了,这里看到STC也推出的串口的DMA功能,这里我使用串口结合定时器做超时判断,从而实现空闲中断的效果。
STC32G128 的串口1是一个非常强大且灵活的通信接口,它不仅支持最常用的异步串行通信(UART),还能配置为SPI、LIN、红外通信甚至智能卡模式
一:AI cube的配置如下所示:

这里就是打开串口1的DMA发送和接收功能,同时配置DMA发送和接收的数组、优先级别;
不过这里DMA的发送和接收的数组支持1-65535,可见STC的DMA功能很强大。二:软件代码2.1 DMA发送函数:void UART1_DMA_Transmit(u8 *pData, u16 Size)
{
if(Size == 0) return;
Size -= 1;
DMA_UR1T_CFG = 0x80; //bit7 1:Enable Interrupt
DMA_UR1T_STA = 0x00;
DMA_UR1T_AMTH = (u8)(Size >> 8); //设置传输总字节数(低8位):n+1
DMA_UR1T_AMT = (u8) Size; //设置传输总字节数(高8位):n+1
DMA_UR1T_TXAH = (u8)((u16)pData >> 8);
DMA_UR1T_TXAL = (u8)((u16)pData);
DMA_UR1T_CR = 0xc0; //bit7 1:使能 UART1_DMA, bit6 1:开始 UART1_DMA 自动发送
}2.2 DMA接收函数:void UART1_DMA_Receive(u8 *pData, u16 Size)
{
if(Size == 0) return;
Size -= 1;
DMA_UR1R_CFG = 0x80; //bit7 1:Enable Interrupt
DMA_UR1R_STA = 0x00;
DMA_UR1R_AMTH = (u8)(Size >> 8); //设置传输总字节数(低8位):n+1
DMA_UR1R_AMT = (u8)Size; //设置传输总字节数(高8位):n+1
DMA_UR1R_RXAH = (u8)((u16)pData >> 8);
DMA_UR1R_RXAL = (u8)((u16)pData);
DMA_UR1R_CR = 0xa1; //bit7 1:使能 UART4_DMA, bit5 1:开始 UART4_DMA 自动接收, bit0 1:清除 FIFO
}2.3 DMA数据回传功能函数:void ReturnUsart1Data(u8 *pData, u16 Size)
{
DMA_UR1R_CR = 0x00; //bit7 1:使能 UART1_DMA, bit5 1:开始 UART1_DMA 自动接收, bit0 1:清除 FIFO
memcpy(SendBuffer1,pData,Size);
UART1_DMA_Transmit(SendBuffer1,Size); //设置DMA发送缓冲区,数据长度,并启动发送
RX1_Cnt = 0;
UART1_DMA_Receive(pu8UR1DMARxBuffer,256); //设置DMA接收缓冲区,数据长度,并启动接收
}采用指针的方式,将要回传的数据,放到DMA的发送函数里就可以了。
2.4 超时判断,触发函数如下所示:
if(RX1_COUNT>0)
RX1_COUNT-- ;
if((RX1_COUNT ==0)&& (RX1_Cnt!=0))
{
// SendMessage(MW_DMAUSART1,RX1_Cnt,0);
b_send1 =1 ;
}2.5 添加到消息任务中或者是放到定时器中断中处理:2.5.1 放到消息队列中:
case MW_DMAUSART1: ReturnUsart1Data(pu8UR1DMARxBuffer,RX1_Cnt); break;
这种方式存在一个问题就是,程序运行一段时间后,DMA发送函数卡死的现象,一直向外界吐数据。不稳定;
2.5.2 放到定时器处理中: case 20:
if(b_send1 == 1)
{
ReturnUsart1Data(pu8UR1DMARxBuffer,RX1_Cnt);
b_send1 = 0 ;
}这种处理方法,很稳定,估计是放到消息队列中,DMA的发送功能收到了影响。三:测试效果如下:
以300MS的时间间隔,发送不同数据长度的字符,运行了几十万的字节,没有发生数据丢失的情况。
四:调试过程中遇到问题、心得4.1 开始的时候DMA配置错误,导致每次发送时候,会导致程序卡死。
4.2 采用创建数据回传消息任务时候,程序在运行一段时间后,就会发现DMA的发送函数“假死”的现象,串口1的DMA一直向外界发送数据,采用增加超时判断时间的方法,情况也是一样的,不太明白为什么会有这种情况。
4.3 使用在定时器中执行串口数据回传的功能还是很稳定的,也没有发现数据丢失的情况,推荐使用该处理方式。
4.4 DMA(直接存储器访问):当项目需要频繁、大量收发数据时,配合DMA可以解放CPU。你只需配置好缓冲区,DMA会自动完成数据搬运,非常适合用于高速数据采集或通信。结合定时器,也可以实现“空闲中断”的方式,不过需要设置好,超时判断的时间间隔。
4.5 USB-CDC虚拟串口:STC32G12K128支持通过USB直接虚拟成一个串口。就不需要USB转TTL工具,直接用Type-C数据线连接电脑就能进行串口通信,调试和产品升级都非常方便
我要赚赏金
