Pic18F46k22 ile 2 Uart Kullanamama

Başlatan Seferi, 20 Aralık 2017, 12:29:12

Seferi

İyi günler. Yeni temin ettiğim pic18f46k22 ile donanımsal iki adet uart birimini kullanmaya çalışıyorum.Veri geldiğinde kesmeye gitmesini istiyorum, Tek Uart da sıkıntı olmuyor ama ikincisini dahil ettiğimde veri alımını gerçekleştiremiyorum.  Nerede hata yaptığımı anlayamadım zamanı olanlar bir bakabilirler mi?

main.h
#include <18F46K22.h>
#device ADC=16

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
#FUSES NOBROWNOUT               //No brownout reset
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOXINST                  //Extended set extension and Indexed Addressing mode disabled (Legacy mode)

#use delay(clock=20000000,crystal=20000000)
#use rs232(UART1,baud=9600,parity=N,stop=1,bits=8,STREAM=PC,ERRORS) 
#use rs232(UART2,baud=9600,parity=N,stop=1,bits=8,STREAM=PIC,ERRORS)


main.c
#include <main.h>
#define LCD_ENABLE_PIN PIN_D0
#define LCD_RS_PIN PIN_D1
#define LCD_RW_PIN PIN_D2
#define LCD_DATA4 PIN_D3
#define LCD_DATA5 PIN_D4
#define LCD_DATA6 PIN_D5
#define LCD_DATA7 PIN_E0

char picgelen[48];
char pcgelen[48];
#include <lcd.c>

#INT_RDA
void  RDA_isr(void) 
{
      disable_interrupts(INT_RDA);
      lcd_gotoxy(1,1);
      printf(lcd_putc,"%s",pcgelen);
      enable_interrupts(INT_RDA);
}

#INT_RDA2
void  RDA2_isr(void) 
{
      disable_interrupts(INT_RDA2);
      fgets(picgelen,PIC);
      delay_ms(10);
      lcd_gotoxy(1,2);
      printf(lcd_putc,"%s",picgelen);
      delay_ms(100);   
      enable_interrupts(INT_RDA2);
}

void main()
{
   lcd_init();
   delay_ms(200);
  
   lcd_gotoxy(1,1);
   printf(lcd_putc,"PIC18F46K22");
   lcd_gotoxy(1,2);

   enable_interrupts(INT_RDA);
   enable_interrupts(INT_RDA2);
   enable_interrupts(GLOBAL);
   delay_ms(2000);
   
   fputs("DENEME",PC);
   fputs("AT",PIC);
   delay_ms(200);
   
   
   while(TRUE)
   {
   enable_interrupts(GLOBAL);
   }
}

dumansiz

#use delay(clock=20000000,crystal=20000000)

USART'tan önce
18F46K22 en fazla 64MHZ(16MIPS) hızında çalışır. Projenizde de clock ve kristal ayarlarınız 20MHZ şeklinde mi ayarlı?
Kesme fonksiyonunun içinde bekleme kullanmayın. Hatta diğer yazdığınız kodları da kullanmayın.
KESME1_GIRDI=1 şeklinde değişkene atama yapın. Ana fonksiyonda bu değişkeni koşul olarak kullanıp, işlem yapın. Aynı koşul içinde de bu değişkeni sıfırlayın.

fide

Merhaba. Kodda hata gözükmüyor. Hata rda kanallarının rx uçlarının boşta kalması olabilir. Daha önce 2 pici haberleştirmeye çalıştığında picin birini programlarken diğeri kilitleniyordu. Sebebi pici programlarken diğer picin seri portu boşta kalınca rda rutinine giriyor, veri gelmediği için kitleniyor.
Önerim:
Her iki rda kanalını da usb seri çevirici ile bilgisayara bağla. Xctu yada benzeri programla veri gönderip almayı dene.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

ismail kaya

#use rs232 (baud=9600,xmit=PIN_C6, rcv=PIN_C7, parity=N, stop=1,STREAM=PC) 
#use rs232 (baud=9600,xmit=PIN_D6, rcv=PIN_D7, parity=N, stop=1,STREAM=PIC)


hocam tx rx pinlerin bu şekilde belirtip dener misiniz?

dursuncemal

kesme fonksiyonlarinin icinde,kesme fonksiyonunun yaptigi isten harici bir islemin yapilmasi son derece sakincali hatta ve hatta yanlistir.delay ve lcd fonksiyonlarini ana menude gosterirseniz daha sonra cikacak problemleri daha rahat cozeriz.iyi calismalar.
:=

omereliusuk

Kesme içinde çok oyalanmışsınız. Veriyi hızlıca alıp kesme rutininden çıkmalısınız. Delay ve lcd rutinlerini başka bir yere alın. Yoksa çook veri kaybı yaşarsınız.

omereliusuk

Bir de string yerine char veya int olarak değiştirin. Bekleyip durmasın.

fide

Yeni farkettim. Rda2 içinde alınan veriyi rda1 kesmesi içinde ekrana yazdırıyorsunuz. Rda kesmesi içinde rdaya ait veri alma işlemi yok.
Şu şekilde kullanım mantıklı olur:
Unsigned int8 rda2_valid;
Rda2 içine rda2_valid=1;
While(1)
içine if (rda2_valid==1)
{
Printf ( lcd_putc,"%s"rda2_gelen);
Rda2_valid=0;
}


daha mantıklı olur.
Bir de gets ile veri aldığın için gönderdiğin veri sonunda sadece enter olmalı. Bazı programlar /r/n gönderir.
Sondaki /n senin programının tekrar rda rutinine girmesine vr enter gelene kadar beklemesine sebep olur.
Her birimiz, geride bıraktığımız eserler kadar ölümsüzüz. Evlat gibi, talebe gibi, icatlar gibi...   http://fidenetgaraj.blogspot.com

eti

interrupt rutinleri içerisinde disable/enable interrupt kullanmanıza gerek yok.
interrupt ile uygulama yaptığınızda  prograamın hiçbir yterinde delay kullanmayın. delay_ms/delay_us fonksiyonları interrruptları maskeliyor.
gecikme döngülerini for veya while ile yapın. bu şekilde interrupt geldiğinde bir sorun olmaz.
arkadaşların dediği gibi interrupt rutinlerini fazla meçgul etmeyin. girin ve çıkın



Seferi

#9
Yardımlarınız için çok teşekkür ederim. Sağlık problemleri nedeniyle yeni bakabildim. Akşam tavsiyeleriniz üzerine kodu tekrar düzenleyip deneyecegim.