uart checksum

Başlatan merve damar, 13 Haziran 2022, 14:53:19

merve damar

selamlar,
uart ile gelen verileri diziye atıp en son gönderilen bytı checksum ile kontrol edip nasıl yazabilirim?
Gelen byte 7 veya 8 olabilir. yardımcı olabilir misinizönerisi olan var mı

quarko

Bir timer kurup hatta boşluk arayabilirsiniz. Beklediğiniz ölçüde boşluk oluşursa ve gelen byte ları alıp checksum kontrolü yapabilirsiniz.
"Vicdanın ziyası ulum-u diniyedir. Aklın nuru fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder."

merve damar

aslında gelen çerçevenin 7byte mi 8 bytmı olduğunu anlayabilsem yeter

quarko

Gelen byte ların hem başında hem sonunda, hattaki boşluğu yakalarsanız, kaç byte geldiği bilgisi elinizde olmuş olur. Yani beklediğiniz ölçüde hatta boşluk oluştuktan sonra rx i aktif et. Veri gelirse alsın. Veri kesildiğinde de hatta beklediğin ölçüde tekrar boşluk yakalarsan, verinin kesildiğini kabul et, gelen veriye istediğin işlemi uygula. Byte sayısını da bir counter la tutabilirsin.
"Vicdanın ziyası ulum-u diniyedir. Aklın nuru fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder."

yucatar

Fırat devecinin modbus kütüphanesini inceleyebilirsiniz fikir verebilir.(https://github.com/FxDev/PetitModbus)

quarko nun dediği gibi uart kesmesi oluştuğunda timer kurarsınız mesala 5ms bir timer eğer 5ms içinde uart kesmesi veri almazsa paketin bittiğini anlayabilirsiniz.

merve damar

yazdım bişeyler saçma ve gereksiz uzun oldu ama umarım problem yaratmaz. timerle falan yapmadım

yucatar

yazılımı paylaşırsanız yardımcı olabilirim.

merve damar

#7


bit riflag;
unsigned int buffer[8],n;
unsigned char count=0;



signed int p = 0;


void SerialPort0_ISR(void) interrupt 4
{
if (RI==1)
{     

buffer[count] = SBUF;
if(buffer[0]==0x55){
count++;
if(count>=7&&((buffer[0]+buffer[1]+buffer[2]+buffer[3]+buffer[4]+buffer[5])%256==buffer[6]))
{count=0;n=0;riflag =1;clr_ES;}
if(count>=8&&((buffer[0]+buffer[1]+buffer[2]+buffer[3]+buffer[4]+buffer[5]+buffer[6])%256==buffer[7]))
{count=0;n=0;riflag =1;clr_ES;}
}
else riflag=1;
clr_RI;
}}



13 Haziran 2022, 16:05:52
biraz komik gelebilir ama istediğimi verdi :D :D

quarko

Bu şekilde yaparsan sadece düzgün bir veri geldiğinde alman mümkün olur. Çoğu zamanda veriler kaçar. Senkronizasyon kaybolur. Mesela hattan veri akıyorken, işlemcinin enerjilendiğini düşün. Buffer[0] değeri o an ne gelmişse o olacak. Baştan kaçırdın mı düzgün paket alman da mümkün olmayacak.
"Vicdanın ziyası ulum-u diniyedir. Aklın nuru fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder."

merve damar

Selamlar,
sıralı sayıları dizi şeklinde uart ile nasıl gönderebilirim? göndericeğim sayıları dizi şeklinde değişkenlere atıyorum ama çok fazla elemanı var mesela bi dizi 49 elemanlı, ama hafıza yetmiyor bu şekilde :(

quarko

Göndereceğin sayıları dizi şeklinde oluşturabiliyorsan, göndermek için ekstra bir dizi kullanman gerekmez. Bu durumda hafıza problemi nasıl oluşabiliyor.
"Vicdanın ziyası ulum-u diniyedir. Aklın nuru fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder."

yucatar

Alıntı yapılan: merve damar - 13 Haziran 2022, 16:05:21bit riflag;
unsigned int buffer[8],n;
unsigned char count=0;



signed int p = 0;


void SerialPort0_ISR(void) interrupt 4
{
if (RI==1)
{     

buffer[count] = SBUF;
if(buffer[0]==0x55){
count++;
if(count>=7&&((buffer[0]+buffer[1]+buffer[2]+buffer[3]+buffer[4]+buffer[5])%256==buffer[6]))
{count=0;n=0;riflag =1;clr_ES;}
if(count>=8&&((buffer[0]+buffer[1]+buffer[2]+buffer[3]+buffer[4]+buffer[5]+buffer[6])%256==buffer[7]))
{count=0;n=0;riflag =1;clr_ES;}
}
else riflag=1;
clr_RI;
}}



13 Haziran 2022, 16:05:52
biraz komik gelebilir ama istediğimi verdi :D :D


Buna benzer basit bir yazılım yaparsan daha doğru olur. Senkronizasyon bozulduğunda problem olmaz.

void 1msKesme()
{
 if(PaketSayaciBaslat)
 {
   PaketSayaci++;
   if(PaketSayaci>=5)
   {
     PaketGeldi=1;
     PaketSayaciBaslat=0;
   }
 }
}

void UartKesmesi()
{

 Buffer[GelenVeriSayisi]=gelen veri;
 GelenVeriSayisi++;
 PaketSayaciBaslat=1;
 PaketSayaci=0;
}

Void main()
{


  while(1)
  {
    if(PaketGeldi==1)
    {
      PaketGeldi=0;
      GelenVeriSayisi=0;
      //if içerisinde paketten gelen veriyi incele.
      //En son buffer sıfırla
    }
  }
}

foseydon

49 eleman çok değil. bence bir yerlerde hata yapıyorsun.

yukardaki yazılımın sıkıntılı. belirli varsayımlara dayanarak yazılmış. birini quarko söylemiş.

misal, interrupt rutini icerisinde veri islenmez. daha dogrusu is yapilmaz. sen orda islem yaptigin zaman donanimi blokluyorsun. o sirada uart'in fiziksel buffer'ini tasiracak kadar veri gelse veri kaybedersin. interrupt'ta fiziksel buffer'daki veriyi hemen alip cikman lazim. veriyi topladiktan sonra main fonksiyonunda isleyebilirsin.

protokolü bilmende lazım. rastgele gelen veriyi nasıl işleyebilirsin ki? bir pattern olması lazım ki o pattern'e göre veriyi işleyebil.

veriyi nasıl göndereceğinde işlemcinin yapısı ile alakalı. tek tek tx fiziksel buffer'ına da yazabilirsin, bunun için bir döngü kulanırsın. veya bazı işlemcilerde arrayı olarak verirsin direk yollar. arm kullanıyorsun dma'sı olabilir. o da ayrı bir yöntem. sen DMA'ya array'ini verirsin, o yazar tx buffer'ina. yöntem çok.

sana bir tavsiye vereyim. çok komplike olmayan, belirli bir iş yapan, yazilim parçalarını kağıda yaz. sana ciddi katkı sağlaycağını göreceksin.