牛卧堂MCU技术交流

标题: 看来只有顶楼才会得到回复。我就重开一贴,关于PDMA [打印本页]

作者: 与时俱进    时间: 2014-5-2 11:10
标题: 看来只有顶楼才会得到回复。我就重开一贴,关于PDMA
本帖最后由 与时俱进 于 2014-5-2 11:18 编辑

我用Nano130板做SD读卡实验,SPI0用32位模式传输128字,原先程序是
            for( i=0;i<128;i++)
            {
            SPI0->CTL |= SPI_CTL_GO_BUSY;  //目的是发送时钟
            while(SPI0->CTL & SPI_CTL_GO_BUSY); //等待发送完成
            *p++ = SPI0->RX0;      //从SD卡接收数据存入缓冲区
            }

以上程序经过验证可以得到正确结果。我现在想用PDMA模式,把上述程序改成
                PDMA_Init();
                PDMA_EnableChannelClock(PDMAGCR_CSR_CLK1);/* Enable Channel 1 Clock */
                sPDMA.DestAddr  = (uint32_t)p;    //目的地址
                sPDMA.SrcAddr = (uint32_t)&(SPI0->TX0);   //源地址
                sPDMA.SrcCtrl  = PDMA_CSR_SAD_FIX;        //固定源地址
                sPDMA.DestCtrl = PDMA_CSR_DAD_INC;     //目的地址递增
                sPDMA.TransWidth = PDMA_CSR_APB_TWS_32BIT;  //32位
                sPDMA.Mode = PDMA_CSR_IP2MEM;
                sPDMA.ByteCnt  = 128*4;
                sPDMA.IsTimeOutEnable = 0;
                PDMA_Open(PDMA1, &sPDMA);
                PDMA_SPI0_RX_TO_CH1();   //PDMA1
                PDMA_CHEnableTransfer(PDMA1);
                SPI_SetRxPDMA(SPI0, TRUE);        //
                SPI_SetGo(SPI0);
                while(!(PDMA1->ISR & PDMA_ISR_TD));    //等待DMA传输完成
                SPI_SetTxPDMA(SPI0, FALSE);
                PDMA_Close();
                PDMA_DeInit();
                p+=128;

实验结果不对,没有正确从SD卡读到数据,为什么?程序哪里有问题吗?
仿真中,SPI_SetGo(SPI0)执行前,PDMA1->ISR值是0,执行后,PDMA1->ISR值马上变为2,这个是不对的,不知何故。

作者: a_ziliu    时间: 2014-5-2 22:18
你的sdcard有先初始化嗎?另外的問題,初始化後有掛fatfs去讀卡的內容嗎?

作者: 与时俱进    时间: 2014-5-3 09:54
本帖最后由 与时俱进 于 2014-5-3 12:10 编辑

SD卡经过初始化,没用FATFS读内容,直接用扇区读程序,读出0扇区再用半主机显示出来。
我已经声明过“以上程序经过验证可以得到正确结果。”----指第一段程序。第二段程序用来替换第一段的。
关键是PDMA传输这样写,程序本身有没有什么地方错误和疏漏。
作者: 与时俱进    时间: 2014-5-3 11:28
本帖最后由 与时俱进 于 2014-5-3 14:20 编辑

找到程序的两个错误:1、源地址应该是&(SPI0->RX0)  2、关闭接收DMA应该用SPI_SetRxPDMA(SPI0, FALSE);
但是这样改后,读第一个扇区正常,后续扇区还是不行,说明第二段程序还是不能完全替换第一段程序。
作者: 与时俱进    时间: 2014-5-3 12:04
可能的原因:
1、关闭PDMA用如下3个语句还不够:
                SPI_SetTxPDMA(SPI0, FALSE);
                PDMA_Close();
                PDMA_DeInit();
2、这种PDMA传输是否很严格地只传输指定字节的数据,换句话说,是否在时钟线上仅仅送出指定字节的时钟信号?会不会时钟“过冲”。
SD卡多扇区读的时序是:  发命令----握手----传第1扇区数据-----握手---传第2扇区数据----,如果时钟“过冲”,可能造成后续扇区握手不成功,导致读取后续扇区失败。
作者: 与时俱进    时间: 2014-5-3 14:28
本帖最后由 与时俱进 于 2014-5-9 20:42 编辑

经过试验,传输完数据,要加上PDMA1->ISR=PDMA1->ISR;  为什么?
正确的程序是:
                PDMA_Init();
                PDMA_EnableChannelClock(PDMAGCR_CSR_CLK1);/* Enable Channel 1 Clock */
                sPDMA.DestAddr  = (uint32_t)p;    //目的地址
                sPDMA.SrcAddr = (uint32_t)&(SPI0->RX0);   //源地址
                sPDMA.SrcCtrl  = PDMA_CSR_SAD_FIX;        //固定源地址
                sPDMA.DestCtrl = PDMA_CSR_DAD_INC;     //目的地址递增
                sPDMA.TransWidth = PDMA_CSR_APB_TWS_32BIT;  //32位
                sPDMA.Mode = PDMA_CSR_IP2MEM;
                sPDMA.ByteCnt  = 128*4;
                sPDMA.IsTimeOutEnable = 0;
                PDMA_Open(PDMA1, &sPDMA);
                PDMA_SPI0_RX_TO_CH1();   //PDMA1
                PDMA_CHEnableTransfer(PDMA1);
                SPI_SetRxPDMA(SPI0, TRUE);        //
                SPI_SetGo(SPI0);
                while(!(PDMA1->ISR & PDMA_ISR_TD));    //等待DMA传输完成
                      PDMA1->ISR=PDMA1->ISR;
                SPI_SetRxPDMA(SPI0, FALSE);
                PDMA_Close();
                PDMA_DeInit();
                p+=128;
作者: 与时俱进    时间: 2014-5-6 08:22
与时俱进 发表于 2014-5-3 14:28
经过试验,传输完数据,要加上PDMA1->ISR=PDMA1->ISR;  为什么?
正确的程序是:
                PDMA_Ini ...

@a_ziliu 请指教。   
作者: a_ziliu    时间: 2014-5-7 09:45
PDMA1->ISR=PDMA1->ISR;
是在清除pdma的中斷旗號位。
作者: a_ziliu    时间: 2014-5-7 09:46
忘了問那一版的bsp?
作者: 与时俱进    时间: 2014-5-7 10:08
a_ziliu 发表于 2014-5-7 09:46
忘了問那一版的bsp?

DownloadList_NANO100B_Series_CMSIS_BSP_EN_Rev1.00.007.zip
作者: 与时俱进    时间: 2014-5-7 10:14
用UDC例程自己添加SD卡程序的。做的是SD卡读卡器。
后来发现,BSP里好像有SD卡的程序。
作者: 与时俱进    时间: 2014-5-7 21:13
a_ziliu 发表于 2014-5-7 09:45
PDMA1->ISR=PDMA1->ISR;
是在清除pdma的中斷旗號位。

我的程序没开PDMA中断,按道理没必要清除中断标志?
作者: a_ziliu    时间: 2014-5-9 11:00
因為手頭上沒有舊的BSP
請參考附件的例子,是用BSP 3.0寫的。
結合PDMA+SPI
Smpl_Basic01_SPI_Flash_w_PDMA.7z (11.32 KB, 下载次数: 914)




欢迎光临 牛卧堂MCU技术交流 (http://nuvoton-mcu.com/) Powered by Discuz! X3.2