ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

【嵌入式外设精学】Day15|DMA:半满全满、乒乓、为什么丢数

【嵌入式外设精学】Day15|DMA:半满全满、乒乓、为什么丢数 【嵌入式外设精学】Day15DMA半满全满、乒乓、为什么丢数今天解决采集为什么尾部不对如何让 CPU 不跟数据抢着跑目录问题 2. 原理 3. 代码 4. 误区 5. 自测 6. 答案1. 问题ADC/串口配了 DMA 仍丢数处理慢一点缓冲里的数据就花掉2. 原理2.1 DMA 干什么外设和内存之间直接搬数据CPU 不用一个个字节去搬只处理结果。2.2 丢数的本质缓冲是循环写的。CPU 处理比 DMA 写得慢→ 旧数据还没用完就被覆盖。2.3 乒乓半区处理把大缓冲分成前后两半事件谁拥有哪半半满HTDMA 在写后半CPU 处理前半全满TCDMA 回头写前半CPU 处理后半同一时间每半只属于一个人就不会互相踩。2.4 时间条件用话记处理半区的最坏时间 填满半区的时间还要留调度余量。做不到就加大缓冲、降低采样率、加快算法。3. 代码示例#includestm32f4xx.h#includestdint.h#defineN1024ustaticuint16_tbuf[N];typedefenum{EVT_NONE,EVT_HALF,EVT_FULL}evt_t;staticvolatileevt_tevtEVT_NONE;voidDMA1_Stream0_IRQHandler(void){if(DMA_GetITStatus(DMA1_Stream0,DMA_IT_HTIF0)!RESET){DMA_ClearITPendingBit(DMA1_Stream0,DMA_IT_HTIF0);evtEVT_HALF;}if(DMA_GetITStatus(DMA1_Stream0,DMA_IT_TCIF0)!RESET){DMA_ClearITPendingBit(DMA1_Stream0,DMA_IT_TCIF0);evtEVT_FULL;}}voidprocess_half(uint16_t*p,uint32_tn){/* 滤波/FFT/统计… */(void)p;(void)n;}voidapp_dma_poll(void){evt_teevt;if(eEVT_NONE){return;}evtEVT_NONE;if(eEVT_HALF){process_half(buf[0],N/2u);}else{process_half(buf[N/2u],N/2u);}}4. 常见误区误区正解DMA 就永远不会丢处理跟不上仍会覆盖缓冲越小越好太小来不及处理运行中随便改 DMA 寄存器先停通道再改只开全满中断用 HT/TC 乒乓更稳5. 自测N1024HT 和 TC 各处理多少乒乓解决什么问题6. 答案各512。明确“这一半归 CPU、那一半归 DMA”避免写读冲突和撕裂。作者shuifanyu标签DMA乒乓采集
返回列表