Stm32 ile usart üzerinden uzunluğu belirsiz veri alma

  • Konbuyu başlatan mühendiss_eem
  • Başlangıç tarihi
Katılım
19 Ocak 2018
Mesajlar
16
Puanları
1
Oncelikle merhaba arkadaşlar. Ben stm32f407 kartı ile usart üzerinden hal kütüphanesi ile veri alıyorum fakat degişken adetli verileri nasıl alırız örneğin bir döngüde 5 byte veri gelmiştir digerinde 8 byte gelcektir ben bu farklı sayıda veriyi nasıl alabilirim.
 

ISMAILY

Üye
Katılım
9 Nis 2010
Mesajlar
439
Puanları
31
usart idle interrupt şeklinde arama yapın.
İlk byte gelince idle kesmesini aktif edin.

Daha garantili yöntem verinin başında sonunda ayraç karakterlerin olması.
 
Konu Sah
mühendiss_eem
Katılım
19 Ocak 2018
Mesajlar
16
Puanları
1
karşıdan gelecek verinin ne olacagı degişken olacak yani başında ve sonundaki veriler degişecek modbus rtuda kullanacagım
 

FakirMaker

Katılımcı Üye
Katılım
5 May 2009
Mesajlar
515
Puanları
56
Bitiş karakteri kullanmayı düşünür müsün? En kolayı budur. Yada gelen her byte ı ayrı ayrı işleyip birleştirmen gerek
 

muratmert4

Usta Üye
Katılım
26 Eyl 2007
Mesajlar
1,071
Puanları
156
Yaş
47
Konum
ANTALYA
Uart interrupt içinde gelen veriyi saydıracağın bir değişken yardımı ile array dizisine aktarıp ve saydırdığın değişken ile data boyunu öğrenip işlemen.

Kod:
#define data_boyu 32

uint8_t rx_data[data_boyu];
uint8_t rx_say;

void __interrupt()UART_ISR(void)
{
       if(PIR1bits.RCIF)
    {
        rx_data[rx_say] = RCREG;
        rx_say++;
    }

}

bunun yapısını stm32 ye göre ayarlayıp / değiştirip uygulayın
 

alarmko

Katılımcı Üye
Katılım
14 Ocak 2009
Mesajlar
684
Puanları
56
Yaş
56
ilk Byte alındıgında data geldi flagını set et ve aynı yerde zaman sayacını her Byte alınışında sıfırla.
Sorgulama bölgende flag set ve zaman baud süresinden uzunsa data gelme işlemi bitmiştir.
Datanı oku ve flag ve zaman sayacını sıfırla.
Bu sekilde istedigin uzunlukta data okuyabilirsin.
 

ISMAILY

Üye
Katılım
9 Nis 2010
Mesajlar
439
Puanları
31
karşıdan gelecek verinin ne olacagı degişken olacak yani başında ve sonundaki veriler degişecek modbus rtuda kullanacagım

Modbus RTU'da belli bir end of frame karakteri yok. Onun yerine en az 3.5 byte lık bir boşluk olması gerekli.
Frame sonunu tespit etme sorunundan önce sabit 3-5 byte veriyi alıp bir array vs. ye atabildiğini varsayıyorum.

Veriyi usart kesmesi ile aldığında;
Kesme içinde 4 frame lik zamana karşılık gelen bir timer kurulur.
Örnek 9600 baud ile veri alıyorsan Start, stop bitleri vs. bir byte için 10 bit aktarılır.
Yani 1 byte için yaklaşık 1milisn. 4 bytelık boşluk için 4 ms. de kesme üretecek bir timer kurulur.
Her usart kesmesinde TIMx->CNT registeri sıfırlanıp, timer'ın kesme üretmesi ertelenir.
Ne zaman usartdan veri gelmezse timer kesmesinde frame sonunun geldiğini anlarsın.

Usart IDLE interrupt ve DMA ile veri almanın HAL ile yapılanadırılması için de aşağıdaki linke bakabilirsin.
https://programming.vip/docs/stm32-hal-library-learning-serial-idle-interrupt.html
 
Konu Sah
mühendiss_eem
Katılım
19 Ocak 2018
Mesajlar
16
Puanları
1
teşekkürler idle interrupt ile degisken uzunlukta veri aldım . Bir sorum daha olacak 2adet 8 bitlik veriyi nasıl 16 bit yaparım make16 komutu çalışmıyorda?
 

muratmert4

Usta Üye
Katılım
26 Eyl 2007
Mesajlar
1,071
Puanları
156
Yaş
47
Konum
ANTALYA
teşekkürler idle interrupt ile degisken uzunlukta veri aldım . Bir sorum daha olacak 2adet 8 bitlik veriyi nasıl 16 bit yaparım make16 komutu çalışmıyorda?
make16 komutu ccs de kullanılan bir komuttur
sana make8 ve make16 fonksiyonları ;)

Kod:
//================================MAKE16=======================================
uint16_t make16(uint8_t hi, uint8_t lo)
{
    uint16_t d=0;
    d = ((d |hi)<<8) | lo;
    return d;
}
//=============================================================================
//================================MAKE16=======================================
uint8_t make8(uint16_t value, uint8_t byte_vo)
{
    uint8_t d[2];
    d[1]=value >>8;
    d[0]=value & 0xFF;
    return d[byte_vo];
}
//=============================================================================
 
Son düzenleme:
Konu Sah
mühendiss_eem
Katılım
19 Ocak 2018
Mesajlar
16
Puanları
1
make16 komutu ccs de kullanılan bir komuttur
sana make8 ve make16 fonksiyonları ;)

Kod:
//================================MAKE16=======================================
uint16_t make16(uint8_t hi, uint8_t lo)
{
    uint16_t d=0;
    d = ((d |hi)<<8) | lo;
    return d;
}
//=============================================================================
//================================MAKE16=======================================
uint8_t make8(uint16_t value, uint8_t byte_vo)
{
    uint8_t d[2];
    d[1]=value >>8;
    d[0]=value & 0xFF;
    return d[byte_vo];
}
//=============================================================================
çok teşekkürler :D
 

Forum istatistikleri

Konular
117,266
Mesajlar
826,383
Kullanıcılar
426,946
Son üye
Ersen38

Yeni konular

Üst