Picproje Elektronik Sitesi

PROGRAMLAMA DİLLERİ => Visual C# => Konuyu başlatan: vitruvius - 19 Nisan 2011, 19:11:41

Başlık: C# ile Seri Port İletişim
Gönderen: vitruvius - 19 Nisan 2011, 19:11:41
Merhaba, proje olarak bir makete trafik ışıkları koyacağım ve C#'ta yazacağım program ile ışıkların yanma sürelerini girip bunu maketimde uygulamak istiyorum. Ancak seri iletişim ile ilgili en ufak bir bilgim yok. Forumda biraz bakındım ancak pek anladığım söylenemez. Bu arada CCS kullanıyorum demeyelim, öğreniyorum.

Öncelikle sorum bilgisayar ile devre arasındaki bağlantıyı nasıl yapacağım? Rs 232, usb, bluetooth gibi seçenekler duydum. Ancak Rs232 kullanmak için bir de dönüştürücü kullanmak gerekiyor galiba. En kolay iltişimi nasıl sağlarım?

Diğer ve temel sorunum ise bu işin temellerini öğrenerek yapmak istediğim ve başka projeleri gerçekleştirmek istiyorum ama pic'e veri seri port iletişime için rehber kaynak gösterebilir misiniz? İstanbul'da birkaç kitapevine gittim ama C# ile seri port iletişim anlatan kitap bulamadım. I/O aynı ,iletişim, manasına mı geliyor?

Teşekkürler.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 19 Nisan 2011, 19:31:45
Direkt olarak seri iletişimi anlatan kitap bulman zor. İstediğin tool nasıl kullanıldığını örenmek istiyosan msdn.microsoft.com dan o tool hakkında herşeyi bulabilrsin. Devre ile iletişim kurmak istiyosan da en kolay yöntem bence seri port. Kolay gelsin.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: kudretuzuner - 19 Nisan 2011, 20:05:56
Merhaba
Linkte açıklamalar var bir bakıverin lütfen aynı konular işleniyor.Kolay gelsin.
https://www.picproje.org/index.php/topic,33033.msg231466/topicseen.html#msg231466
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 29 Nisan 2011, 15:19:38
Merhaba çeşitli sorunlardan sonra denemelere başlayabildim. Şimdi basit bir adımla başlayıp sonradan geliştirmek istiyorum. Şuanda Form'a bir adet buton, textbox ve seriport koydum. Yapmak istediğim şey ise textbox'ta yazdığım harfin 16F877'ye bağladığım lcd'de gözükmesi. Devrede sadece 16F877,lcd, max232 ve conn-d9f var. Tabiki ilk denememde başarılı olamadım =) Lcd'de boş ekran gözüküyor. Sorun nerede acaba?

Bir de denemesini nasıl yapmam gerekiyor? Önce Isis'ten simülasyonu başlatıp sonra da yazdığım kod sonucu oluşan .exe yi çalıştırsam direkt algılıyor mu?

Teşekkürler.

C#'ta yazdığım kod:

private void button1_Click(object sender, EventArgs e)
        {
            serialPort1.Open();
           
            string x = textBox1.Text;
            serialPort1.WriteLine(x + (char)13);
            serialPort1.Close();
        }


CCS C'de yazdığım kod:

#include <16f877.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use rs232 (baud=9600,rcv=PIN_C7, xmit=PIN_C6, parity=N, stop=1) //rs 232 için

void veri()
{
char x[80];
gets(x);
printf(lcd_putc,"\f%s",x);  //LCD'yi temizle ve x string ifadesini LCD'de göster
return;
}

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
lcd_init();

while(1)
  {
    veri();
  }
}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 29 Nisan 2011, 21:03:02
Ayrıca kafama takıldı pic'e iletişimin hangi porttan yapıldığını bildirmek gerekmez mi?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 29 Nisan 2011, 22:23:00
Dizi kullanmana gerek yok yani veri fonksiyonun içine şu komutları yazabilirsin
void veri(void)
{
char k;
k=getc();
if(k=='\n')//c# her cümleyi gönderdiğinde sonuna \n koyuyo
return;
printf(lcd_putc,"\f%s",x);
}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 29 Nisan 2011, 22:48:37
Dediğinizden yola çıkarak şu şekilde bir kod yazdım:

#include <16f877.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use rs232 (baud=9600,rcv=PIN_C7, xmit=PIN_C6, parity=N, stop=1) //rs 232 için

void veri(void)
{
char x;
x=getc();
if(x=='\n')//c# her cümleyi gönderdiğinde sonuna \n koyuyo
return;
printf(lcd_putc,"\f%s",x);
}

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
lcd_init();

while(1)
  {
    veri();
  }
}


Sanırım siz k'yı genel bir ifade olarak yazdınız, onun için x ile değiştirdim. Yine lcd boş gözüküyor. Ancak denemeyi doğru yaptığımdan da emin değilim. Isis'te simülasyonu çalıştırıyorum o çalışırken C#'ta yazdığım kod sonucu oluşan .exe dosyasını açıp textbox'a bir harf girip enter'a basıyorum.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 29 Nisan 2011, 22:51:14
button1 in click olayına yazdığınız için texbox ın içine yazıp button1 e tıklamalısınız
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 29 Nisan 2011, 22:57:00
Pardon enter demişim butona tıklıyorum ama bir sonuç alamadım henüz.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 29 Nisan 2011, 23:01:44
Max232 nin bağlantılarını doğru yaptığınıza emin misiniz?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 29 Nisan 2011, 23:07:20
Bu şekilde şu an devrem:

