HAL Kütüphanesi ile UART'ta Size sorunsalı

Başlatan Cemre., 26 Şubat 2016, 16:10:17

Cemre.

Herkese iyi günler.

Anlayamadığım bir nokta var. UART ile veri gönderip almak için HAL kütüphanesinde

HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)
HAL_UART_Transmit(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout)

diye iki fonksiyon mevcut. Bu iki fonksiyonun IT ve DMA şeklinde ikişer tane de türevleri var. Peki ben bu fonksiyonları kullanarak Size'ını bilmediğim bir veriyi nasıl gönderip alabilirim? Şuan GPS ile çalışıyorum ve eğer GPS kapalı alandaysa $GPGGA,,,,,, gibi boş veriler gönderiyor. Yani uzunluk çoğu zaman değişken oluyor. Bu durumda Size belirsiz.

Buna bir çözüm misal "$ karakteri gelene kadar bekle" "* karakteri gelene kadar okumaya devam et" gibi bir mantık olabilir. Ancak ben bu kontrolü nasıl yapacağımı bilmiyorum. Nereden başlayayım?

Teşekkürler, iyi günler.

ArifAhmet

Yaşasın Open Source!

Cemre.

Alıntı yapılan: ArifAhmet - 26 Şubat 2016, 16:32:58
sizeof(degisken) / sizeof(veri tipi)

Hocam doğmamış çocuğa nasıl don biçeceğim ki?

Misal GPS'ten veri gelecek.

if(HAL_UART_Receive(&UartHandle, (uint8_t *)aRxBuffer, RXBUFFERSIZE, 5000) != HAL_OK)
  {
    Error_Handler();  
  }


Yukarıdaki şekilde veriyi alacağımı varsayalım. RXBUFFERSIZE yerine ne yazacağım? Gelecek verinin Size'ı değişken. Daha kısa veri gelirse TimeOut olacak, daha uzun veri gelirse fazlalık kısım umrunda olmayacak. Nasıl olacak anlayamadım. Mantığını yanlış anladığım bir fonksiyon var mı?

ArifAhmet

teker teker almayi denedin mi? her seferinde tek bir char
Yaşasın Open Source!

Cemre.

Hayır hocam denemedim, ama aklıma şöyle bir şey geliyor.

HAL_UART_ReceiveIT fonksiyonu ile 1 byte veri almaya çalışsam, veri geldiğinde yönlendirdiği interrupt fonksiyonunda da gelen verinin misal "$" olup olmadığını kontrol etsem. Daha sonra nasıl devam ederim?

ArifAhmet

Kendin icin bir flag belirle. Gelen data "$" ise birdahaki "$"a kadar veriyi almaya devam etsin, sonra kontrol edip diger datayi alirsin
Yaşasın Open Source!

Cemre.

#6
Son durum şöyle ve anlayamadığım bir sorun var.

GPS'ten şuan gelen veri bu. (USB Seri dönüştürücü ile okuyorum)

$GPRMC,192019.00,V,,,,,,,260216,,,N*7E
$GPGGA,192019.00,,,,,0,00,99.99,,,,,,*64


Benim veri almaya çalıştığım kod ise aşağıda.

Bu durumda $.........* gibi 100 karakterlik bir veri gönderdiğimde tam olarak aynısını geri gönderebiliyor ve bunu çok sık aralıklarla yapabiliyor. (100ms civarı deneyebildim.)

Ancak GPS'in göderdiği veriyi almaya çalıştığımda aynı şey olmuyor. Bazen ilk 6 karakteri bazen ilk 7 karakteri alıyor. Canı nasıl isterse öyle takılıyor. GPS 1Hz veri gönderiyor.

main fonksiyonum
int main(void)
{
  HAL_Init();
  SystemClock_Config();
  MX_GPIO_Init();
  MX_UART4_Init();
  
  HAL_UART_Receive_IT(&huart4, Rx_Data, 1); // ilk kez veri geldiğinde kesmeye girebilmek için

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */
		if(TxCplt == 1)
		{
			HAL_UART_Transmit_IT(&huart4, Rx_Buffer, 100); // GPS'ten alınan veri usb-seri çeviriciye gönderiliyor
			TxCplt = 0;
		}
  /* USER CODE BEGIN 3 */
  }


Kesme fonksiyonum
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	uint8_t i;
	if (huart->Instance == UART4)	//current UART
	{
		if (Rx_Data[0] == 36) // "$" karakteri geldiyse buffer temizle
		{
			for (i=0; i<100; i++) Rx_Buffer[i] = 0;
			Rx_Index = 0;
		}
		
		if (Rx_Data[0] != 42) // "*" karakterine kadar
		{
			Rx_Buffer[Rx_Index++] = Rx_Data[0];
		}
		else
		{
			TxCplt = 1;
		}

		HAL_UART_Receive_IT(&huart4, Rx_Data, 1);
	}

}


mesaj birleştirme:: 26 Şubat 2016, 21:34:51

Aptal kafam.
Çünkü ikinci $ işareti hiç bekleme olmadan geliyor ve bu da buffer'ın temizlenmesine sebep oluyor. Peki buna nasıl bir çözüm oluşturabilirim?

İkinci kez aptal kafam.
Şimdi de bana aslında sadece GPRMC etiketli verinin yeterli olduğunu farkettim. Yani çakışma olmayacak. Ancak yine de çözüm önerilerini merak ediyorum...

sadogan

Ben bu şekilde okuyorum.
paket header '$' ile başlayıp newline ve enter ile bitiyor
'$'bekleyip indexsi sıfırlayıp '$'geldigini bir flaga yazıp /n (0X0A) karekteri
geldiğinde bir frame buffer a yazılmış oluyor.
0X0A (10) gelen başlık tanımlanıp onla ilgili bir flagı set edip mainde kullanabilirsiniz.
   _gps_veri=getc();
   if(_gps_veri=='$')
   {
      Dolar_ok=1;
      gosterge=0;
   }
   if(Dolar_ok)
   {

      GXXXX[gosterge]=_gps_veri;
      gosterge++;  
      if(_gps_veri==10)
      {
         if(GXXXX[3]=='R' && GXXXX[4]=='M' && GXXXX[5]=='C')
         {
            for(GX=0;GX<gosterge;GX++)
            {
              tx_buf[GX]=GXXXX[GX];
            }
            rmc_flag=1; 
         }         
         gosterge=0;
         Dolar_ok=0;
      }
}

cyhn41

Merhaba ben Stm32f4103 kitinde adc den deger okuyum uart ile bilgsayara göndermek istiyorum ama söyle bir skınıtı var adc 12 bit çözünülüğe sahip uart 8 bit  bit veri gönderiyor. verinin tam olarak gönderilmesi için ne yapmam gerekli

olemiss

Farklı bir soru olduğu için önce yeni bir başlık açmanız gerekiyor.
Yazılım Mühendisi, Çevirmen.

sadogan

12 bitin, yüksek 4 biti bir byte, düşük 8 biti ni 1 byte olarak ayırıp 2 byte şeklinde
göndermeniz gerekiyor.

cyhn41

peki ayırma işleminden sonra gönderim sekli nasıl olacak aynı hattan sıra sıra mı? farklı iki hattan mı?