18f4550 Usb haberleşme

Başlatan _MeRKeZ_, 14 Aralık 2013, 22:36:29

_MeRKeZ_

Merhaba arkadaşlar,

18f4550 ile bilgisayar arasında haberleşme yapmak istiyorum. Bu konuda internette birçok araştırma yaptım. Özellikle Uğur Yalçın Hocamın örnekleri çok faydalı oldu. Neticesinde bir örnek yaptım. Bağlantının kurulmasında bir sorun olmuyor ancak devamında program çalışmayı durduruyor. Nedenini anlayamadım. Bilgi sahibi olanlar yardımcı olursa çok makbule geçer. Teşekkürler

//Arayüz

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using USBManagement;

namespace Usb_Hid
{
    public partial class Form1 : Form
    {

        UsbHidDevice my_hid = new UsbHidDevice();
        DialogResult Sonuc;
        byte Gelen_Veri;

        short VendorID = short.Parse("1111", NumberStyles.HexNumber);
        short ProductID = short.Parse("1111", NumberStyles.HexNumber);

        byte[] my_buffer = new byte[64];
        byte[] gelen_buffer = new byte[64];
        public Form1()
        {
            InitializeComponent();
            my_hid.DeviceStateChanged += new DeviceStateChangeEventHandler(OnChangeDeviceState);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            
            CheckForIllegalCrossThreadCalls = false;
        }

        //OKU METHODU
        void Oku()
        {
            
            while (true)
            {
                my_buffer[3] = (byte)'o';

                if (my_hid.IsOpen)
                {

                    if (my_hid.IsWindowsXpOrLater)
                        my_hid.WritePipe(my_buffer, TransactionType.Interrupt);
                    else
                        my_hid.WritePipe(my_buffer, TransactionType.Control);

                    if (my_hid.IsWindowsXpOrLater)
                        my_hid.ReadPipe(ref gelen_buffer, 64, TransactionType.Interrupt);
                    else
                        my_hid.ReadPipe(ref gelen_buffer, 64, TransactionType.Control);

                    Gelen_Veri = gelen_buffer[2];

                    if (Gelen_Veri == 1)
                    {
                        bilgi.Visible = true;
                        hareket.Visible = true;
                    }

                }
            }
        }

        public delegate void OkuHandler();
        public void IslemTamam(IAsyncResult ar)
        {

        }
        
        private void OnChangeDeviceState(object sender, DeviceStateChangeEventArgs e)
        {
            if (e.CurrentState == DeviceState.Opened)
            {
                toolStripStatusLabel1.Text = "Cihazın durumu değişti. Şu anki durum: Açık";
                //Debug.WriteLine("Device State Changed!! Curren State : Opened");
            }
            else if (e.CurrentState == DeviceState.Closed)
            {
                toolStripStatusLabel1.Text = "Cihazın durumu değişti. Şu anki durum: Kapalı";
                //Debug.WriteLine("Device State Changed!! Curren State : Closed");
            }
            else if (e.CurrentState == DeviceState.Waiting)
            {
                toolStripStatusLabel1.Text = "Cihazın durumu değişti. Şu anki durum: Bekliyor";
                //Debug.WriteLine("Device State Changed!! Curren State : Waiting");
            }
            else if (e.CurrentState == DeviceState.Ready)
            {
                toolStripStatusLabel1.Text = "Cihazın durumu değişti. Şu anki durum: Hazır";
                //Debug.WriteLine("Device State Changed!! Curren State : Ready");
            }
            else
            {
                toolStripStatusLabel1.Text = "Cihazın durumu değişti. Şu anki durum: Cihaz bulunamadı";
                //Debug.WriteLine("Device State Changed!! Curren State : None");
            }
        }


        private void OnDeviceAttached(object sender, EventArgs e)
        {
            bool Success;

            toolStripStatusLabel1.Text= "Attached Device";
            Success = my_hid.OpenPipe(VendorID, ProductID);
            if (Success)
            {

                toolStripStatusLabel1.Text=  "Bağlantı kuruldu";

            }
        }

