[ÇÖZÜLDÜ] DMA + USART ile 16bit data transferi nasıl yapılır?

Başlatan tekosis, 17 Kasım 2018, 20:44:49

tekosis

stm32f103C8 + keil + Cubemx(hal library) kullanıyorum. 16 bit veriyi hızlı bir şekilde usarttan yollamam lazım. bu 16 bit veriyi yazılımsal olarak 8 bitlik iki parçaya ayırıp dma ile yollayabilirim ancak bunu yapmadan doğrudan yine dma ile 16 bitlik veriyi gönderme şansım var mıdır? bazen 8000 değişkene kadar veri yolamam gerekecek ki yazılımda zaman kaybetmeden mümkün ise donanımsal olarak bu işlemi gerçekleştirmek istiyorum.
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

devrecii

Dma'nin hafıza girişini 16bit tanımlayıp çıkışı 8bit ayarlayabilirsin.   uart data registeri 8 bit.

tekosis

Yeni yeni öğrenmeye başlıyorum hal library ve cubemx ayarlarını. Kullandığım dma ayarı aşağıdaki şekilde. Sizin dediğinize uyuyor mu?


İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

devrecii

Her iki tarafın da byte olması daha doğru olur çünkü tek clockta 2 tane ard arda byte göndermeye çalışabilir. uarttan dma ya gelen her clokta bir byte gitmesi gerekir.

Önemli olan dizinin adresidir 16bit hafızada olsa 32bit de olasa hafızada byte olarak saklanıyor ,  dma ya source olarak bu dizinin adresini vermelisin, dest adres olarak uart data registeri adresini vermelisin.

uartın dma için register ayarları da var, cubemx bunları hallediyormu bilmiyorum, yoksa çok iş var.

Elektroemre

#4
Mesela:

uint16_t dizi[8192]; olsun

Siz DMA ayarında source(dizi) ve destination(usart)'ın data size'ını 8bit ayarlayıp, DMA ile gönderilecek veri size'ını 8192 * 2 = 16384 yapmanız yeterli.

Diğer türlü source(dizi) 16bit, destination(usart) 8bit ayarlarlayıp, veri size'ını 8192 yaparsanız büyük ihtimalle, düşük ya da yüksek değerlikli 8bit karşıya gönderilir.


Ekleme: Her şey düzgün çalıştığında da endian problemi olabilir, dikkat etmek lazım. (byte order)


tekosis

#5
en altta kod parçam mevcut. derlediğim zaman "error:  #167: argument of type "uint16_t *" is incompatible with parameter of type "uint8_t *" hatasını alıyorum. benden uint8_t tipinde değişken vermemi istiyor. Bir de MX_DMA_Init() kısmında 8 bit yada 16 bit ile ilgili bir ayar yok. şimdi kütüphaneyi inceliyorum.

hocam ayarlarım şu şekide ;
uart ayarları :
static void MX_USART1_UART_Init(void)
{
  huart1.Instance = USART1;
  huart1.Init.BaudRate = 460800;
  huart1.Init.WordLength = UART_WORDLENGTH_8B;
  huart1.Init.StopBits = UART_STOPBITS_1;
  huart1.Init.Parity = UART_PARITY_NONE;
  huart1.Init.Mode = UART_MODE_TX_RX;
  huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  if (HAL_UART_Init(&huart1) != HAL_OK)
  {
    _Error_Handler(__FILE__, __LINE__);
  }
}

dma ayarları :

static void MX_DMA_Init(void) 
{
  __HAL_RCC_DMA1_CLK_ENABLE();
  HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);
}

aşağıda da kod parçam mevcut :

  uint16_t 	data16bit[5];
	  data16bit[0]=0xabcd;
	  data16bit[1]=0x1234;
	  data16bit[2]=0x1010;
	  data16bit[3]=0x78cb;
	  data16bit[4]=0x1000;
   	  HAL_UART_Transmit_DMA(&huart1,data16bit,10);
		while (1)
		{ }

dma ayar penceresi :


İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.

tekosis

#6
çözüldü: 
uygulamamda stm32f1xx_hal_msp.c altında aşağdıdaki kodlar mevcut. burada data genişliği vs ayarları mevcut. cubemx üzerinden veya buradan düzeltmek mümkün. Aşağıdaki satırlarda data boyutu ayarlanabiliyor. Henüz yüksek sayıda değişken denemedim bir problem olursa buradan yazarım.

@Elektroemre @iboibo teşekkür ederim.

/* USART1 DMA Init */
    /* USART1_TX Init */
    hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
    hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
 

aşağıdaki kod parçası ile yaptığım deneme olumlu sonuç verdi, istediğim sonucu altım.

  printf("\nbirazdan veri yolanacak : \n");
   HAL_Delay(1500);
   
    uint16_t data16bit[5];
   data16bit[0]=0x6261;
   data16bit[1]=0x6463;
   data16bit[2]=0x6665;
   data16bit[3]=0x6867;
   data16bit[4]=0x6a69;
   
    HAL_UART_Transmit_DMA(&huart1,(uint8_t *)data16bit,10);// burada casting işlemi yapınca sorun çözüldü.
   while(1)
   {
   HAL_Delay(10);
   }
İlim ilim bilmektir, ilim kendin bilmektir, sen kendin bilmezsin, bu nice okumaktır.