Thắc mắc về hàm DMA trong stm32f1

Chào mọi người. Mình dùng DMA trong stm32f1 để chuyển dữ liệu từ memory tới memory thì trong hàm khởi động DMA có thông số địa chỉ nguồn và địa chỉ đích, mình không biết điền gì vào 2 thông số này, điền như nào? anh em nào biết chỉ giúp mình với:
nguyeen mẫu hàm DMA nhưa sau:

HAL_DMA_Start(DMA_HandleTypeDef *hdma, uint32_t SrcAddress, uint32_t DstAddress, uint32_t DataLength)

và nó được sử dụng trong hàm main:

HAL_DMA_Start_IT(&DmaHandle, (uint32_t)&aSRC_Const_Buffer, (uint32_t)&aDST_Buffer, BUFFER_SIZE)

kí tự & phía trước tên biến có ý nghĩa gì các bạn?

Em không biết DMA là gì nhưng em có 1 thắc mắc nhỏ là anh đã học C/C++ hay 1 ngôn ngữ nào chưa ạ. Nếu rồi thì anh đã học 1 về con trỏ, tham số và đối số chưa nhỉ. Nếu rồi thì mọi người có thể giải thích cho anh. Còn nếu chưa thì phụ thuộc vào việc anh đang làm có liên quan mật thiết đến lập trình hay không. Nếu không thì cứ coi đó là 1 cú pháp/cấu trúc hay gì đó cũng được.

2 Likes

trong trường chỉ dạy anh về pascal, còn đây là ngôn ngữ C dùng cho lập trình nhúng. con trỏ anh đọc nhiều lần nhưng vẫn mơ hồ

ngoài pascal ra, còn lại C anh tự học em ạ, cám ơn em đã trả lời

1 Like

merged and moved by noname00

Vậy thì có lẽ anh hiểu con trỏ là gì rồi. Em xin phép diên x giải cách hiểu của em.
Do con trỏ là 1 biến chứa địa chỉ của 1 biến khác, bên hàm nguyên mẫu yêu cầu giá trị nhận vào kiểu *(kiểu con trỏ) nên mình cần truyền giá trị kiểu con trỏ hoặc địa chỉ 1 biến vào. Có thể hiểu dấu & là toán tử để lấy địa chỉ của 1 biến nào đó.

5 Likes

mục đích của việc sử dụng hàm đó là gì?

1 Like

Địa chỉ nguồn, địa chỉ đích là địa chỉ của 2 đoạn bộ nhớ nguồn và đích. DMA sẽ copy dữ liệu nằm ở địa chỉ nguồn đến địa chỉ đích mà không cần thông qua quá trình xử lý của cpu.

Dấu & phía trước biến là để lấy địa chỉ của biến đó. Phải có địa chỉ của biến để truyền vào các hàm của DMA thì nó mới có thể copy dữ liệu vào biến đó hoặc từ biến đó đi nơi khác.

4 Likes

Mình nghĩ là bạn xem code mẫu của Cube IDE, tương tự tại đây: https://github.com/STMicroelectronics/STM32CubeF7/blob/08376dce1b404687e4a86b73077f396bccfc9cb5/Projects/STM32F746ZG-Nucleo/Examples/DMA/DMA_FLASHToRAM/Src/main.c#L178

Theo mình thấy thì code mẫu này bị dư dấu & . Chứng tỏ khâu review code của STM32 team không tốt. :weary:. Nghĩa là có hay không có & đều như nhau.

Mặt khác, mình nghĩ là bạn nên học kỹ lại phần pointer trước khi tiếp tục học về STM32.

4 Likes

mình code DMA thế này mà ko biết vì sao nó ko chạy: đoạn code này khởi rạo DMA theo chế độ vòng tròn để chuyển dữ liệu nhận được từ UART vào rx, sau đó liên tục kiểm tra rx[0] ==‘a’ không, nếu bằng thì nháy led và gửi lại chuỗi hello về máy tính

int main(void)
{
  /* USER CODE BEGIN 1 */
	uint8_t rx[10],tx[] = "hello world\r\n";
  /* USER CODE END 1 */
  

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_LPUART1_UART_Init();
  MX_DMA_Init();
  /* USER CODE BEGIN 2 */
	//HAL_UART_Receive_IT(&hlpuart1,tx,1);	
	HAL_UART_Receive_DMA(&hlpuart1,rx,4);
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
		//HAL_UART_Transmit(&hlpuart1,tx,13,1000);
		//HAL_UART_Receive(&hlpuart1, rx, 1, 1000);
		//HAL_UART_Receive_DMA(&hlpuart1,rx,1);
		if(rx[0]=='a')
		{
			HAL_GPIO_TogglePin(LED_0_GPIO_Port,LED_0_Pin);
			rx[0] = 0;
			HAL_UART_Transmit(&hlpuart1,tx,13,1000);
			//HAL_GPIO_TogglePin(
		}
		//HAL_Delay(1000);
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}

Tới đây thì mình khá khá khá lười để debug giúp bạn.
Cho bạn 1 tia hy vọng (hên xui) nè:

5 Likes

Nó làm như vậy là chuẩn đấy, khi size bằng 1, tức là 1 biến thì toán tử "& "vẫn lấy đc địa chỉ của nguồn và đích và thực hiện copy 1 byte từ nguồn sang đích. Nếu không có toán tử & thì sai rồi

2 Likes

có toán tử & là đúng nhưng chương trình ko chạy bạn ạ

2 Likes

Truyền vào 1 biến hay truyền vào pointer của mảng là 2 case khác nhau. Sao lại đánh đồng như vậy.

Mình không nói nó sai nhé! Mình nói là nó dư trong trường hợp này. Vì &&&&ptr == &ptr
Ở trên đã gợi ý link stackoverflow về việc đảo thứ tự init rồi. Ít nhất là bạn nên sửa việc đó.

4 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?