        private void OnDeviceDetached(object sender, EventArgs e)
        {
            toolStripStatusLabel1.Text = "Detached Device";

            if (my_hid.IsOpen) 
                my_hid.ClosePipe();

            toolStripStatusLabel1.Text = "Cihaz ile bağlantı kesildi";
            this.Text = "Cihaz bekleniyor..";
        }

        
        public void VeriGonder(char veri)
        {
            my_buffer[3] = (byte)veri;

            if (my_hid.IsOpen)
            {
                if (my_hid.IsWindowsXpOrLater)
                    my_hid.WritePipe(my_buffer, TransactionType.Interrupt);
                //my_hid.WritePipe(my_buffer, TransactionType.Control);
                //else
                //my_hid.WritePipe(my_buffer, TransactionType.Control);
            }
            else
            {
                toolStripStatusLabel1.Text = "Cihaz ile bağlantı yok!";
            }
        }

        

        private void LedPIC()
        {
            throw new NotImplementedException();
        }

        

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            try
            {
                if (my_hid.IsOpen)
                    if (my_hid.ClosePipe())
                        toolStripStatusLabel1.Text = "Veri iletim hattı kapatıldı";
                    else
                        toolStripStatusLabel1.Text = "Bağlantı kapatılamıyor..";

                if (my_hid.IsRegistered) 
                    my_hid.UnRegisterDevice();
            }
            catch (Exception err)
            {
                MessageBox.Show(err.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }
       
     

        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Enter)
            {
                if (!my_hid.IsOpen)
                {
                    Sonuc = MessageBox.Show("USB bağlantısı oluşturmak ister misiniz?", "Bağlantı", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                    if (Sonuc == DialogResult.Yes)
                    {
                        if (my_hid.OpenPipe(VendorID, ProductID))
                        {
                            toolStripStatusLabel1.Text = "Bağlantı Kuruldu";

                            //my_hid.DeviceArrived += new HidDeviceArrivedEventHandler(OnDeviceAttached);
                            //my_hid.DeviceRemoved += new HidDeviceRemovedEventHandler(OnDeviceDetached);

                            OkuHandler my_oku = new OkuHandler(Oku);
                            my_oku.BeginInvoke(new AsyncCallback(IslemTamam), null);

                        }
                        else
                        {
                            toolStripStatusLabel1.Text = "Cihaz bulunamadı...!";
                        }

                    }
                }
            }

            else if (keyData == Keys.Escape)
            {
                
                if (my_hid.IsOpen)
                {
                    Sonuc = MessageBox.Show("USB bağlantısını kapatmak istediğinize emin misiniz?", "Bağlantı", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
                    if (Sonuc == DialogResult.Yes)
                    {
                        my_hid.ClosePipe();
                        toolStripStatusLabel1.Text = "Bağlantı Kesildi";
                        bilgi.Visible = false;
                        hareket.Visible = false;
                        konum.Text = "";
                    }
                }
            }

            else if (keyData == Keys.Q)
            {
                VeriGonder('Q');
                konum.Text = "Kuzeybatı";
            }

            else if (keyData == Keys.W)
            {
                VeriGonder('W');
                konum.Text = "Kuzey";
            }
            else if (keyData == Keys.E)
            {
                VeriGonder('E');
                konum.Text = "Kuzeydoğu";
            }
            else if (keyData == Keys.D)
            {
                VeriGonder('D');
                konum.Text = "Doğu";
            }
            else if (keyData == Keys.S)
            {
                VeriGonder('S');
                konum.Text = "Güney";
            }
            else if (keyData == Keys.A)
            {
                VeriGonder('A');
                konum.Text = "Batı";
            }
            else if (keyData == Keys.Space)
            {
                VeriGonder('P');
            }


            return base.ProcessCmdKey(ref msg, keyData);
        }

       
     }
}





#include <18F4550.h>
#device ADC=10
#fuses HSPLL,NOWDT,NOPROTECT,NOLVP,NODEBUG,USBDIV,PLL5,CPUDIV1,VREGEN,NOBROWNOUT 
#use delay(clock=48000000)

#define USB_HID_DEVICE     TRUE             
#define USB_EP1_TX_ENABLE  USB_ENABLE_INTERRUPT //Uçnokta1'de Kesme transferi aktif
#define USB_EP1_RX_ENABLE  USB_ENABLE_INTERRUPT    
#define USB_EP1_TX_SIZE    64                 //Uçnokta1 için maksimum alınacak ve gonderilecek
#define USB_EP1_RX_SIZE    64 

#include "flex_lcd.c"
#include <pic18_usb.h>     
#include <USB_Konfigurasyon.h>                   //USB konfigurasyon bilgileri bu dosyadadir.
#include <usb.c>    

#use fast_io(a)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)

#define UcNokta1       1 

#define Kontrol_Noktasi PIN_A5

#define surum_no1      0x00            //surum_no2.surum_no1 ornek: 1.0
#define surum_no2      0x01 

#define BILGISAYAR   PIN_D0
#define ISLEMCI      PIN_D1

#define usb_durum          paket[0] 
#define yon_bilgisi        paket[1]
#define port_durum         paket[2]
#define kontrol_bilgisi    paket[3]

unsigned int8 paket[64];
byte Kontrol,Sol,Sag,Ileri,Geri;

..


void main()
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_timer_1(T1_DISABLED);     // T1 zamanlayıcısı devre dışı
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_timer_3(T3_DISABLED | T3_DIV_BY_1);
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   

