完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
嗨,我正在使用一个DSPIC33 EP512MC202和MixStiK II开发工具包。我使用DMA将数据从ADC传输到ED中声明的2个缓冲器。DMA被配置为乒乓模式。我想使用for循环找到缓冲区中的最大值,然后如果该值超过阈值,则关闭DMA/ADC。理想情况下,这将发生在DMA中断中,所以我需要的数据没有被DMA写过。我在中断程序中遇到了一个问题,当我把循环添加到查找最大值时,DMA缓冲区没有被交换。这就是我的中断的样子:我的DMA初始化函数在这里:如果我使用调试器,DMAPPsBIT.PPST0寄存器值一致。如果中断例程不包含循环以查找缓冲区中的最大值,则每次中断0到1之间的ping。使用循环来找到最大值,DMAPPsBIT.PPST0寄存器值保持在0。有人对如何修复这个问题/什么可能出错有什么建议?谢谢!
以上来自于百度翻译 以下为原文 Hi, I'm working with a dsPIC33EP512MC202 and a MicroStik II development kit. I'm using the DMA to transfer data from the ADC to 2 buffers declared in EDS. The DMA is configured for ping-pong mode. I would like to use a for loop to find the maximum value in a buffer and then if that value exceeds a threshold to then turn off the DMA/ADC. Ideally, this would occur within the DMA interrupt so that the data that I need is not over-written by the DMA. I'm having an issue with the interrupt routine where the DMA buffers are not being swapped when I add the loop to the find the maximum value. This is what my interrupt looks like: void __attribute__ ( ( interrupt, no_auto_psv ) ) _DMA0Interrupt( void ) { //Reset the interrupt flag IFS0bits.DMA0IF = 0; BUFFER_INDEX = DMAPPSbits.PPST0; //IO_RA0_SetHigh(); if (CURRENT_BUFFER == 0){ BUFFERA_FULL = 1; } else{ BUFFERA_FULL = 0; } if(BUFFERA_FULL == 1){ //if(BUFFER_INDEX == 2){ /*CURRENT_BUFFER = 1;*/ //BUFFERA_FULL = 1; //Find the max value in the buffer for (i = 0; i < BUFFER_SIZE; i++){ /*if (BUFFER_A > max){ max = BUFFER_A; }*/ max = (max > BUFFER_A?max:BUFFER_A); } } //this was changed to if from else if //if (CURRENT_BUFFER == 1){ else{ /*CURRENT_BUFFER = 0;*/ //BUFFERA_FULL = 0; /*k = DMAPPSbits.PPST0;*/ for (i = 0; i < BUFFER_SIZE; i++){ /*if (BUFFER_B > max){ max = BUFFER_B; }*/ max = (max > BUFFER_B?max:BUFFER_B); } } My DMA initilization function is here: void DMA_Initialize_1(void) { // Initialize channels which are enabled // AMODE Peripheral Indirect Addressing mode; CHEN enabled; DIR Reads from peripheral address, writes to RAM address; HALF Initiates interrupt when half of the data has been moved; SIZE 16 bit; NULLW disabled; MODE Continuous, Ping-Pong modes are enabled; //DMA0CON= 0x9022 & 0x7FFF; //Enable DMA Channel later; // FORCE disabled; IRQSEL ADC1; //DMA0REQ= 0xD; // CNT 0; //DMA0CNT= BUFFER_SIZE - 1; // STA 4096; //Initialize the DMA buffers //DMA0STAL= 0x1000; //Transfer a word at a time DMA0CONbits.SIZE = 0; //Read from peripheral write to RAM DMA0CONbits.DIR = 0; //Generate Interrupt when the entire transfer has completed //DMA0CONbits.HALF = 0; //Generate Interrupt when all of the transfer has completed DMA0CONbits.HALF = 0; //When the full transfer is complete //DMA0CONbits.HALF = 0; //Normal operation DMA0CONbits.NULLW = 0; //DMA Configured for Peripheral Indirect Mode //DMA0CONbits.AMODE = 2; DMA0CONbits.AMODE = 0; //Configure for Continuous Ping-Pong Mode DMA0CONbits.MODE = 2; DMA0PAD = (int)&ADC1BUF0; //ADC1 Selected as DMA Request Source DMA0REQ = 13; DMA0CNT = ( BUFFER_SIZE - 1 ); //DMA0CNT = 7; DMA0STAL = __builtin_dmaoffset(&BUFFER_A); DMA0STAH = __builtin_dmapage(&BUFFER_A); /*DMA0STAL = __builtin_dmaoffset(&gDataBuff); DMA0STAH = __builtin_dmapage(&gDataBuff);*/ /*DMA0STAL =&BUFFER_A; DMA0STAH = &BUFFER_A;*/ //DMA0STAH = 0x0000; DMA0STBL = __builtin_dmaoffset(&BUFFER_B); DMA0STBH = __builtin_dmapage(&BUFFER_B); /*DMA0STBL = &BUFFER_B; DMA0STBH = &BUFFER_B;*/ //DMA0STBH = 0x0000; // STA 0; //DMA0STAH= 0x0; // Clearing Channel 0 Interrupt Flag; IFS0bits.DMA0IF = false; // Enabling Channel 0 Interrupt IEC0bits.DMA0IE = 1; //Enable DMA Channel 0 DMA0CONbits.CHEN = 1; } If I go through using the debugger the DMAPPSbits.PPST0 register value consistently ping-pongs between 0 and 1 every time the interrupt fires if the interrupt routine does not contain the loop to find the max value in the buffer. With the loop to find the maximum value the DMAPPSbits.PPST0 register values stays at 0. Does anyone have any advice on how to fix this issue/what might be going wrong? Thanks! |
|
相关推荐
3个回答
|
|
很难准确地知道你是如何设置所有这些注释行的DMA通道的,但是我认为它是可以的——你是在乒乓模式下,在每个缓冲区都满了之后发生中断。我怀疑你在ISR内部占用的时间太长。我建议你沿着伪代码的线条清理代码:我不知道这是否足够快,但值得一试。如果没有别的,它将减少大量的数组索引操作和开始时的测试次数。当然,如果MAX被使用在ISR之外,那么它应该被声明为易失性。苏珊。
以上来自于百度翻译 以下为原文 It is hard to see exactly how you have set up the DMA channel with all of those commented out lines but I think it is OK - you are in ping-pong mode with interrupts occurring after each buffer is fulled. I suspect that you are taking too long inside the ISR. I suggest that you clean up the coding there along the lines of the pseudo code: int *value_ptr = BUFFERA; int i; if( DMAPPSbits.PPST0) { value_ptr = BUFFERB; } for(i = 0; i < BUFFER_SIZE; i++) { if( max < *value_ptr) { max = *value_ptr; } value_ptr++ } I have no idea if that will be fast enough but it is worth a shot. If nothing else it will cut down on the large number of array indexing operations and the number of tests at the start. Of course, if max is used outside of the ISR then it should be declared as volatile. Susan |
|
|
|
非常感谢你的信息!你建议的数组指针方法确实有点帮助。它允许采样比我们以前使用的方法更快地停止大约200μs。我最后做的是调整PLL设置,以提高MCU的处理器速度,同时保持ADC采样速度相同。这最终解决了你指出的问题。谢谢你的帮助!
以上来自于百度翻译 以下为原文 Thanks very much for the info! The array pointer method that you suggested did help a little bit. It allowed the sampling to be stopped about 200 us sooner than with the previous method I was using. What I ended up doing was adjusting the PLL settings to increase the processor speed for the MCU while keeping the ADC sampling speed the same. This ended up fixing the problem that you pointed out. Thanks for the help! |
|
|
|
在这种情况下,最好还是将大部分代码从ISR中移出。一般来说,ISR应该尽可能快地执行。尝试在ISR中设置一个标志来指示需要检查哪些缓冲区并在主循环中测试该缓冲区。只要采样不比你想要执行的循环快,那么所有的都会很好。(当然,如果样品来得太快,你不能跟上十,你还有其他问题!)苏珊
以上来自于百度翻译 以下为原文 In that case it would be better still to move the bulk of the code out of the ISR. In general an ISR should be as quick executing as possible. Try setting a flag in the ISR to indicate which buffer needs to be checked and testing that in the main loop. As long as the sampling is not faster than the loop you want to execute then all will be well. (Of course if the samples are coming in so fast that you can't keep up ten you have other problems!) Susan |
|
|
|
只有小组成员才能发言,加入小组>>
5234 浏览 9 评论
2026 浏览 8 评论
1950 浏览 10 评论
请问是否能把一个ADC值转换成两个字节用来设置PWM占空比?
3200 浏览 3 评论
请问电源和晶体值之间有什么关系吗?PIC在正常条件下运行4MHz需要多少电压?
2253 浏览 5 评论
771浏览 1评论
659浏览 1评论
有偿咨询,关于MPLAB X IPE烧录PIC32MX所遇到的问题
588浏览 1评论
PIC Kit3出现目标设备ID(00000000)与预期的设备ID(02c20000)不匹配。是什么原因
669浏览 0评论
571浏览 0评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-19 19:56 , Processed in 1.203549 second(s), Total 83, Slave 66 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号