analog okuma

Başlatan pax, 15 Kasım 2014, 23:02:24

pax

xc8 de pic18f2550 nin A0 pinine bir poatansiyometre bağlıyorum ve ADC işlemi yapıyorum ve elde ettiğim değerleri 2x16 LCD ekranda gösteriyorum. potansiyometrenin değerini değiştirdikçe okuduğum değer de değişiyor. 0 dan 1023 e kadar değer okuyorum buraya kadar herşey normal. potansiyometre son sınırda iken 1023 okuyabiliyorum . sıkıntım 1023 okuduktan sonra potansiyometrenin değerini ters yönde değiştiriyorum normalde 1023-1018 1015 gibi azalarak gitmesi gerekiyor ve azalıyor da. ancak 1000 den geriye 990 gibi bir değer alması gerekirken ekranda 9991 gibi bir değer okuyorum. yardıcı olursanız sevinirim

program
#include <xc.h>
#include <pic18f2550.h>
#include <stdio.h>
#include "lcd.h"
#include <stdint.h>
#pragma config FOSC = XTPLL_XT    // XT oscillator, PLL enabled (XTPLL)
#pragma config CPUDIV =OSC1_PLL2  // [Primary Oscillator Src: /1][96 MHz PLL Src: /2]
#pragma config PLLDIV = 1         // No prescale (4 MHz oscillator input drives PLL directly)
#pragma config USBDIV = 2         // USB clock source comes from the 96 MHz PLL divided by 2
#pragma config FCMEN = OFF        // Fail-Safe Clock Monitor disabled
#pragma config IESO = OFF         // Oscillator Switchover mode disabled
#pragma config PWRT = OFF         // PWRT disabled
#pragma config VREGEN = OFF       // USB voltage regulator disabled
#pragma config BOR = OFF          // PORTB<4:0> pins are configured as digital I/O on Reset
#pragma config WDT = OFF
#pragma config PBADEN = OFF
#pragma config MCLRE = ON

#define _XTAL_FREQ 48000000

char s1[16]="ANALOG OKUMA";
char s2[16]="";
int veri=0;
const float adc =5.0/ 1023;
int adc_deger=0;
void ilk_ayar(void);
void bekle(unsigned int );

main()
{
    uint8_t i;
    ilk_ayar();
    lcd_init();

      
    for(;;)
    {
       ADCON0bits.CHS=0x00;
      __delay_us(25);
       ADCON0bits.GO=1;
       while(ADCON0bits.nDONE);
       veri=(ADRESH<<8)+ADRESL;
     
        lcd_gotoxy(1,1);
        sprintf(&s2,"adc= %d",veri);
        lcd_yaz(s2);
        for(i=0;i<16;i++)
        {
        s2[i]="";
        }
    }

}
void ilk_ayar()
{
     PORTA = 0X00;
     LATA  = 0X00;
     ADCON1 = 0X0A;
     CMCON = 0X07;
     TRISAbits.RA0= 1;
     PORTB = 0X00;
     LATB = 0X00;
     ADCON1 = 0X0A;
     TRISB = 0X00;


     ADCON0bits.CHS3=0;
     ADCON0bits.CHS2=0;
     ADCON0bits.CHS1=0;
     ADCON0bits.CHS0=0;

   
    ADCON2bits.ACQT2=1;
    ADCON2bits.ACQT1=1;
    ADCON2bits.ACQT0=1;


    ADCON2bits.ADCS2=1;
    ADCON2bits.ADCS1=0;
    ADCON2bits.ADCS0=0;

    ADCON2bits.ADFM=1;

    ADCON0bits.ADON=1;

}
void bekle(unsigned int x)
{
   unsigned int i;

   for(i = 0; i < x; i++)
   {
      __delay_ms(1);
   }
}
 

lcd kütüphanesi meftun un kütüphanesinin biraz değiştirilmiş hali

lcd.c
#include <p18f452.h>
#include "lcd.h" // lcd.h dosyasi tanimlanip, degerler aliniyor
#include "delays.h" // Gecikme fonksiyonu tanimlaniyor
void lcd_busy(void)
{
    //DelayUs(250);
    Delay10TCYx(312);
}

void lcd_komut(unsigned char c) // Komut gönderme fonksiyonu
{
    unsigned char data_komut  ;

    rw=0; // LCD'ye yazma yapilacak
    rs=0; // LCD'ye komut gönderilecek
    e=1; // Düsen kenar tetikleme oldugu için E önce 1

    data_komut= ( c & 0xF0 );
    data_ayar(data_komut);
    

    
    e=0; // E, 0 yapiliyor
    lcd_busy(); //Belirli süre bekleniyor
    e=1; // E, 1 yapiliyor

    data_komut = ( (c & 0x0F)<<4 ); // Düsük degerlikli bitler gönderiliyor
    data_ayar(data_komut);

    e=0; // E, 0 yapiliyor
    lcd_busy(); // Belirli bir süre bekleniyor
}

void veri_yolla(unsigned char c)
{
    unsigned char data_veri  ;
    rw=0;
    rs=1; // Komut yolladan tek farki, RS'nin 1 olmasi
    e=1;
    data_veri  = ( c & 0xF0 );
    data_ayar(data_veri );

    e=0;
    lcd_busy();
    e=1;

    data_veri= ( (c & 0x0F)<<4 ); // Düsük degerlikli bitler gönderiliyor
    data_ayar(data_veri );
    e=0;
    lcd_busy();
}