   set_tris_a(0xFF);
   set_tris_b(0x00);
   set_tris_c(0x00);
   set_tris_d(0x00);
   
   output_a(0x00);
   output_b(0x00);
   output_c(0x00);
   output_d(0x00);

   lcd_init();
   
   
   
      
   while(1)
   {  
         
            if(input(Kontrol_Noktasi))
            {
               
               printf(lcd_putc,"\f");
               printf(lcd_putc,"USB Baglantisi");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"Bekleniyor");
               
               output_high(BILGISAYAR);
               output_low(ISLEMCI);
               
               usb_init();                      
               usb_task();                    
               usb_wait_for_enumeration();         //Cihaz, hazır olana kadar bekle
               
               Kontrol=1;
               
               if(usb_enumerated())
               {
                  printf(lcd_putc,"\f");
                  printf(lcd_putc,"Baglanti Kuruldu");
                  lcd_gotoxy(5,2);
                  printf(lcd_putc,"MeRKeZ");
                  delay_ms(2000);
               }
               
               while(usb_enumerated())
               {
                                   
                  paket[1]=Kontrol;
                  usb_put_packet(UcNokta1, paket,64, USB_DTS_TOGGLE); // Datayı Gönder..
                 
                  if (usb_kbhit(1))             //Eğer pc'den yeni bir paket geldiyse
                  {     
                     usb_get_packet(UcNokta1, paket, 64); //paketi oku 
                     
                     Switch(yon_bilgisi)
                     {
                        case 'Q':
                           Ileri=1;
                           Sol=1;
                           Geri=0;
                           Sag=0;
                        break;
                        
                        case 'W':
                           Ileri=1;
                           Sol=0;
                           Geri=0;
                           Sag=0;
                        break;
                        
                        case 'E':
                           Ileri=1;
                           Sol=0;
                           Geri=0;
                           Sag=1;
                        break;
                        
                        case 'D':
                           Ileri=0;
                           Sol=0;
                           Geri=0;
                           Sag=1;
                        break;
                        
                        case 'S':
                           Ileri=0;
                           Sol=0;
                           Geri=1;
                           Sag=0;
                        break;
                        
                        case 'A':
                           Ileri=0;
                           Sol=1;
                           Geri=0;
                           Sag=0;
                        break;
                        
                        case 'P':
                           Ileri=0;
                           Sol=0;
                           Geri=0;
                           Sag=0;
                        break;
                     }
                  }
               }
            }
               
           
   }
}

t2

Aygıtı sökmeden, programı kapatıp açınca, yeniden bağlantı sağlanıyor mu?

_MeRKeZ_

Program kilitleniyor hocam. Görevi sonlandırmam gerekiyor

t2

#3
programı sonlandırdın, yeniden başlattın. ozaman bağlantı sağlayabiliyor mu?

yani kısaca programınız aygıtla hiç bağlantı sağlayabiliyor mu? bağlantı koptu kilitlendi. programı sonlandırdınız yeniden başlattınız bu sefer bağlanabiliyor mu? aygıtı söküp takmak gerekiyor ise aygıtta sorun var. gerekmiyor ise programda sorun var.

Pir-O

Aşağıda kırmızı olarak gösterdiğim satır yanlış. Sen bilgisayara doğrudan veri yolluyorsun ama bilgisayar o veriyi almak için hazır olup olmadığını bilmiyorsun. Yani gönderiyorsun ama bilgisayar alacak durumda mı değil mi bilmeden yolluyorsun. Bunun yerine bilgisayardan bir veri gelince sen de karşılığında veri yolla. Yani yöneten taraf bilgisayar olsun. Örneğin arayüzde programında bir buton olsun o butona basılınca işlemciye veri yolla (ne olduğu önemli değil) sonra bilgisayar veri bekleme konumuna geçsin ve sen de göndermek istediğin veriyi yolla. Eğer taraflardan biri veri yollayıp diğer taraf belirli bir sürede alamazsa programın hata verir.