(http://i53.tinypic.com/jfucg4.jpg)
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 29 Nisan 2011, 23:44:22
Ya bu devrede bi sorun yok.Şu an pek bişey söyleyemeyecm.lcd normalde bişey yazdığınızda düzgün çalışıyo mu?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 29 Nisan 2011, 23:51:55
Veri fonksiyonun içine printf(lcd_putc,"\f   deneme"); yazınca yazı yazmadı. Aynısını main fonksiyonunun içine yazınca yazı çıktı. Veri fonksiyonunda bir yerde mi acaba hatam?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: kudretuzuner - 29 Nisan 2011, 23:53:54
Merhaba
Bu tür çalışmalarda PC tarafında TX ten çıkıp tekrar PC'nin RX 'ine girer geri döner ve de yolladığınız datayı görürseniz PC tarafındaki yazılım tamamdır demektir.ikinci aşama PC'nin TX'inden çıktıktan sonra max232'nin R1 in ayağına (pin13)girin.R1 out(pın12)den çıkan ucu T1 in'e girin(pın11)  sonra T2out(pin14) ayağı PC'nin RX'ine girin (tabii max232'nin beslemesini unutmadan ve kondansatörlerin polarizasyonlarını doğru olarak bağlamak şartı ile)Eğer yolladığınız datayı PC'de görürseniz max232 ayağı da tamamdır.Bundan sonra R1out (pın12)'yi PIC'in RX'ine PIC'in TX'ini T1İN(pın11)'e T2out(pın14) rs232'nin RX'ine bağlayın.Tabii daha gelişmiş çalışma birkaç kanallı yüksek frekanslı osiloskop ne girdi ne çıktı görsel olarak da görebilirsiniz.Benim amatör görüşüm böyle en azından ben bu yöntemi uyguluyorum.Kolay gelsin.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: dumansiz - 30 Nisan 2011, 00:03:30
x=getc();
Bu fonksiyon veri gelene kadar kodu aynı satırda bekletiyor mu?
Bekletmiyorsa; while döngüsü içerisinde LCD ye sürekli bir şey yazdığınızdan veri LCD de görünmüyor olabilir mi?
Bir de C# da kullandığınız serialport nesnesinin özelliklerine baktınız mı? Hızı(9600) ve haberleşme kuralları(8N1) aynı mı?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 00:06:46
Öncelikle çok teşekkür ederim, çok güzel bir yöntem gösterdiniz. Yolladığım datayı bilgisayarda görmek için serialPort1.Readline(); gibi bir komut mu yazmam gerekiyor? Bir de PC'nin TX ucu dediğiniz CONN-D9F'in 3 numaralı ucu mu oluyor?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: kudretuzuner - 30 Nisan 2011, 00:13:28
Merhaba
Max232 ve rs232(D9) sizin şemanızda gördüğüm kadar doğru bağlanmış.2,3 diyerek yanıltmayayım.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: kudretuzuner - 30 Nisan 2011, 00:27:19
Merhaba
Komple full kod verme adetim yok (gençlerin çalışıp araştırıp kendilerinin bulması için)fakat işiniz uzayacağı için yardımcı olayım.Ama ben VB Net 2008 express edition kullanmaktayım.
Public Class Form1

    Private Sub Button4_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button4.Click
        Me.Close()
    End Sub



    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
        Label1.Text = Len(TextBox1.Text)

    End Sub

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        SerialPort1.PortName = ComboBox1.Text
        SerialPort1.Open()
        Button1.Enabled = False
        Button3.Enabled = True
        Button2.Enabled = True
    End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        SerialPort1.WriteLine(TextBox1.Text)

    End Sub

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        ComboBox1.Text = "COM3"
        Button3.Enabled = False
        Button2.Enabled = False

    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        SerialPort1.Close()
        Button1.Enabled = True
        Button3.Enabled = False
        Button2.Enabled = False

    End Sub

    Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
        Dim gelen As String = SerialPort1.ReadLine

        If gelen = "kudret" Then
            PictureBox1.BackColor = Color.Red
            Exit Sub
        End If

        MsgBox(gelen)
    End Sub
End Class
text box'a "kudret" yazar da data doğru giderse picture box kırmızı oluyor.Kolay gelsin
https://rapidshare.com/files/459834929/data_yollama.rar
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 00:34:39
Ehehe birkaç gündür sorularımla bıktırdım sizi farkındayım, sabrınıza hayranım. Ancak aynı adetten komple kodlara son anda bakarım, çünkü yapmak değil öğrenmek istiyorum. Sorularım bitmeyecek yani  :) Size ne kadar teşekkür etsem azdır.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 30 Nisan 2011, 00:57:32
Dostum bir de şunu dener misin rx ucuna 100 ohm ile beraber bi led bağlayıp bilgisayarda hazırladığınız formdaki butona basıldığında ledte herhangi bir yanıp sönme oluyo mu?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 30 Nisan 2011, 01:01:16
Bir de benim daha önceden hazırladığım bi uygulama var dı hi-tech c de yazılmış kodlarına bir bak istersen belki senin için bir ip ucu olur.Anladığım kadarıyla c# kısmında bir sorun yok tabi serialport un property lerini doğru ayarlamışsanız.
#include <htc.h>
#include <delay.c>
#include <yusuf_lcd.c>
#include <yusuf_usart.c>
#include <stdio.h>
#include <stdlib.h>
void
main(void)
{
unsigned char c,c1=0,c2,c3=0,i=10,k=0,q=0;
unsigned char f[]="";
unsigned char g[]="";
int a;
TRISD=0;
PORTD=0;
ADCON1=7;
TRISA=0;
PORTA=0;
TRISB=0;
PORTB=0;
TRISC=128;
PORTC=0;
CCP1M0=1;
CCP1M1=1;
CCP1M2=1;
CCP1M3=1;
TOUTPS0=1;
TOUTPS1=1;
TOUTPS2=0;
TOUTPS3=0;
T2CKPS0=1;
T2CKPS1=1;
CCPR1L=16;
CCP1X=0;
CCP1Y=0;
CCPR2L=125;
CCP2X=0;
CCP2Y=0;
TMR2ON=1;
lcd_hazirla();
lcd_temizle();
usart_hazirla();
while (1){
c=usart_al();
if(k==1&&c!='+'&&c!='\n')
{
sprintf(f,"%c",c);
c2=atoi(f);
c3=c3+c2*i;
i=1;
}
if(c=='!')
{
k=1;
}
if(c=='+')
{
c1=c3;
i=10;
k=0;
c3=0;
}
    if(c=='#')
{
lcd_gotoxy(2,1);
continue;
}
if(c=='&')
{
lcd_gotoxy(1,1);
continue;
}
if(c=='x')
{
lcd_temizle();
    continue;
}
if(c=='W')
{
  PORTA=1;
  continue;
}
if(c=='Q')
{
PORTA=2;
continue;
}
if(c=='V')
{
PORTA=0;
continue;
}
if(c=='x')
{
PORTA=0;
continue;
}

    if(c=='\n')
{
continue;
}
if(c!='!'&&c!='+')
{
veri_gonder(c);
}
PORTD=c1;
PR2=250-c1*10;
}
}

Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 01:08:26
Alıntı yapılan: dumansiz - 30 Nisan 2011, 00:03:30
x=getc();
Bu fonksiyon veri gelene kadar kodu aynı satırda bekletiyor mu?
Bekletmiyorsa; while döngüsü içerisinde LCD ye sürekli bir şey yazdığınızdan veri LCD de görünmüyor olabilir mi?
Bir de C# da kullandığınız serialport nesnesinin özelliklerine baktınız mı? Hızı(9600) ve haberleşme kuralları(8N1) aynı mı?

Alıntı YapCcs c de mesela getc(); yazıp bilgiyi almak istiyoruz ya, bu komut buton tarama komutu vs. gibi sürekli döngü şeklince çalıştırılmıyor.Mesela sen void main içerisine getc(); yazdın diyelim. Pic bunu gördüğünde veriyi beklemeye başlıyor yani rs232den veri gelinceye kadar programı kesiyor gibi birşey alt satırları çalıştırmıyor. diyelim ki sen bir display sürüyorsun pic ile display kodlarından önce getc(); yazdın, pic bilgi beklediği için display kodlarını çalıştırmayacaktır.

Böyle bir bilgi buldum, sanırım bununla alakalı sorunum? Serialport nesnesinin özellikleri ayarlı. Teşekkürler.

Yamak bey sizin dediklerinizi de uygulayacağım ancak led'in yanıp sönmesi için ekstradan bir kod yazmam gerekmez mi? Teşekkürler.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 30 Nisan 2011, 01:22:08
Hayır gerekmez siz pc den veri gönderdiğinizde orada bir gerilim oluşuyo zaten.Yani bir kare dalga rx hattından bundan dolayı veriyi gönderdiğinizde ledte yanıp sönme olması lazım.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 01:30:17
Dediğinizi denemek için devreyi şu şekilde kurdum fakat led'de bir değişiklik olmadı.

(http://i52.tinypic.com/2w4gvg7.jpg)
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 30 Nisan 2011, 01:53:28
Veri pc den pic e geldiği için bağladığınız şekilde devreyi açık devre haline getirmiş olursunuz.rcx ucuyla toprak arasına led ile direnci seri olacak şekilde bağlayıp dener misini?Yani led in anot u pic tarafnda olacak şekilde.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 02:09:39
Bu şekilde mi olmalı yani? Yine led'te bir değişiklik olmadı.

(http://i51.tinypic.com/ng96vd.jpg)
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 30 Nisan 2011, 02:40:37
Siz bunu simülasyonde denemiyosunuz di mi gerçek devre üzerinde deniyosunuz?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 02:44:19
Yok hayır simülasyonda deniyorum =) Demiştim Isis'te açıyorum çalıştırıyorum, sonra C#'ı açıyorum diye... O şekilde yapamaz mıyız?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: yamak - 30 Nisan 2011, 10:22:41
Ben böyle uygulamaları hep gerçek devre üzerinde gerçekleştiriyorum sizin de öyle yapmanızı öneriririm.Eğer proteusta yapmak isterseniz illa da seriport konektörünün yerine compim diye bi tool var onu kullanının.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 14:42:50
Bu compim'deki rxd ucunun (2 nolu pinin) sarı yanması bir sıkıntı olduğunu gösteriyor değil mi? En azından butona bastığımda yeşil olan rxd kırmızı oluyor, yani iletişim var. Bir de compim'in özelliklerinde physical özellikler ile virtual olanların arasındaki fark ne? Ben ikisini de aynı ayarladım. C#'taki seriport COM2 kullanıyor, compim'deki virtual ve physical portları da COM1 olarak ayarladım bilmiyorum doğru mu yaptım.

Önerinizi dikkate alıp pazartesi günü gerekli ekipmanları alacağım. Merak ettiğim pic'e programı kaç defa silip yükleyebiliriz ve bu işlem için hangi cihazı ve programı önerirsiniz? Teşekkürler.

Simulasyon çalışırken bir resim aldım, ufak kırmızı,sarı, mavi ve gri renkteki kutucukları nasıl yorumlayacağımı tam bilmiyorum çünkü. Sarı yanması bir sıkıntı olduğuna işaret sanırım.

(http://i56.tinypic.com/sn2d93.jpg)
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: RcALTIN - 30 Nisan 2011, 16:04:01
isis de denerken max232 kullanmanıza gerek yok, compim'e direkt bağlantı yapın. yalnız compim rx = pic rx ve compim tx = pic tx şeklinde bağlayın orada aslında compim'in receive ve transmit ettiği bacakları gösteriyor, yani terslik oluyor; sarı yanması da bu yüzden oluyor.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 30 Nisan 2011, 16:36:17
Merhaba, dediğiniz gibi yapınca oldu. Pazartesi elemanları alıncaya kadar kodları geliştirme fırsatım olacak. Size ve diğer arkadaşlara çok teşekkür ederim.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 01 Mayıs 2011, 02:40:50
Şimdi de bir led'i sürekli yakıp söndürmeye çalıştım ama bir türlü sonsuz döngüye sokamadım. d4 pini ilk başta yanıyor tabiki döngüde değil farkındayım ama döngüye sokunca da alt satıra geçmiyor program. d7 ve d0 pini ise sadece butona bastığım zaman işliyor. Şöyle bir kod denedim:

#include <16f877.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#define use_portb_lcd TRUE
#use fast_io(d)
#include <lcd.c>
#use rs232 (baud=9600,rcv=PIN_C7, xmit=PIN_C6, parity=N, stop=1) //rs 232 için

void veri()
{
char x[80];
gets(x);
printf(lcd_putc,"\f%s",x);  //LCD'yi temizle ve x string ifadesini LCD'de göster
output_high(pin_d0); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_d0); //Kırmızı Işık Söndü
delay_ms(500);
return;
}

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);
set_tris_d(0x00);
output_d(0x00);

output_high(pin_d4); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_d4); //Kırmızı Işık Söndü
delay_ms(500);

