Stm32 ile usart üzerinden uzunluğu belirsiz veri alma

Katılım
19 Ocak 2018
Mesajlar
57
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.
 
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ı.
 
karşıdan gelecek verinin ne olacagı degişken olacak yani başında ve sonundaki veriler degişecek modbus rtuda kullanacagım
 
Bitiş karakteri kullanmayı düşünür müsün? En kolayı budur. Yada gelen her byte ı ayrı ayrı işleyip birleştirmen gerek
 
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
 
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.
 
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
 
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?
 
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:
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
129,835
Mesajlar
930,600
Kullanıcılar
452,662
Son üye
Yılmaz Çetiner

Yeni konular

Çevrimiçi üyeler

Geri
Üst