Seri Haberleşme Zamanlama - Debian- Linux

Başlatan resonator, 23 Temmuz 2015, 00:53:27

resonator

Merhaba arkadaşlar,

Benim sorum şu olacak. A20 allwinner işlemcide linux/debian ortamında Uart çıkışından 38 khz pulse sinyali almaktayım. Amacım IR verici için modülasyonu sadece Uart modülünde tamamlayıp IR lede basmak. Aşağıda yazılı kodun çıktısı IR alıcı için lojik 1 frame e tekabül etmekte. Şöyle ki ;

          write(fd,buffer,8);  //that means 1.4 ms for pulse to be HIGH - 1.4 ms lik dilimde 38 khz lik sinyali basıyorum
          usleep(500);        // 0.5 ms to wait  - daha sonra 0.5 ms lik dilimde bekliyorum

Daha sonrasında ise IR alıcının "aç" komutlarını byte olarak aşağıdaki fonksiyonla basmaktayım.


    Byte_Write_For_IRDevice(char byte_v)
{
    int bitcount;
    char t=0;

    for(bitcount=0;bitcount<8;bitcount++)
    {
      int t=byte_v&1;
      byte_v>>=1;

      if(t==1)        //Logic '1' frame
      {
        write(fd,buffer,8);  //that means 1.4 ms for pulse to be HIGH

        usleep(500);        //0.5 ms for wait
      }
      else            //Logic '0' frame
      {
        write(fd,buffer,4);  //that means 0.7 ms for pulse to be HIGH

        usleep(500); 
      }

   }
}


Burda karşılaştığım sıkıntı 1.4 ms 38 khz sinyali rahatlıkla gözlerken 0.5 ms bekleme için herhangi bir delay olmaması.Şöyle ki eğer bekleme süresini uzatırsam istediğim beklemeyi elde ediyorum. Bu zamanlama ayarı için Posix thread, nanosleep vb.  denedim ama nafile. Aşağıda seri portu açtığım fonksiyon yer almakta. Hatam belki oradan da kaynaklanıyor olabilir. (Not:38 khz sinyali oluştururken custom baudrate kullandım. )


int OpenSerialPort()
{

/* Open and configure serial port */
if ((fd = open(SERIALPORT,O_RDWR|O_NOCTTY)) == -1)
{
    return -1;
}
struct termios options;
struct serial_struct serinfo;


// generating proper Baudrate to obtain 38 Khz freq. pulse wave on Uart
speed = rate_to_constant(rate);

    if (speed == 0) {
       /* Custom divisor */
       serinfo.reserved_char[0] = 0;
       if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
           return -1;
       serinfo.flags &= ~ASYNC_SPD_MASK;
       serinfo.flags |= ASYNC_SPD_CUST;
       serinfo.custom_divisor = (serinfo.baud_base + (rate / 2)) / rate;
       if (serinfo.custom_divisor < 1)
          serinfo.custom_divisor = 1;
       if (ioctl(fd, TIOCSSERIAL, &serinfo) < 0)
          return -1;
       if (ioctl(fd, TIOCGSERIAL, &serinfo) < 0)
          return -1;
       if (serinfo.custom_divisor * rate != serinfo.baud_base) {
              warnx("actual baudrate is %d / %d = %f",
                 serinfo.baud_base, serinfo.custom_divisor,
                 (float)serinfo.baud_base / serinfo.custom_divisor);
       }
   }

   fcntl(fd, F_SETFL, 0);
   tcgetattr(fd, &options);
   cfsetispeed(&options, speed ?: B38400);
   cfsetospeed(&options, speed ?: B38400);
   cfmakeraw(&options);
   options.c_cflag |= (CLOCAL | CREAD);
   options.c_cflag &= ~CRTSCTS;

   if (tcsetattr(fd, TCSANOW, &options) != 0)
   {
    //return -1;
   }


}

Şimdiden teşekkürler. Herkese kolay gelsin.

resonator

Sorun çözüldü. Gönderilen her byte için yaklaşık 100 mikrosaniye daha gecikme koymamla istediğim sinyali elde etmeyi başardım.