lcd_init();

while(1)
{
output_high(pin_d7); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_d7); //Kırmızı Işık Söndü
delay_ms(500);
veri();
}
}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 01 Mayıs 2011, 11:58:10
Program muhtemelen, veri () fonksiyonundaki gets() satırında takılıp kalıyordur. Yanlış hatırlamıyorsam gets() karşıdan veri alma işini bitirene kadar programı orda bekletiyor. Ve C programınız ile proteusu doğru şekilde haberleştiremiyorsanız, gets satırında takılır kalır.
Tabi sorunu bulmanın en kolay yolu debug'tır. Simulasyon yapmaya başladıktan bir süre sonra pause yapıp programın hangi satırda kaldığı görülebilir.

C#'ta yazılan program ile proteusun haberleştiğinden emin misiniz? Bu bağlantıyı ne şekilde yaptınız?
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 01 Mayıs 2011, 13:14:51
Pause olayını bilmiyordum teşekkür ederim. Dediğiniz gibi gets ()'te kalmış, o yüzden C#'ta butona bastığım zaman ledler yanıyor. Program haberleşiyor, yani textboxa bir şey yazıp butona bastığım zaman lcd ekranda görebiliyorum. Devre bağlantım şu şekilde:

(http://i56.tinypic.com/sn2d93.jpg)

Nasıl bir çözüm önerirsiniz? Teşekkürler.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 01 Mayıs 2011, 14:28:35
Bilgisayardan bir string gönderdiğinizde bunu pic tarafında seri iletişim kesmesi ile alabilirsiniz, daha sağlıklı olur. Getc() ile karakterleri tek tek alıp sırayla bir stringe atayabilirsiniz, yada gets() ile bütün olarak da alablirsiniz. Bu kesmede de dikkat edilecek en önemli olay, kesmeye girince kesmeleri disable edip, kesme çıkışında kesmeleri aktif etmektir(sonsuz döngüde aktif edilebilir / while(1) ). Ben de seri iletişimle yeni yeni uğraşıyorum, ezbere konuşursam yanlış bilgi verebilirim.
Serdar Çiçek'in kitabı varsa oradan bakabilirsiniz. Yoksa da netten, kitaptaki uygulamalara ait proteus ve ccs dosyalarını indirip uygulamaları simulasyon üzerinde inceleyebilirsiniz. Temel ccs konuları üzerine çok güzel bir kaynaktır, tavsiye ederim.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 01 Mayıs 2011, 14:41:41
Kitaptaki örneğin fazlalıklarını attım, bilgisayardan gelen stringi almak için kullanılacak yöntem bu şekilde:

char   klavye[80];  // klavye isminde 80 üyeli bir dizi tanımlanıyor

#int_rda   // RX ucuna veri gelince meydane gelen kesme
void serihaberlesme_kesmesi ()
{
   disable_interrupts(int_rda); // int_rda kesmesini pasif yap
   
   gets(klavye); // String ifadeyi al ve "klavye" adlı dizi değişkenine aktar.
}


   // void main()
   enable_interrupts(GLOBAL);  // Aktif edilen tüm kesmelere izin ver

   while(1) // Sonsuz döngü
   {
      enable_interrupts(int_rda); // int_rda kesmesi aktif
   }

Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 01 Mayıs 2011, 22:16:31
Merhaba Serdar Çiçek'in kitabı var, bahsettiğiniz örneği inceledim. Aşağıdaki gibi bir kod yazdım. Şimdi durumumu özetlersem program çalıştığı zaman d7 pinindeki led yanıp sönüyor, textboxtan bir metin girdiğim zaman girdiğim metin bir karakterden fazla ise program donuyor. Pause yapıp baktığımda gets(x)'te beklediğini görüyorum. Eğer tek karakter girersem onu lcd'de görebiliyorum ve d7 pinim yanıp sönmeye devam ediyor. Fakat o tek harfi silip yenisini yazıp butona bastığımda ekrandaki harf değişmiyor, d7 pinindeki led yanıp sönmeye devam ediyor. gets() ile birden fazla karakteri alamayıp o tek karakteri de niye değiştiremiyorum? Teşekkürler.

#include <16f877.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#define use_portb_lcd TRUE
#use fast_io(d)
#include <lcd.c>
#use rs232 (baud=9600,rcv=PIN_C7, xmit=PIN_C6, parity=N, stop=1) //rs 232 için



#int_rda
void kesme ()
{
char x[80];
disable_interrupts(int_rda);
output_high(pin_d0); //Kırmızı Işık Yandı
delay_ms(500);
gets(x);
printf(lcd_putc,"\f%s",x);  //LCD'yi temizle ve x string ifadesini LCD'de göster
output_low(pin_d0); //Kırmızı Işık Söndü
delay_ms(500);
return;
}

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_d(0x00);
output_d(0x00);

lcd_init();

enable_interrupts(GLOBAL);

while(1)
{
enable_interrupts(int_rda);
output_high(pin_d7); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_d7); //Kırmızı Işık Söndü
delay_ms(500);
kesme ();
}
}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 02 Mayıs 2011, 01:52:35
Koddaki hatalar:
1) x dizisi kesme içinde tanımlanmış onu global tanımlayın. Bu haliyle kesme fonksiyonu çıkışında dizi silinir.

