Mục tiêu
- Học cách cấu hình DMA transfer với CubeIDE
- Tạo transfer truyền dữ liệu từ RAM tới RAM
Kết quả
- Sử dụng CubeIDE sinh code DMA
- Sử dụng các function HAL của DMA
- Kiểm tra các chức năng bằng việc so sánh các buffer truyền nhận
Cấu hình DMA
Tạo project
- Cách làm tương tự như 2 bài hướng dẫn trước File > New > STM32 Project
- Với DMA thì chúng ta không cần cấu hình bất kỳ chân nào
Cấu hình clock
- Set clock với tần số tối đa
Cấu hình DMA
- Thẻ Pinout & Configuration > DMA > DMA2 > Add
- Chọn MEMTOMEM DMA request
- Normal mode, Increment Address source memory và destination memory
- Dùng FIFO
- Byte data width
- Burst size là single
Sau đó là save và auto generate code
Workflow
Quá trình start DMA (tương tự TIM, ADC)
- Quá trình start non blocking
- Kết thúc của quá trình phải được check bằng polling
Return value
- Hầu hết function HAL đều có return value với mục đích để thông báo nếu hoạt động là thành công, timeout hoặc là lỗi
- Developer được khuyến khích là handle các giá trị return để đảm bảo rằng chương trình chạy đúng với mong đợi
Mọi người có thể xem các return value của DMA dưới hình sau
Code
Giờ thì mở file main.c
và sửa code, HAL function được dùng cho DMA là
HAL_DMA_Start(DMA_HandleTypeDef hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)
HAL_DMA_PollForTransfer(DMA_HandleTypeDef hdma, uint32_t CompleteLevel, uint32_t Timeout)
Chúng ta cần tạo 2 buffer
- Một buffer cho source data
- Một cho destination data
HAL_DMA_Start
sẽ khởi động quá trình transfer data M2MHAL_DMA_PollForTransfer
kiểm tra quá trình transfer kết thúc thành công hay chưa.
/* USER CODE BEGIN 0 */
uint8_t Buffer_Src[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
uint8_t Buffer_Dest[10];
/* USER CODE END 0 */
//..
/* USER CODE BEGIN 2 */
HAL_DMA_Start(&hdma_memtomem_dma2_stream0, (uint32_t)(Buffer_Src), (uint32_t)(Buffer_Dest), 10);
while (HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream0, HAL_DMA_FULL_TRANSFER, 100) != HAL_OK)
{
__NOP();
}
/* USER CODE END 2 */
Link code vẫn ở chỗ cũ cho mọi người tham khảo