串口使用DMA發(fā)送,使用DMA_Mode_Normal模式,怎么來手動觸發(fā)發(fā)送?

串口使用DMA發(fā)送,使用DMA_Mode_Normal模式,怎么來手動觸發(fā)發(fā)送?

DMA設(shè)置如下:

void bsp_InitHardUart(void)

{

? ? GPIO_InitTypeDef GPIO_InitStructure = {0};

? ? USART_InitTypeDef USART_InitStructure = {0};

? ? DMA_InitTypeDef DMA_InitStructure = {0};

? ? NVIC_InitTypeDef NVIC_InitStructure = {0};


? ? RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB | RCC_APB2Periph_USART1, ENABLE);

? ? RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);


? ? // USART1 TX->B.6 ? RX->B.7

? ? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

? ? GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

? ? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

? ? GPIO_Init(GPIOB, &GPIO_InitStructure);

? ? GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7;

? ? GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;

? ? GPIO_Init(GPIOB, &GPIO_InitStructure);


? ? // USART1重映射至PB6、PB7

? ? GPIO_PinRemapConfig(GPIO_Remap_USART1, ENABLE);


? ? // 配置串口1

? ? USART_DeInit(USART1);

? ? USART_InitStructure.USART_BaudRate = 115200;

? ? USART_InitStructure.USART_WordLength = USART_WordLength_8b;

? ? USART_InitStructure.USART_StopBits = USART_StopBits_1;

? ? USART_InitStructure.USART_Parity = USART_Parity_No;

? ? USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;

? ? USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;

? ? USART_Init(USART1, &USART_InitStructure);


? ? // 配置DMA

? ? DMA_DeInit(DMA1_Channel4);

? ? DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DATAR;

? ? DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ucaTxBuffer;

? ? DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralDST;

? ? DMA_InitStructure.DMA_BufferSize = FRAME_SIZE;

? ? DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

? ? DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

? ? DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_Byte;

? ? DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_Byte;

? ? DMA_InitStructure.DMA_Mode = DMA_Mode_Normal;

? ? DMA_InitStructure.DMA_Priority = DMA_Priority_VeryHigh;

? ? DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

? ? DMA_Init(DMA1_Channel4, &DMA_InitStructure);


? ? DMA_DeInit(DMA1_Channel5);

? ? DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&USART1->DATAR;

? ? DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ucaRxBuffer;

? ? DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

? ? DMA_InitStructure.DMA_BufferSize = FRAME_SIZE;

? ? DMA_Init(DMA1_Channel5, &DMA_InitStructure);


? ? // 啟用 USART DMA 接口

? ? USART_DMACmd(USART1, USART_DMAReq_Tx, ENABLE);


? ? // 使能 DMA 通道傳輸

? ? DMA_Cmd(DMA1_Channel4, ENABLE); // USART1_TX

? ? DMA_Cmd(DMA1_Channel5, ENABLE); // USART1_RX


? ? // 設(shè)置中斷優(yōu)先級

? ? NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; ? ? ? ? // IRQ通道

? ? NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; // 搶占優(yōu)先級別

? ? NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; ? ? ? ?// 從優(yōu)先級別

? ? NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; ? ? ? ? ? // 使能

? ? NVIC_Init(&NVIC_InitStructure);


? ? // 使能串口接收中斷

? ? USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);

? ? // 使能串口

? ? USART_Cmd(USART1, ENABLE);

}


你好,在DMA正常模式下,當(dāng)DMA傳輸完一次需要啟動第二次傳輸時,需要關(guān)閉DMA對應(yīng)的通道,對CNTR寄存器進(jìn)行賦值,同時如若需要修改傳輸?shù)腂uff ,也需要將待傳輸?shù)臄?shù)據(jù)地址重新賦值給MADDR寄存器,后再使能DMA通道開啟第二次傳輸。如圖是個參考:

image.png


我現(xiàn)在只重新給CNTR寄存器數(shù)據(jù)長度就可以重新發(fā)了,我的緩沖區(qū)位置不變,只改了內(nèi)容,重新CNTR賦值就可以觸發(fā)發(fā)送了,這樣沒有啥問題吧?


這個不用,數(shù)據(jù)地址不變的話不用重新賦值。CNTR需要重新復(fù)制的原因見下面手冊:

image.png


就是這個寄存器遞減沒了,所以在上面初始化完后的基礎(chǔ)上,我每次改好緩沖區(qū)的內(nèi)容后,調(diào)用了

DMA_SetCurrDataCounter(DMA1_Channel4, usLength);

這個函數(shù),數(shù)據(jù)就發(fā)送出去了,不過為了確保數(shù)據(jù)能正常發(fā)送,確實(shí)需要再次打開DMA對應(yīng)的通道。


DMA_Cmd(USARTx_DMA_CHN_Tx[idx],?DISABLE);???????????????????????//關(guān)DMA_ChannelTx修改參數(shù)
DMA_ClearFlag(USARTx_DMA_FLAG_Tx[idx]);?????????????????????????//?清除DMA1_IT_TC傳輸完成標(biāo)志
DMA_SetCurrDataCounter(USARTx_DMA_CHN_Tx[idx],?TxLen);??????????//?設(shè)置數(shù)據(jù)發(fā)送長度
USART_Cmd(USARTx[idx],?ENABLE);?????????????????????????????????//?開啟串口X
USART_DMACmd(USARTx[idx],?USART_DMAReq_Tx,?ENABLE);?????????????//?開啟串口DMATx
DMA_Cmd(USARTx_DMA_CHN_Tx[idx],?ENABLE);????????????????????????//?開啟DMA_ChannelTx

0處理完成要發(fā)送的數(shù)據(jù),1關(guān)閉DMA,2清標(biāo)志,3設(shè)長度,4開串口,5開DMA Tx,6開DMA....我一直都是這樣用的,不知道有沒有錯。

因?yàn)樵?jīng)發(fā)現(xiàn)不關(guān)閉會被干擾得很煩人,所以現(xiàn)在都習(xí)慣不用時都關(guān)掉串口、關(guān)掉DMA。


只有登錄才能回復(fù),可以選擇微信賬號登錄

国产91精品新入口,国产成人综合网在线播放,九热这里只有精品,本道在线观看,美女视频a美女视频,韩国美女激情视频,日本美女pvp视频