2) kesme içerisinde gecikme(delay) kullanmak kesmenin askıya alınmasına yol açıyor, yani kesmenin en önemli işlevi olan "kesme" yalan oluyor. İllaki kesme içerisinde delay kullanmak isterseniz aşağıdaki mesajımı ve konuyu incelemeniz faydalı olur.
https://www.picproje.org/index.php/topic,28463.msg196433.html#msg196433

3) lcd komutlarının içerisinde de delay komutu yer aldığından aynı soruna, printf(lcd_putc.. komutu da sebep olur.
Yani lcd komutlarını da kesme içerisinde kullanmayın.
Gecikmeleri, lcd'ye yazdırma işlerini ana döngü içerisinde halledin.
[Kitaptaki örnekte de lcd komutu kesme içerisinde kullanılmış, o da soruna yol açabilir. Kod çalışmazsa ilk şüpheleneceğiniz satır o olmalı]

Ve böyle durumlarda, çalıştığından emin olduğunuz bir kodu bir kere çalıştırıp kendi sisteminizde, devrenizde çalışıp çalışmadığını kontrol edin. Eğer düzgün çalışıyorsa, onun üzerinde oynamalar yapıp her değişiklik sonrası simulasyon yaparak nelerin değiştiğini gözlemlemek, daha kolay ilerlemenizi sağlar. Temel noktalarda hata yaparak kaybedilecek zamanı bolca denemeye ve farklı şeyler öğrenmeye ayırmış olursunuz.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 02 Mayıs 2011, 03:14:49
Dediğiniz gibi yaptım, birden fazla karakter alabiliyorum. Ancak textboxtaki yazıyı değiştirip tekrar butona bastığım zaman yeni x'i göstermiyor lcd'de. Bir de esas derdime adım adım gitmeye çalıştığım için yeni geldim. Bu led'lerin yanma sürelerini textbox ile kontrol etmek istiyorum.

delay_ms(x); yazdığım zaman sabit bir değer girilmeli hatası veriyor. Bu x'i dizi olarak tanımladığım için mi oluyor? Yada C#'ta double olarak tanımlamaya çalıştım string'i sayı olarak algılamaz diye ama yine delay_ms(x) denemem olmadı. Teşekkürler.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 02 Mayıs 2011, 11:54:04
Kodun son halini eklememişsiniz. Debug yaparak dizi içerinin nasıl değiştiğini takip ederseniz ilk sorunun yanıtını bulabilirsiniz.

Gecikme konusunda da delay kullanmak yerine timer içerini kontrol ederek bir gecikme koyulabilir. Timer kesmesine gerek yok sadece timerı aktif edip içeriğini gerekli yerde sıfırlayıp, içerik istenen süre kadar artmış mı diye kontrol ederek gecikme koyulabilir.

Ayrıca anladım kadarıyla pc den pice bir sayı göndermek istiyorsunuz. Bu durumda öncelikle x dizisinin içeriğininden, gönderilen sayıyı oluşturmanız gerekli. Yoksa ne delay fonksiyonu içerisinde ne de başka bir yerde kullanmak istediğiniz sayıyı değil bir dizi rakamı kullanmış olursunuz.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 02 Mayıs 2011, 13:00:19
Alıntı yapılan: 50Cal - 02 Mayıs 2011, 11:54:04
Ayrıca anladım kadarıyla pc den pice bir sayı göndermek istiyorsunuz. Bu durumda öncelikle x dizisinin içeriğininden, gönderilen sayıyı oluşturmanız gerekli. Yoksa ne delay fonksiyonu içerisinde ne de başka bir yerde kullanmak istediğiniz sayıyı değil bir dizi rakamı kullanmış olursunuz.

Evet yapmak istediğim şey o. Dediğinizden yola çıkarak başka bir dizi tanımladım. For döngüsü içinde x'in birinci karakterini getc ile alıp ikinci dizimin birinci karakterine atadım. Sonra 3 tane değişken tanımlayıp bunlara ikinci dizimin sırasıyla karakterlerini tek tek atadım. Yani ben böyle düşündüm, lcd'ye de herhangi bir değişkeni yazdırmak istedim doğru mu yapıyorum diye ancak hep 0 görüyorum. Kodum şu şekilde:

#include <16f877.h>
#device ADC=10
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay (clock=4000000)
#define use_portb_lcd TRUE
#use fast_io(d)
#include <lcd.c>
#use rs232 (baud=9600,rcv=PIN_C7, xmit=PIN_C6, parity=N, stop=1) //rs 232 için

char x[20];
char sayi[4];
int i;
int k;
int y1, y2, y3;


#int_rda
void kesme ()
{
disable_interrupts(int_rda);
for(i=0,k=0;i<4 && k<4;i++,k++)
{
x[i]=getc();
putc(sayi[k]);
}
y1=sayi[1];
y2=sayi[2];
y3=sayi[3];
return;
}

void main()
{
setup_psp(PSP_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);

set_tris_d(0x00);
output_d(0x00);

lcd_init();


enable_interrupts(GLOBAL);
enable_interrupts(int_rda);

while(1)
{

output_high(pin_d7); //Kırmızı Işık Yandı
delay_ms(500);
output_low(pin_d7); //Kırmızı Işık Söndü
delay_ms(500);
kesme ();
printf(lcd_putc,"\f%d",y1); //İlk basamağa bakalım
delay_ms(800);
printf(lcd_putc,"\f%s",x);  //LCD'yi temizle ve x string ifadesini LCD'de göster
}
}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: ferdem - 02 Mayıs 2011, 19:39:06
50Cal arkadaşın da dediği gibi seri veriyi sonsuz döngü içerisinde kontrol ederek değil de bu iş için ayrılmış donanımı kullanarak kesme ile almalıyız, bu işlemin en sağlıklı yolu kesme ile almaktır, son mesajınızda kesme fonksiyonu yazmışsınız ancak program tam olmamış, örnek koda bakabilirsiniz:
https://www.picproje.org/index.php/topic,32476.msg232425.html#msg232425
Program kesme fonksiyonuna veri geldiği zaman otomatik olarak gider, sonsuz döngüde çağrılmasına gerek yoktur. Kesmenin özelliği bu, sadece gerektiği zaman kapınızı çalar, sürekli kontrole gerek bırakmaz.

Yapmak istediğinize çok benzer bir çalışma var, bakmanızda fayda olabilir: Hobi Servo Sürelim (Bilgisayar Kontrollü)  (http://www.fatiherdem.net/hobi-servo-surelim/).

Seri kesmesinde enable-disable işlemleriyle bizim uğraşmamıza gerek kalmıyor, kesmeye girdiğimizde GIE 0 oluyor(kesmeler otomatik kapatılıyor), veriyi okuduğumuzda donanım RCIF i 0 a çeker ve kesmeden çıkarken yine donanım tarafından GIE 1 e çekilir. Yukarıdaki örnek koda bakılabilir.

İyi çalışmalar herkese, saygılarımla.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 03 Mayıs 2011, 03:53:58
Merhaba öncelikle verdiğiniz örnek için çok teşekkür ederim, çok güzel bir örnek dakikalarca oynadım. Lakin kafamı çok karıştırdı, moralimi de bozdu biraz çünkü mantığını anlamadım.

Şimdi C#'taki kısımda anlamadığım send(200)'ün bir anlamı var mı, yoksa sadece motor belli olsun diye mi yazdık? Bir de send(Byte.Parse(trackBar1.Value.ToString())); ın tam olarak ne iş yaptığını anlamadım. Değer neyse direkt onu mu gönderiyor? Ben kendi programımda send(Byte.Parse(textBox1.Text.ToString())); bunu denedim ama bunu double'a convert etmem gerekmez miydi? Bir de 249'dan fazla değer girdiğim zaman hata veriyor. Bunun sebebini araştırırken okumuştum sanırım bitlerle ilgisi var. Parça parça böl öyle oku deniyordu galiba ama o zaman da bir şey anlamamıştım. Buffer'ı sormayacağım bile =) Onu araştırmam lazım.

CCS C kısmında ise anlamadığım şey; textboxtan 123 girdiğimi düşünürsek bx=getc(); komutunda bx'in 123 olması mı beklenir? Ben öyle düşünüp aşağıdaki gibi kod yazdım ve 250'den küçük değer girdiğim zaman sonuç alabiliyorum ancak lcd'ye yazdıramadım aldığım değeri. #fuses'te INTRC_IO unknown keyword hatası veriyor bu arada. Bir de d7 pinimdeki led sürekli yanıyor, herhangi bir kod yazmama rağmen. Bunun sebebi ne olabilir? Teşekkür ederim.

C#'ta yeni yazdığım kod:

namespace Trafik_isigi_deneme1
{
    public partial class Form1 : Form
    {
        public void send(byte data)
        {
            if (serialPort1.IsOpen)
            {
                byte[] buffer = { 0 };
                buffer[0] = data;
                serialPort1.Write(buffer, 0, 1);
            }
            else
            { MessageBox.Show("Port Açık Değil!"); }
        }
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            comboBox1.DataSource = System.IO.Ports.SerialPort.GetPortNames();
            comboBox1.SelectedItem = 1;
        }

        private void button1_Click(object sender, EventArgs e) //Başlat
        {
            if (!serialPort1.IsOpen)
            {
                serialPort1.PortName = comboBox1.SelectedItem.ToString();
                serialPort1.Open();
            }
        }

        private void button2_Click(object sender, EventArgs e) //Durdur
        {
            if (serialPort1.IsOpen)
                serialPort1.Close();
        }
     

        private void button3_Click(object sender, EventArgs e) //Gönder
        {
           
            send(Byte.Parse(textBox1.Text.ToString()));
        }

    }
}



CCS C'de yeni yazdığım kod:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use rs232(baud=9600, xmit=PIN_C6, rcv=pin_C7,uart1)
#use fast_io (a)
#use fast_io (b)
#byte INTCON=0x0B
#byte PIE1=0x8C

long s1=1000; //farkı anlamak için süre
long dt; //kesme ile gelen data


void main()
{
INTCON=0b11000000; //global ve peripheral kesmeler aktifmiş
PIE1=0b00100000; //uart kesmesi ayarlanmış
set_tris_c(0b10000000);
set_tris_d(0x00); //tümüyle çıkış olsun
output_high(pin_d0); //calisma için
lcd_init();

while(1)
{
printf(lcd_putc,"\f%s",dt);
      output_high(pin_d5);
      delay_ms(s1);
      output_low(pin_d5);
      delay_ms(s1);           
}
}

#INT_RDA
void data()
{
dt=getc();
s1=dt;
}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 04 Mayıs 2011, 04:59:30
Sonuç alıyorum demiştim ama yanlış alıyormuşum.
Alıntı YapCCS C kısmında ise anlamadığım şey; textboxtan 123 girdiğimi düşünürsek bx=getc(); komutunda bx'in 123 olması mı beklenir?
ve aynı şekilde send(Byte.Parse(textBox1.Text.ToString())); girdiğim sayıyı direkt yollar mı? Bu soruların cevabını evet olarak düşünüp kodlama yapıyorum.

3 textbox'tan 3 led'i kontrol etmeye çalışıyorum. İncelediğim motor örneğinde 3 trackbar'la 3 motor kontrol ediliyordu. Anladığım kadarıyla hangi trackbar'dan bilgi geldiğinin anlaşılması için send(200); v.b. değerler gönderilip bu değerler CCS C'de yorumlanıyordu. Bende her textbox'ım için bir değer göndermeyi düşündüm ki, hangi led'in süresini hangi değerden hesaplanacağı belli olsun. Bu arada mili saniye cinsinden çalıştığım için değeri de 1000 ile çarptım. Yalnız led'lerimin yanıp sönmesini kontrol edemedim. Yardımlarınız için teşekkür ederim.

C#'ta yazdığım kod:

//Verileri Gönder
        private void button9_Click(object sender, EventArgs e)
        {
            {
                send(100);
                send(Byte.Parse(textBox1.Text.ToString()));
            }
            {
                send(101);
                send(Byte.Parse(textBox2.Text.ToString()));
            }
            {
                send(102);
                send(Byte.Parse(textBox3.Text.ToString()));
            }
        }


Bu send (101) (102) (103) işlemlerini peşpeşe yazarsam bir sıkıntı olur mu?

CCS C'de yazdığım kod:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=pin_C7,uart1)
#use fast_io (a)
#use fast_io (b)
#byte INTCON=0x0B
#byte PIE1=0x8C

long s1,s2,s3; //sürelerimiz
long dt; //kesme ile gelen data
int led=1;  // veri hangi led için gelmiş


void main()
{
INTCON=0b11000000; //global ve peripheral kesmeler aktifmiş
PIE1=0b00100000; //uart kesmesi ayarlanmış
set_tris_c(0b10000000);
set_tris_d(0x00); //tümüyle çıkış olsun
output_high(pin_d0); //calisma için

while(1)
{
      output_high(pin_d5);
      delay_ms(s1);
      output_low(pin_d5);
      output_high(pin_d6);
      delay_ms(s2);
      output_low(pin_d6);
      output_high(pin_d7);
      delay_ms(s3);
      output_low(pin_d7);
                 
}
}

#INT_RDA
void data()
{
dt=getc();
if (dt==100)
{led=1;}
if(dt==101)
{led=2;}
if(dt==102)
{led=3;}

if(led==1)
{s1=1000*dt;}
if(led==2)
{s2=1000*dt;}
if(led==2)
{s3=1000*dt;}
}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: ferdem - 04 Mayıs 2011, 11:07:17
send fonksiyonunu byte göndermek için yazmıştım ve 123 ü 123 olarak gönderiyordu, bir byte tan daha büyük(>255) bir değer için deneme yapılırsa ne olur bilemiyorum.
Alıntı YapCCS C kısmında ise anlamadığım şey; textboxtan 123 girdiğimi düşünürsek bx=getc(); komutunda bx'in 123 olması mı beklenir?
Hemen deneyebebilirsiniz; textboxa 123 yazalım, send(Byte.Parse(textBox1.Text.ToString())); ile gönderelim, PIC tarafında da:
#INT_RDA
void data(){
dt=getc();
if (dt==123)
output_toggle(pin_b0);
}

yazıp led toggle durumuna bakalım.Proteus ta da görebilirsiniz.
b0 ledi toggle olmadı o zaman hemen şunu deniyoruz:
#INT_RDA
void data(){
dt=getc();
if (dt==123)
output_high(pin_b0);
putc(dt);// 123 almadıysan ne aldın?, proteus ta virtual terminalden görebilirsiniz
}


Kesme fonksiyonunda "led" değişkenini aradan çıkarabilirsiniz(sadece bir defa if yazmanız yeterli görünüyor), ayrıca ledlerin sürelerinin ayarlanmasından önce ledleri on-off yapmayı deneyin, şöyle olabilir:

#INT_RDA
void data(){
dt=getc();
if (dt==100){
output_toggle(led1); //define led1 pin_bx varsayilsin
}
if(dt==101){
output_toggle(led2);
}
if(dt==102){
output_toggle(led3);
}

}


on-off çalıştıktan sonra süre olayında sorun çıkarsa tekrar yazarsınız. İyi çalışmalar dilerim.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 04 Mayıs 2011, 14:10:17
Merhaba, sanırım mantığıma yatmadığı için bu kadar zorlanıyorum. Şimdi C#'ta:
//Verileri Gönder
        private void button9_Click(object sender, EventArgs e)
        {
            {
                send(100);
                send(Byte.Parse(textBox1.Text.ToString()));
            }
            {
               send(101);
                send(Byte.Parse(textBox2.Text.ToString()));
            }
            {
                send(102);
                send(Byte.Parse(textBox3.Text.ToString()));
            }
        }


kodunu yazıyorum. Buradaki 100-101-102'yi yollamamın sebebi hangi textbox'tan bilginin geldiğini anlamaya çalışmak. Çünkü her textbox bir adet led'i kontrol edecek. Ama peşpeşe aralık vermeden byte göndermek sağlıklı olur mu, yani CCS C'de bunları anında alabilir miyim onu bilmiyorum?

Bu kısmını geçip CCS C'de kafama yatmayan ise;

#INT_RDA
void data()
{
dt=getc();
if (dt==100)
{
output_toggle(pin_b0);
dt=getc();
s1=1000*dt;
}
if(dt==101){
output_toggle(pin_b1);
dt=getc();
s2=1000*dt;
}


Burada şunun olmasını umuyorum; (textbox1 için konuşursam) öncelikle bakıyorum ilk aldığım byte 100 mü? 100 ise diyorum ki 100 gelmiş demek ki textbox1'in içinden gelecek sıradaki byte. O zaman diyorum ki sıradaki byte'ı da getc ile alayım ve mili saniye cinsinden çalıştığım için 1000 ile çarpayım. (Bu arada bu sıradaki byte'ı tekrar alma bunu yazarken aklıma geldi ama aralara dt=getc() sıkıştırmasam da bir şey değişmiyor) Sonra bu saniye cinsine çevirdiğim sayıyı bir değişkene atayıp delay_ms'in içine yazıyorum.

Bu arada deneme amaçlı dediğiniz gibi virtual terminal bağlayıp ne aldığımı görmek istedim. Virtual terminal'de karakterler gördüm. Biraz araştırma yapınca bunların C#'ta gönderdiğim byte'lerın ASCII olarak yollandığını anladım. Yazılarla işim olmadığından gelen ASCII (sayısal bilgilerle) bilgileriyle işleme devam ettim.

Bahsettiğiniz on-off işini verdiğiniz örnek gibi araya  output_toggle(); komutunu ekleyerek yaptım bilmiyorum doğru mu yaptım.

Devreyi çalıştığımda ledlerin süreleri yine kontrolsüz ve çok hızlı yanıyor. C#'tan veri yollamasam da aynı şekilde oluyor. Devreyi çalışıtırırken de ISIS'te şu warning'i alıyorum: Simulation is not running in real time due to excessive CPU load.

CCS C'de yazdığım kod şu şekilde şu an:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=pin_C7,uart1)
#use fast_io (a)
#use fast_io (b)
#byte INTCON=0x0B
#byte PIE1=0x8C

long s1,s2,s3; //sürelerimiz
long dt; //kesme ile gelen data

void main()
{
INTCON=0b11000000; //global ve peripheral kesmeler aktifmiş
PIE1=0b00100000; //uart kesmesi ayarlanmış
set_tris_c(0b10000000);
set_tris_b(0x00); //tümüyle çıkış olsun
output_b(0x00); //Sıfırlayalım

while(1)
{     
      output_high(pin_b0);
      delay_ms(s1);
      output_low(pin_b0);
      output_high(pin_b1);
      delay_ms(s2);
      output_low(pin_b1);
      output_high(pin_b2);
      delay_ms(s3);
      output_low(pin_b2);
     
}
}

#INT_RDA
void data()
{
dt=getc();
if (dt==100)
{
output_toggle(pin_b0);
dt=getc();
s1=1000*dt;
}
if(dt==101){
output_toggle(pin_b1);
dt=getc();
s2=1000*dt;
}
if(dt==102){
output_toggle(pin_b2);
dt=getc();
s3=1000*dt;
}

}
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 04 Mayıs 2011, 19:18:33
Öncelikle kendinizi zora soktuğunuzu görüyorum, henüz temeli oturmamış bir konuya fazladan eklemeler yapıyorsunuz ve bu şekilde işin içinden çıkmanız zorlaşıyor.
İlk olarak, birden fazla textboxtan gelen veriyi ayırma çalışmadan önce tek bir textboxtan gelen veriyi, sıfır hata ile alıp tek bir ledi ona göre yakıp söndürebilmelisiniz. Bunu sorunsuz yapabildikten sonra 3 değil 30 tane ayrı veri gönderilse kolayca ayrıştırılabilirler.

Dikkat edilmesi gerektiğini düşündüğüm bir kaç noktayı sıralayayım:

1) Öncelike 1 byte'tan büyük verilerle çalışmayın, textboxtan gönderilecek sayı şimdilik maks. 255 olsun. Yani nasıl pic tarafında birer byte şeklinde veri alıyorsak, c den de byte byte veri gönderilmeli, string şeklinde olmamalı.
2) Veri tipi olarak, hem c#'tan göndereceğiniz sayının atandığı değişkenin, hem de ccs'te verinin atanacağı değişkenin unsigned int(bir byte lık işaretsiz tamsayı) olmasına dikkat edin.
3) Gelen verinin ne olduğunu görmek için, sonsuz döngü içerisinde lcd ye yazdırmak en kolay debug yöntemi olacaktır. printf(lcd_putc,"\f%u",gelen verinin atandığı değişken)
4) C# tan gönderilen verinin karakter tipi olmadığından, sayısal değer olduğundan emin olun. örn textboxa 7 yazdığınızda iletilen veri 7 olmalı, 7 karakterinin ascii karşılığı değil.
5) C# ta her bir byte gönderimi arasına 10ms 20 ms gibi bir bekleme koyulursa, proteustaki "gerçek zamanlı sim. yapılamıyor" hatasının önüne geçilmiş olur. Aynı şekilde, ccs te sonsuz döngü içerisinde lcdye veriyi yazdırırken araya bir gecikme koyun ki hem görüntü titremesin hem o hataya yol açılmasın.
6) 3 ayrı textboxtan gelen veriyi almaya çalışırken kesme içerisinde tekrar getc ile veri beklemişsiniz. Bunun yerine tb1 tb2 tb3 şeklinde logic değişkenler(int1) tanımlayıp, bunların durumunu if kontrolleriyle gelen veriye göre değiştirirseniz daha sağlıklı olur. Bu konuyla şimdilik uğraşmayın, burası kolay kısmı. Siz tek textboxtan gelen veriyi sorunsuz alabilip ledi ona göre yaktırdıktan sonra o kısma bakarız.

