完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
扫一扫,分享给好友
小弟我最近想实现串口用DMA 发送数据 手里只有一分官方DMA 的事例,对于有些地方实在不理解,萌新也没有师傅带,希望论坛大哥多带带
硬件平台 LPC1768 软件平台:keil4 串口0用DMA发送数据 下附部分代码,完整代码在后面 /*-------------------------MAIN FUNCtiON------------------------------*/ /*********************************************************************//** * @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);
|
|
相关推荐
1个回答
|
|
呵呵 自己给自己回答了 后面 继续搞SPI DMA w25q64
|
|
1 条评论
|
|
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
嵌入式学习-飞凌嵌入式ElfBoard ELF 1板卡-LCD显示图片编程示例之介绍mmap
180 浏览 0 评论
《DNESP32S3使用指南-IDF版_V1.6》第二章 常用的C语言知识点
587 浏览 0 评论
【RA-Eco-RA2E1-48PIN-V1.0开发板试用】(第三篇)ADC采集+PWM输出
549 浏览 0 评论
《DNK210使用指南 -CanMV版 V1.0》第四十五章 人脸识别实验
548 浏览 0 评论
1051 浏览 0 评论
【youyeetoo X1 windows 开发板体验】少儿AI智能STEAM积木平台
11763 浏览 31 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 16:58 , Processed in 0.431626 second(s), Total 47, Slave 37 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号