void lcd_clear(void) // LCD siliniyor
{
    lcd_komut(0x1);
    //DelayMs(2);
    Delay10KTCYx(2);
}

void lcd_yaz(const char * s) // LCD'ye string ifade gönderiliyor
{
    lcd_busy();
    while(*s)
    veri_yolla(*s++);
}

void lcd_gotoxy(unsigned char x,unsigned char y) //LCD'nin belli //bölgesine gidiliyor
{
    if(x==1)
    lcd_komut(0x80+((y-1)%16));
    else
    lcd_komut(0xC0+((y-1)%16));
}

void lcd_init() // LCD ilk yükleme ayarlari yapiliyor
{
    lcd_tris.RB4=0;
    lcd_tris.RB5=0;
    lcd_tris.RB6=0;
    lcd_tris.RB7=0;

    rs_tris=0;
    rw_tris=0;
    e_tris=0;

    rs = 0;
    e = 0;
    rw = 0;
    Delay10KTCYx(15);
    e=1;
    lcd_komut(0x02);
    Delay10KTCYx(2);
    lcd_komut(CiftSatir4Bit);
    lcd_komut(SagaYaz);
    lcd_komut(ImlecGizle);
    lcd_clear();
    lcd_komut(BirinciSatir);
}
void data_ayar(unsigned char data)
{
    unsigned char data_kur;

    data_kur=data & 0x80;
    if(data_kur==0x80)
        data_7=1;
    else data_7=0;

    data_kur=data & 0x40;
    if(data_kur==0x40)
        data_6=1;
    else data_6=0;

    data_kur=data & 0x20;
    if(data_kur==0x20)
        data_5=1;
    else data_5=0;

    data_kur=data & 0x10;
    if(data_kur==0x10)
        data_4=1;
    else data_4=0;

}


lcd.h
#define rs LATBbits.LATB0
#define rw LATBbits.LATB1
#define e  LATBbits.LATB2
#define rs_tris TRISBbits.RB0
#define rw_tris TRISBbits.RB1
#define e_tris  TRISBbits.RB2

#define lcd_port LATB
#define lcd_tris TRISBbits

#define data_7 LATBbits.LATB7
#define data_6 LATBbits.LATB6
#define data_5 LATBbits.LATB5
#define data_4 LATBbits.LATB4
////////////////////////////////////////////

/* LCD'de kullanilan komutlarin tanimlamasi*/
#define Sil 1 // Ekrani temizler
#define BasaDon 2 // Imleci sol üst köseye getirir
#define SolaYaz 4 // Imlecin belirttigi adres azalarak gider
#define SagaYaz 6 // Imlecin belirttigi adres artarak gider
#define ImlecGizle 12 // Göstergeyi ac, kursor görünmesin
#define ImlecAltta 14 // Yanip sönen blok kursor
#define ImlecYanSon 15 // Yanip sönen blok kursor
#define ImlecGeri 16 // Kursoru bir karakter geri kaydir
#define KaydirSaga 24 // Göstergeyi bir karakter saga kaydir
#define KaydirSola 28 // Göstergeyi bir karakter sola kaydir
#define EkraniKapat 8 // Göstergeyi kapat (veriler silinmez)
#define BirinciSatir 128 // LCD'nin ilk satir baslangiç adresi
// (DDRAM adres)
#define IkinciSatir 192 // ikinci satirin baslangiç adresi
#define KarakUretAdres 64 // Karakter üreteci adresini belirle
// (CGRAM adres)
/* LCD'de Kullanilan Fonksiyon Seçimi */
#define CiftSatir8Bit 56 // 8 bit ara birim, 2 satir, 5*7 piksel
#define TekSatir8Bit 48 // 8 bit ara birim, 1 satir, 5*7 piksel
#define CiftSatir4Bit 40 // 4 bit ara birim, 2 satir, 5*7 piksel
#define TekSatir4Bit 32 // 4 bit ara birim, 1 satir, 5*7 piksel
extern void veri_yolla(unsigned char);
extern void lcd_clear(void);
extern void lcd_yaz(const char *s);
extern void lcd_gotoxy(unsigned char x, unsigned char y);
extern void lcd_init(void);
extern void lcd_komut(unsigned char c);
extern void data_ayar(unsigned char data);


devre şeması



F493

Selam,

   En son ekranda 4 karakter vardi ve siz 999'a dusunce 3 karakter oldu. Yani son karakteri silemedi. Ekrana   %04d seklinde yazdirmayi deneyin.

sprintf(&s2,"adc= %04d",veri);

Eger olmazsa yazmadan önce ekranı temizleyip öyle yazın fakat yukarıdaki olması gerekir.


Esen kalın.

pax

dediğiniz şekilde oluyor örneğin 1003 ten geriye gelince 0989 yazıyor. ekranı silince de oluyor o zaman da 989 yazıyor. sonuç itibari ile burada ki sorun birler hanesinin ekranda kalıyor olmasından kaynaklanıyor. ancak benzer uygulamayı CCS C İle yapmıştım orada böyle bir sıkıntı olmamıştı. acaba LCD kütüphanesinde değiştirmem gereken bir şeyler olabilir mi?

Kabil ATICI

Bunun cevabını kütüphanede aramak gerek.
Hatta kendi kütüphane veya fonksiyonunu oluşturabilirsin. Gördüğüm kadarı ile bunu yapabilecek durumdasın.
ambar7

Extreme

%d olan yeri %4d yazmayı deneyin.