Bir picten diğerine 1 bytelık sayı gönderdiğimde, alıcı picte gelen sayıyı aşağıdaki gibi alıyorum. Eğer bu kodu aynen denediğinizde, textbox'a yazılan sayıyı, lcd de göremiyorsanız, "C#'ta 8 bitlik bir sayı seri porttan nasıl gönderilir" onu araştırmalısınız. Kolay gelsin..


char veri;
unsigned int data=1;

#int_rda
void serihaberlesme_kesmesi ()
{
disable_interrupts(int_rda); // int_rda kesmesi pasif
veri=getc();
data=(unsigned int)veri;
}


   while(1) // Sonsuz döngü
   {
      enable_interrupts(int_rda); // int_rda kesmesi aktif
      printf(lcd_putc,"\f%u",data);   
      delay_ms(10);
   }



EKLEME:
Gözden kaçırmışım; zaten ferdem, C#'ta bir sayının, "sayı olarak" nasıl gönderileceğini yazmış ve kullanmışsınız. Tek yapılması gereken yukarıda verdiğim kodda olduğu gibi cast işlemiyle, gelen verinin, karakter tipinden sayı tipine çevrilmesi:

data=(unsigned int)veri;
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 04 Mayıs 2011, 23:32:08
Merhaba dediklerinizi uyguladım. CCS C'deki tüm değişkenleri unsigned int yaptım. Ancak C#'ta unsigned int yok galiba.

