天天看點

stm32 檔案系統dma大小_stm32 DMA 的 buffersize 意義與設定

總結一下:

我的了解是一次傳輸多個資料,不管你的資料是8位,16位還是32位,也就相當于你接收資料部分緩存的資料量。buf[buf_size],就是這個bufe_size。

1.看庫函數中

DMAy_Channelx->CNDTR = DMA_InitStruct->DMA_BufferSize;

而CNDTR即資料傳輸數量 (Number of data to transfer)

資料傳輸數量為0至65535。這個寄存器隻能在通道不工作(DMA_CCRx的EN=0)時寫入。通

道開啟後該寄存器變為隻讀,訓示剩餘的待傳輸位元組數目。寄存器内容在每次DMA傳輸後遞

減。

資料傳輸結束後,寄存器的内容或者變為0;或者當該通道配置為自動重加載模式時,寄存

器的内容将被自動重新加載為之前配置時的數值。

當寄存器的内容為0時,無論通道是否開啟,都不會發生任何資料傳輸。

2.DMA_BufferSize的大小應該取多少?

上面的讨論很多同學就疑惑了,這個大小應該取多少呢?暫時我建議你需要多少資料就寫多少。

__IO uint16_t ADC_ConvertedValue[NUM];

一般,我們會定義一個變量存我們的資料,然後

DMA_InitStruct.DMA_BufferSize = NUM;

DMA_InitStruct.DMA_MemoryBaseAddr = (u32)&ADC_ConvertedValue;

這時候,緩沖區的大小和我們定義的數組一緻,也友善我們操作。

但是如果DMA_BufferSize大于NUM會怎麼樣?根據上面問題1的解釋,緩沖區位址其實就是我們的ADC_ConvertedValue位址,如果DMA_BufferSize為NUM+N,其實緩沖區就是ADC_ConvertedValue[NUM+N],再說一遍,Buffer的首位址和ADC_ConvertedValue相同,如果我們用指針通路,可以很好的驗證。

__IO uint16_t *p;

p=ADC_ConvertedValue;

省略代碼,printf是序列槽通信改寫的函數….

printf(“%4x\n”,ADC_ConvertedValue[NUM-1]);

printf(“%4x\n”,*(p+NUM));

printf(“%4x\n”,*(p+NUM+1));

你會很吃驚的發現,*(p+NUM)裡面也有我們采樣的資料。如果我們用ADC_ConvertedValue[NUM]通路則會出錯,因為超出數組範圍了。也就是說DMA_BufferSize可以大于NUM,但是大于NUM的位址屬于不被定義的内容。從程式設計角度,它使用了未知的區域,如果這個位址定義别的變量,那麼就會誤操作這個變量。

ysmz4:可以将DMA_SetCurrDataCounter(DMA2_Channel3,R_B_SIZE); //設定傳輸資料長度

改成DMA_SetCurrDataCounter(DMA2_Channel3,n);    //n為實際用到的大小

我覺得就可以避免這個問題。

__IO uint16_t ADC_ConvertedValue[NUM];

__IO uint16_t a[N];

比如我們定義時候,緊跟ADC_ConvertedValue定義一個a;一般編譯器會把這兩個變量的位址連在一起。那麼在運作程式時候:

printf(“%4x\n”,ADC_ConvertedValue[NUM-1]);

printf(“%4x\n”,*(p+NUM));

printf(“%4x\n”,ADC_ConvertedValue[NUM-1]);

printf(“%4x\n”,a[0]);

是一樣的資料。

很危險吧。a[0]的資料就被DMA覆寫了。