while(usb_enumerated())
               {
                                   
                  paket[1]=Kontrol;
                  usb_put_packet(UcNokta1, paket,64, USB_DTS_TOGGLE); // Datayı Gönder..

                 
                  if (usb_kbhit(1))             //Eğer pc'den yeni bir paket geldiyse
                  {     
                     usb_get_packet(UcNokta1, paket, 64); //paketi oku
                     
                     Switch(yon_bilgisi)
                     {
                        case 'Q':
                           Ileri=1;
                           Sol=1;
                           Geri=0;
                           Sag=0;
                        break;

_MeRKeZ_

@t2

Hocam, sorun bağlantının kurulmasının ziyade veri iletiminde

@Pir-O

Hocam, dediğin gibi okuma gerçekleşmediği için zaman aşımına uğruyormuş. Yapıyı şu şekilde değiştirdim. Doğru mudur?

if(input(Kontrol_Noktasi))
            {
               
               printf(lcd_putc,"\f");
               printf(lcd_putc,"USB Baglantisi");
               lcd_gotoxy(1,2);
               printf(lcd_putc,"Bekleniyor");
               
               output_high(BILGISAYAR);
               output_low(ISLEMCI);
               
               usb_init();                      
               usb_task();                    
               usb_wait_for_enumeration();         //Cihaz, hazır olana kadar bekle
               
               Kontrol=1;
               
               if(usb_enumerated())
               {
                  printf(lcd_putc,"\f");
                  printf(lcd_putc,"Baglanti Kuruldu");
                  lcd_gotoxy(5,2);
                  printf(lcd_putc,"MeRKeZ");
                  
                  if (usb_kbhit(1))             //Eğer pc'den yeni bir paket geldiyse   
                  {
                     usb_get_packet(UcNokta1, paket, 64); //paketi oku 
                  
                     if(usb_durum=='H')
                     {
                        kontrol_bilgisi=Kontrol;
                        usb_put_packet(UcNokta1, paket,64, USB_DTS_TOGGLE); // Datayı Gönder..
                     }
                  }
               }
               
               while(usb_enumerated())
               {

                        Switch(yon_bilgisi)
                        {
                           case 'Q':
                              Ileri=1;
                              Sol=1;
                              Geri=0;
                              Sag=0;
                           break;
                           
...



Merak ettiğim diğer bir husus, veri iletimi esnasında bağlantı kurulur kurulmaz -hazır olduğunu ifade etmek için- H harfini yolluyorum bilgisayardan. Bu harf işlemciye geldiği zaman dizinin hangi üyesine (paket[0], paket[1], paket[2], paket[3])gelir? Bu işlemi bir kereliğine yapıyorum. Bundan sonra yollamam gereken verileri gönderdiğimde hangi elemana gelir? Aynı şekilde işlemciden bilgisayara yolladığım eleman 64 elemanlı dizinin hangi elemana gider? Bu nasıl belirleniyor?

Bilgisayardaki arayüz programında gönderilen eleman dizinin hangi elemanına atanmışsa işlemcide de aynı elemana atanır diye düşündüm ama doğru mu acaba?

Çok sağol hocam


Pir-O

Kodlar bu şekilde çalışır büyük ihtimalle sorun yok gibi görünüyor. İkinci olarak bilgisayardan yolladığın verileri paket[0] a yazmışsanız alıcı kısımda da paket[0] dan aynı veriyi almanız gerekir. Yalnız benim yaptığım uygulamada işlemciden gönderdiğim veriler bir kayarak bilgisayara iletiliyordu yani paket[0] a yazdığım veriyi bilgisayar tarafında paket[1] den alıyordum nedenini aradım bir türlü bulamadım o şekilde kullandım. onun dışında bilgisayardan paket[1] yazdığımı işlemci kısmında paket[1] den alabiliyorum sorun yok.

_MeRKeZ_

Hocam dediklerinizi gözönünde bulundurarak tekrar denedim ancak yine aynı yerde zaman aşımına uğrama hatası alıyorum. Başka bir sıkıntı olabilir mi?