Şimdi şöyle hem virtual terminal hem de lcd bağladım. Lcd ekranda textbox'tan kaç girmişsem onu görüyorum sayı olarak. Virtual terminalde ise ascii karşılığı neyse onu görüyorum. Misal vermek gerekirse; textbox'tan 123 girdiğim zaman lcd'de "123", virtual terminal'de "d" yazıyor.

D portuna bağlı pinlerin kontrolsüz yanması sorunu kalktı ancak hala textbox'tan aldığım değeri delay_ms()'in içine yerleştiremedim. Textbox'tan 1 girdiğimde yavaş yanıyor, 10'da daha hızlı yanıyor, 11'de 1 girmişim gibi yanıyor..

CCS C'de denediğim kod:

#include <16F877.h>
#fuses XT,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD
#use delay(clock=4000000)
#define use_portb_lcd TRUE
#include <lcd.c>
#use rs232(baud=9600, xmit=PIN_C6, rcv=pin_C7,uart1)
#use fast_io (a)
#use fast_io (d)
#byte INTCON=0x0B
#byte PIE1=0x8C

unsigned int s1; //sürelerimiz
unsigned int dt; //kesme ile gelen data
unsigned int veri;

void main()
{
INTCON=0b11000000; //global ve peripheral kesmeler aktifmiş
PIE1=0b00100000; //uart kesmesi ayarlanmış
set_tris_c(0b10000000);
set_tris_d(0x00); //tümüyle çıkış olsun
output_d(0x00); //Sıfırlayalım
lcd_init();

while(1)
{     

printf(lcd_putc,"\f%u",veri);
delay_ms(10);
      output_high(pin_d0);
      delay_ms(s1);
      output_low(pin_d0);
      delay_ms(s1);     
}
}

