目前SCI加上DMA可以多次传输固定长度的数据。但是我们再使用串口发送数据时不可能总是发送固定长度的数据,有时我们要发送10字节数据,有时又发送20字节数据。这时DMA应该如何配置,来达到发送不同长度的数据。
This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
目前SCI加上DMA可以多次传输固定长度的数据。但是我们再使用串口发送数据时不可能总是发送固定长度的数据,有时我们要发送10字节数据,有时又发送20字节数据。这时DMA应该如何配置,来达到发送不同长度的数据。
我初步尝试了一下:可以多次发送固定长度数据,程序和结果如下:
#include"HL_sci.h"
#include"HL_reg_sci.h"
#include "HL_reg_dma.h"
#include "HL_sys_dma.h"
g_dmaCTRL g_dmaCTRLPKT_SCI1_TX;
uint8 SCI1_TX_DATA[40]={0};
void SCI_DMA_Init(void)
{
dmaReqAssign(DMA_CH19, DMA_REQ29);
g_dmaCTRLPKT_SCI1_TX.SADD = (uint32)(SCI1_TX_DATA) ;
g_dmaCTRLPKT_SCI1_TX.DADD = ((uint32_t)(&(sciREG1->TD))+3);
g_dmaCTRLPKT_SCI1_TX.CHCTRL = 0;
g_dmaCTRLPKT_SCI1_TX.FRCNT = 10;
g_dmaCTRLPKT_SCI1_TX.ELCNT = 1;
g_dmaCTRLPKT_SCI1_TX.ELDOFFSET = 0;
g_dmaCTRLPKT_SCI1_TX.ELSOFFSET = 0;
g_dmaCTRLPKT_SCI1_TX.FRDOFFSET = 0;
g_dmaCTRLPKT_SCI1_TX.FRSOFFSET = 0;
g_dmaCTRLPKT_SCI1_TX.PORTASGN = PORTA_READ_PORTB_WRITE;
g_dmaCTRLPKT_SCI1_TX.RDSIZE = ACCESS_8_BIT;
g_dmaCTRLPKT_SCI1_TX.WRSIZE = ACCESS_8_BIT;
g_dmaCTRLPKT_SCI1_TX.TTYPE = FRAME_TRANSFER ;
g_dmaCTRLPKT_SCI1_TX.ADDMODERD = ADDR_INC1;
g_dmaCTRLPKT_SCI1_TX.ADDMODEWR = ADDR_FIXED;
g_dmaCTRLPKT_SCI1_TX.AUTOINIT = AUTOINIT_OFF;
dmaSetCtrlPacket(DMA_CH19,g_dmaCTRLPKT_SCI1_TX);
dmaSetChEnable(DMA_CH19, DMA_HW);
sciREG1->SETINT |= (1<<16U) ;
}
void SCI_DMA_SEND(uint8 length)
{
// dmaRAMREG->PCP[DMA_CH19].ITCOUNT =(0x00000001 | length<<16);
dmaSetChEnable(DMA_CH19, DMA_HW);
}
uint32 timen=50000;
int user_main(void)
{
uint8 i=0;
sciInit();
dmaEnable();
for(i=0;i<40;i++)
{
SCI1_TX_DATA[i]=i;
}
SCI_DMA_Init();
while(1)
{
while(timen--);
timen=50000;
SCI_DMA_SEND(20);
}
}

可以实现。
发送不同长度数据,失败,程序做以下修改和结果如下:
void SCI_DMA_SEND(uint8 length)
{
dmaRAMREG->PCP[DMA_CH19].ITCOUNT =(0x00000001 | length<<16);
dmaSetChEnable(DMA_CH19, DMA_HW);
}

只有第一次发送出来了,后面的就发送不出来了。 求解答。
好的我们已收到您的问题并升级到英文论坛,如有答复将尽快回复您。谢谢!
您好,需要重新配置 MibSPI DMA :
mibspiREG1->DMACTRL[0] |= (3 << 20) | (2 << 16);
mibspiREG1->DMACTRL[0] |= 0x8000C000;
同时启用传输组:
mibspiREG1->TGCTRL[0] |= 0x80000000U;
sciREG1->CLEARINT |= SCI_SET_TX_DMA;
g_dmaCTRLPKT.FRCNT = size/2; -->new FRCNT
g_dmaCTRLPKT.ELCNT = 1;
dmaRAMREG->PCP[0].ITCOUNT = (g_dmaCTRLPKT.FRCNT << 16U) | g_dmaCTRLPKT.ELCNT;
/*将 DMA 通道 0 和 1 设置为在硬件请求上触发*/
dmaSetChEnable(DMA_CH0, DMA_HW);
sciREG1->SETINT |= SCI_SET_TX_DMA;
1. 清除 SCI TX DMA 位
2. 重新配置帧计数和元素计数
3. 设置硬件通道使能位
4. 设置 SCI TX DMA 位 ti 触发传输
希望以上回答对您有所帮助,如有其他问题请随时联系我们。
这种问题我也遇到过,我的解决方法如下
只需在下次发送时清除标志位即可
sciREG1->CLEARINT |= (1 << 16U);
函数封装如下:
void scidmaSend(uint8 *source_address,uint8 len)
{
g_dmaCTRL g_dmaCTRLPKT;
sciREG1->CLEARINT |= (1 << 16U);
dmaEnable();
/* - configuring dma control packets */
g_dmaCTRLPKT.SADD = (uint32)source_address; /* source address */
g_dmaCTRLPKT.DADD = (uint32_t)(&(sciREG1->TD)); /* destination address */
g_dmaCTRLPKT.CHCTRL = 0; /* channel control */
g_dmaCTRLPKT.FRCNT = len; /* frame count */
g_dmaCTRLPKT.ELCNT =1 ; /* element count */
g_dmaCTRLPKT.ELDOFFSET = 0; /* element destination offset - is required? */
g_dmaCTRLPKT.ELSOFFSET = 0; /* element source offset - is required? */
g_dmaCTRLPKT.FRDOFFSET = 0; /* frame detination offset - is required? */
g_dmaCTRLPKT.FRSOFFSET = 0; /* frame source offset - is required? */
g_dmaCTRLPKT.PORTASGN = PORTA_READ_PORTB_WRITE; /* port b */
g_dmaCTRLPKT.RDSIZE = ACCESS_8_BIT; /* read size */
g_dmaCTRLPKT.WRSIZE = ACCESS_8_BIT; /* write size */
g_dmaCTRLPKT.TTYPE = FRAME_TRANSFER ; /* transfer type */
g_dmaCTRLPKT.ADDMODERD = ADDR_INC1; /* address mode read */
g_dmaCTRLPKT.ADDMODEWR = ADDR_FIXED; /* address mode write */
g_dmaCTRLPKT.AUTOINIT = AUTOINIT_OFF; /* autoinit (loop) */
/* - setting dma control packets for transmit */
dmaSetCtrlPacket(DMA_CH0,g_dmaCTRLPKT);
dmaSetChEnable(DMA_CH0, DMA_HW);
sciREG1->SETINT |= (1 << 16U);
}