小弟我最近想实现串口用DMA 发送数据 手里只有一分官方DMA 的事例,对于有些地方实在不理解,萌新也没有师傅带,希望
论坛大哥多带带
硬件平台 LPC1768
软件平台:keil4
串口0用DMA发送数据
下附部分代码,完整代码在后面
/*-------------------------MAIN FUNC
tiON------------------------------*/
/*********************************************************************//**
* @brief c_entry: Main UART program body
* @param[in] None
*
@Return int
**********************************************************************/
int c_entry(void)
{
uint8_t *rx_char;
uint32_t idx;
// UART Configuration structure variable
UART_CFG_Type UARTConfigStruct;
// UART FIFO configuration Struct variable
UART_FIFO_CFG_Type UARTFIFOConfigStruct;
GPDMA_Channel_CFG_Type GPDMACfg;
// Pin configuration for UART0
PINSEL_CFG_Type PinCfg;
/*
* Initialize UART0 pin connect
*/
PinCfg.Funcnum = 1;
PinCfg.OpenDrain = 0;
PinCfg.Pinmode = 0;
PinCfg.Pinnum = 2;
PinCfg.Portnum = 0;
PINSEL_ConfigPin(&PinCfg);
PinCfg.Pinnum = 3;
PINSEL_ConfigPin(&PinCfg);
/* Initialize UART Configuration parameter structure to default state:
* Baudrate = 9600bps
* 8 data bit
* 1 Stop bit
* None parity
*/
UART_ConfigStructInit(&UARTConfigStruct);
// Initialize UART0 peripheral with given to corresponding parameter
UART_Init(LPC_UART0, &UARTConfigStruct);
/* Initialize FIFOConfigStruct to default state:
* - FIFO_DMAMode = DISABLE
* - FIFO_Level = UART_FIFO_TRGLEV0
* - FIFO_ResetRxBuf = ENABLE
* - FIFO_ResetTxBuf = ENABLE
* - FIFO_State = ENABLE
*/
UART_FIFOConfigStructInit(&UARTFIFOConfigStruct);
// Enable DMA mode in UART
UARTFIFOConfigStruct.FIFO_DMAMode = ENABLE;
// Initialize FIFO for UART0 peripheral
UART_FIFOConfig(LPC_UART0, &UARTFIFOConfigStruct);
// Enable UART Transmit
UART_TxCmd(LPC_UART0, ENABLE);
/* GPDMA Interrupt configuration section ------------------------------------------------- */
/* Initialize GPDMA controller */
GPDMA_Init();
/* Setting GPDMA interrupt */
// Disable interrupt for DMA
NVIC_DisableIRQ (DMA_IRQn);
/* preemption = 1, sub-priority = 1 */
NVIC_SetPriority(DMA_IRQn, ((0x01<<3)|0x01));
// Setup GPDMA channel --------------------------------
// channel 0
GPDMACfg.ChannelNum = 0;
// Source memory
GPDMACfg.SrcMemAddr = (uint32_t) &menu1;
// Destination memory - don't care
GPDMACfg.DstMemAddr = 0;
// Transfer size
GPDMACfg.TransferSize = sizeof(menu1);
// Transfer width - don't care
GPDMACfg.TransferWidth = 0;
// Transfer type
GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_M2P;
// Source connection - don't care
GPDMACfg.SrcConn = 0;
// Destination connection
GPDMACfg.DstConn = GPDMA_CONN_UART0_Tx;
// Linker List Item - unused
GPDMACfg.DMALLI = 0;
// Setup channel with given parameter
GPDMA_Setup(&GPDMACfg);
// Setup GPDMA channel --------------------------------
// channel 1
GPDMACfg.ChannelNum = 1;
// Source memory - don't care
GPDMACfg.SrcMemAddr = 0;
// Destination memory
GPDMACfg.DstMemAddr = (uint32_t) &rx_buf;
// Transfer size
GPDMACfg.TransferSize = sizeof(rx_buf);
// Transfer width - don't care
GPDMACfg.TransferWidth = 0;
// Transfer type
GPDMACfg.TransferType = GPDMA_TRANSFERTYPE_P2M;
// Source connection
GPDMACfg.SrcConn = GPDMA_CONN_UART0_Rx;
// Destination connection - don't care
GPDMACfg.DstConn = 0;
// Linker List Item - unused
GPDMACfg.DMALLI = 0;
GPDMA_Setup(&GPDMACfg);
/* Reset terminal counter */
Channel0_TC = 0;
/* Reset Error counter */
Channel0_Err = 0;
// Enable interrupt for DMA
NVIC_EnableIRQ (DMA_IRQn);
// Enable GPDMA channel 0
GPDMA_ChannelCmd(0, ENABLE);
// Make sure GPDMA channel 1 is disabled
GPDMA_ChannelCmd(1, DISABLE);
//==上面常规串口配置初始化,DMA 配置通道配置初始化都没有问题,都能看懂
/* Wait for GPDMA on UART0 Tx processing complete */
while ((Channel0_TC == 0) && (Channel0_Err == 0));
/
/==注释是等待UART9 TX 处理完成,不是很明白 Channel0_TC 为什么要等于0才是正确处理完成 ,
/
/==如何多次用串口发送,
// Main loop - echos back to the terminal
/
/==后面是很串口0收到的数据回显 也没问题
while (1)
{
/* Reset terminal counter */
Channel1_TC = 0;
/* Reset Error counter */
Channel1_Err = 0;
// Setup channel with given parameter
GPDMA_Setup(&GPDMACfg);
// Enable GPDMA channel 1
GPDMA_ChannelCmd(1, ENABLE);
// Clear Rx buffer using DMA
for (idx = 0; idx < RX_BUF_SIZE; idx++){
rx_buf[idx] = 0;
}
// now, start receive character using GPDMA
rx_char = (uint8_t *) &rx_buf;
while ((Channel1_TC == 0) && (Channel1_Err == 0)){
// Check whether if there's any character received, then print it back
if (*rx_char != 0)
{
UART_Send(LPC_UART0, rx_char, 1, BLOCKING);
rx_char++;
}
}
}
}
关于中断找了很多 都没有这方面的资料 主要就是为什么要
Channel0_TC++;
GPDMA_ChannelCmd(0, DISABLE);
如果判断是终端计数器 为要要Channel0_TC++;并且还要关闭DMA 通道
/*----------------- INTERRUPT SERVICE ROUTINES --------------------------*/
/*********************************************************************//**
* @brief GPDMA interrupt handler sub-routine
* @param[in] None
* @return None
**********************************************************************/
void DMA_IRQHandler (void)
{
uint32_t tmp;
// Scan interrupt pending
for (tmp = 0; tmp <= 7; tmp++) {
if (GPDMA_IntGetStatus(GPDMA_STAT_INT, tmp)){
// Check counter terminal status
if(GPDMA_IntGetStatus(GPDMA_STAT_INTTC, tmp)){
// Clear terminate counter Interrupt pending
GPDMA_ClearIntPending (GPDMA_STATCLR_INTTC, tmp);
switch (tmp){
case 0:
Channel0_TC++;
GPDMA_ChannelCmd(0, DISABLE);
break;
case 1:
Channel1_TC++;
GPDMA_ChannelCmd(1, DISABLE);
break;
default:
break;
}
}
// Check error terminal status
if (GPDMA_IntGetStatus(GPDMA_STAT_INTERR, tmp)){
// Clear error counter Interrupt pending
GPDMA_ClearIntPending (GPDMA_STATCLR_INTERR, tmp);
switch (tmp){
case 0:
Channel0_Err++;
GPDMA_ChannelCmd(0, DISABLE);
break;
case 1:
Channel1_Err++;
GPDMA_ChannelCmd(1, DISABLE);
break;
default:
break;
}
}
}
}
}
补充内容 (2017-12-13 20:04):
也没人回答 我后来自己调试出来 中间出个低级错误 C语言基本错误
补充内容 (2017-12-13 20:06):
while ((Channel1_TC == 0) && (Channel1_Err == 0)) 我当时不知道为什么 进入了思维误区 DMA传送完成进入中断 Channel1_TC++,while ((Channel1_TC == 0) && (Channel1_Err == 0)) 是等待传送完成
补充内容 (2017-12-13 20:10):
如果要继续发送数据 因为DMA传输数据长度的寄存器值是更新的,。所以要重新配置 GPDMACfg.TransferSize,并且一定要关闭DMA通道,中断中完成DMA传输后自动关闭中断,所以后面要继续发送数据 先判断是一次是否发送完成 然后 重新给GPDMACfg.TransferSize赋值, GPDMA_Setup(&GPDMACfg); GPDMA_ChannelCmd(0, ENABLE);
-
-
DMA.rar
下载积分: 积分 -1 分
30.58 KB, 下载次数: 30, 下载积分: 积分 -1 分
一周热门 更多>