#INT_RDA
void data()
{
dt=getc();
veri=(unsigned int)dt;
s1=1000*veri;

}


Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 05 Mayıs 2011, 01:05:57
Merhaba, yazdan beri c#'ı açmadım, veri tiplerinde farklılık var, doğru. Bir byte lık bir integer tanımlarsanız 127'nin üzerine çıkamazsınız diye öyle söylemiştim, çalışıyorsa sorun yok.
Virtual terminal de ascii karşılıklarını görürsünüz bu normal. Zaten lcd'den takip etmek daha kolay demem bundandı.
Delay_ms() fonksiyonunun 16bit'e kadar değer alabildiği yazıyor ccs helpinde, sorun neyden kaynaklanıyor göremedim. O 1000 çarpanını 10 yada 100e düşürüp denediğinizde durum ne?

Timer kullanımını öğrenip bu tip gecikmeleri timerla yapmalısınız. 10 snlik delay, programı öldürür. Öyle bir kod varken program led yakıp söndürmekten başka birşey yapamaz.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 05 Mayıs 2011, 01:28:57
Zaten led yakıp söndürmesinden başka bir şey istemiyorum =) Ama led sayısı 20 civarında. Eğer kastınız veri alamaz ise o zaman sabaha kadar timer çalışırım =) Hımm, evet çarğanı 10'a düşürdüğümde daha mantıklı sonuçlar çıktı. En azından textbox'tan yolladığım değer arttıkça yanıp sönme yavaşlıyor. Şu var yalnız textbox'tan 100 yazdığımda bunu 10'la çarpıp 1 saniye beklemesi gerekir ama öyle bir bekleme yok. Timer'la bu işi halledebilir miyiz? Sabaha kadar çalışmayan kod deniyorum, en azından timer öğrenirim sabaha kadar. Teşekkürler.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 05 Mayıs 2011, 02:17:13
Merhabalar, sorunumu şu an çözdüm. s1'i 8 bit üstü çalıştığım için unsigned long olarak tanımlamak gerekiyormuş. Şimdi textbox sayısını arttırıp deneyeceğim.

Onu hallettim diyelim seri iletişimsiz denemiştim başlarda projemi... O zaman bir sorunla karşılaşmıştım: Led sayımı arttırdığımda while içinde her led'in yanıp sönme komutlarını yazdığım zaman program yukarıdan aşağıya işliyor. Yani iki led'i aynı anda yakamıyorum. Şu var; trafik lambası yapacağımdan C# simulasyonunda 3'lü 3'lü (direk direk) gruplayıp öyle kodluyorum. if'lerle de on-off durumunu kontrol ettiğim zaman bütün if blokları birbirinden bağımsız zamanda çalıştığı için hem aynı anda birden fazla ışık yanıyor, hem de bir direğin durumunu on yada off yaptığım zaman anında tepki alıyorum. CCS C'de ise program yukarıdan aşağıya işliyor yani bir led sönmeden diğeri yanmıyor. C#'ta yaptığım gibi 3'lü 3'lü olarak birbirlerinden bağımsız gruplayıp nasıl kodlayabilirim? Timer kullanarak olur mu?

Herkese çok çok teşekkür ediyorum.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 05 Mayıs 2011, 03:15:44
Timer kullanmamak, bu uygulamada veri alımında sorun oluşturmaz çünkü veri kesme içerisinde alınıyor.
2. mesajdaki sorunun ilacı tam olarak, timer kullanımı.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 05 Mayıs 2011, 04:14:05
Birden fazla textbox kullanma işini ferdem'in verdiği örneği inceleyerek şu şekilde yaptım ve çalışıyor:

C#:

private void button3_Click(object sender, EventArgs e) //Gönder
        {
            {
                send(100);
                send(Byte.Parse(textBox1.Text.ToString()));
            }
            {
                send(101);
                send(Byte.Parse(textBox2.Text.ToString()));
            }
        }


CCS C:

#INT_RDA
void data()
{
dt=getc();
if(dt==100)
{
led=1;
}
if(dt==101)
{
led=2;}
if(dt<100){
if(led==1){
s1=1000*dt;}
if(led==2)
{s2=1000*dt;}
}
}


Şimdi timer kullanarak ledleri aynı anda yakma işim kaldı sanırım bir tek.. Nerde şu Serdar Çiçek'in kitabı  :)

Mantığını anlamak için soruyorum dt 100'den ne zaman küçük olur? Çünkü o kısmı yazmayınca çalışmıyor. Bir de hem diyoruz ki dt=101 ise hem de sonra aynı dt değişkenini textboxtan aldığımız değere atıyoruz. Yani bir değişkeni birden fazla bilinmeyene atıyoruz, burada sorun çıkmamasının sebebi C#'ın byte byte sırayla yollaması ve CCS C'nin de değerleri byte byte sırayla anında alması mıdır? Teşekkürler.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: 50Cal - 05 Mayıs 2011, 05:40:06
Elinizdeki kitaptan temel konuları okumanız gerekiyor. Timer çalışmadan önce de kesme konusunu öğrenin mutlaka yoksa bir süre sonra herşey birbirine girebilir, temeli sağlam tutmaya bakın.

-c# tarafından gönderilen bytelar koddaki yazım sırasına göre gönderilir. önce 100, ardından ona ait süre(tb1), 101 ve ona ait süre(tb2).
-ccs'te ise pice her bir byte geldiğinde program kesmeye gider.

ilk byte geldi kesme oluştu..
ne geldi?
100
dt=100
led=1 yapıldı ve diğer ifler kontrol edildi..
dt=100 olduğu için diğer iflere girilmez ve kesme fonksiyonundan çıkar program..
hemen ardından c#, textbox 1 deki sayıyı gönderdi, veri pice geldi, program yine kesmeye girdi.
ne geldi?
sayı (sanırım bu sayı değerleri hep 100'ün altında, ki öyle olmalı bu kodun çalışması için)
dt=sayı
sayı<100 olduğundan aşağıdaki if grubuna girer program
led neydi? 1
if(led==1) koduna geçer ve dt değerini 1000 le çarparak s1 e atar.
dt son durumda sayı olduğu için istenen işlem yapılmış olur.

böyle devam eder..

Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: vitruvius - 16 Mayıs 2011, 02:57:37
Buradaki sorunu şu şekilde çözdüm:

while(1)
{     
   Counter1++;   
   
   delay_ms(1000);
   
   // 1. Direk 
   if(Counter1==1)
   { output_low(pin_b2);
     output_high(pin_b0); }
   if(Counter1==Direk1_Kirmizi)
   { output_low(pin_b0);
     output_high(pin_b1); }
   if(Counter1==Direk1_Sari)
   { output_low(pin_b1);
     output_high(pin_b2); }
   if(Counter1==Direk1_Yesil)
   Counter1=0;}


Direk_1Kirmizi v.s. değerleri de kesme ile alıyorum. Şu an istediğim işi yapıyor. Herkese teşekkür ederim.
Başlık: Ynt: C# ile Seri Port İletişim
Gönderen: isovski - 15 Haziran 2011, 13:24:59
isiste kullandığınız rs232 portunun 2. ve 3. bacaklarını değiştirip 2. bacağı pic in RX konumuna getiriniz..