16f877a ile hesap makinesi programı yazımı

Başlatan hemso, 04 Temmuz 2010, 23:34:16

hemso

Arkadaşlar merhaba,
pic programlama işine yeni girdim.hi tech c ile 16f877a da hesap makinesi programı yazmam gerekiyor ve bunu virtual terminal üzerinden yapmak zorundayım.yani virtual terminalden sayı gireceğim pic bu sayıyı alacak işlemleri yapacak ve sonra tekrar virtual terminal ekranına yollayacak.Ancak kafamı kurcalayan bir sorun oluştu. bir yerden bulduğum libraryde, ekrana yazdıgımız karakterleri almak için getch() diye bir fonksiyon yazmıs.getch fonksiyonunun döndürdüğü değişken char türü bir değişken.ben sayılarla işlem yapacağım için char yerine int veya float yazmam gerekiyor fakat bunları yazdıgımda hata veriyor.sanırım bu hata receive ve transmit işleminin 8 bitlik ayarda yapılmasından kaynaklanıyor.Bu sorunu nasıl düzeltebilirm?yardımlarınız için şimdiden teşekkürler..

hemso

sadece denemek için yazdıgım kodu aktarayım:

#include <htc.h>
#include <stdio.h>

#include "delay.h"
#include "usart2.h"

void main(void) // Ana fonksiyon alanı
{
int a;

TRISC=0xF0; // USART pinleri giris olarak kabul ediliyor

usart_init(); // USART ilk ayarları yapılıyor
a=getch();
putch(a);
for(;;)
{

printf("dmsalk");
}
}

ayrıca kullandıgım usart.c source file ı da şu:

#include <pic.h>
#include "stdio.h"
#include "usart2.h"
void usart_init(void)
{
unsigned char speed,nine_bits;
unsigned int divider;
RX_PIN = 1; // Seri iletisim pinleri giris olarak tanımlanıyor
TX_PIN = 1;
if(HIGH_SPEED==1) // Hızlı iletisim yapılacaksa
speed=0x4;
else // Yaval iletisim yapılacaksa
speed=0x00;
if(NINE==1) // 9 bitlik iletisim yapılacaksa
nine_bits=0x04;
else // 8 bitlik iletisim yapılacaksa
nine_bits=0x00;
SPBRG = DIVIDER; // Hız değeri SPBRG'ye yükleniyor
RCSTA = (nine_bits|0x90); // Alım kaydedicisi ayarlanıyor
TXSTA = (speed|nine_bits|0x20); // Gönderim kaydedicisi ayarlanıyor
}
void putch(char byte)
{
// Tek byte gönder
while(!TXIF); // Transfer tamponu bos mu
TXREG = byte; // Tek byte gönderiliyor
}
char getch(void)
{
// Tek byte al
while(!RCIF); // Alım tamponu bos mu
return RCREG; // Tek byte alınıyor
}

hemso

yukarıdaki library de putch içindeki ve getch ın döndürdüğü değeri char olarak bırakırsam program derlenebiliyor.ancak bu 2 char ı int yaparsam hata alıyorum.

fatihinanc

void putch(char byte)

Zaten putch() fonksiyonuna gelen veri char olarak tanımlanmış.
int giremezsin.

return RCREG;

bu kısımda açıklamada belirtildiği gibi byte(char) dır. aynı şekilde buna da int giremezsin.

bir de a yı int olarak değil de char olarak tanımlamalısın.
klavyeden veri okuduğun için char olması gerekir.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

BenC

getch() ve putch() fonksiyonları adından da anlaşılacağı üzere char türünde veri döndürür veya ister.

Siz seri port dan veriyi char türünde alıp bunu bir fonksiyonla integer 'a dönüştüreceksiniz.  aşağıda ki vereceğim fonksiyon işinizi görecektir. Orda yanlız eklenmesi gereken bişey daha var girdiğiniz sayının kaç haneden oluştuğu. Bu değeride işleme sokara bu fonksiyon işinizi görür.

/*******************************************************************************/
/***                   DIGIT VERİYİ DECIMAL VERİYE DÖNÜŞTÜR                  ***/
/*******************************************************************************/
/*******************************************************************************/
/*Fonksiyon Adı  : int DigToDec()                                              */
/*Açıklama       : Fonksiyona giren 4 değişik digit verisini birleştirip       */
/*                 int türünde decimal veri üretmek.                           */
/*                 Örneğin herhangi bir cihazdan alınan 4 basamaklı veriyi 4   */
/*                 değişik değişkende saklamak yerine int türünden bir değiş-  */
/*                 kende decimal değeri olarak saklamak.                       */
/*                                                                             */
/*                                                                             */
/*Yazar          : Armağan YILMAZ                                              */
/*Tarih          : 01.06.2009                                                  */
/*Version        : 1.0                                                         */
/*                                                                             */
/*Giriş          : char xDeger1,char xDeger2,char xDeger3,char xDeger4         */
/*               :                                                             */
/*Çıkış          : int DigToDec()                                              */
/*                                                                             */
/*                                                                             */
/*Kullanılan Veri: 1 byte                                                      */
/*******************************************************************************/
int DigToDec(char xDeger1,char xDeger2,char xDeger3,char xDeger4,char xDeger5,char xDeger6,char xDeger7)

	{
		char tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,tmp10,tmp11,tmp12,tmp13,tmp14;

		tmp1 = xDeger1 << 4;		
		tmp2 = tmp1 >>4;

		tmp3 = xDeger2 << 4;		
		tmp4 = tmp3 >>4;

		tmp5 = xDeger3 << 4;		
		tmp6 = tmp5 >>4;

		tmp7 = xDeger4 << 4;		
		tmp8 = tmp7 >>4;

		tmp9  = xDeger5 << 4;		
		tmp10 = tmp9 >>4;

		tmp11  = xDeger6 << 4;		
		tmp12 = tmp11 >>4;

		tmp13  = xDeger7 << 4;		
		tmp14 = tmp13 >>4;



		return (((tmp2*1000000)+(tmp4*100000)+(tmp6*10000)+(tmp8*1000)+(tmp10*100) +(tmp12*10)+ (tmp14*1)));

	}	
/*******************************************************************************/
/*******************************************************************************/




getch() ile aldığınız  sayısal karakterleri bu fonksiyon ile decimal yani integer yaparsınız. Daha sonra matematiksel işlemi yaparsınız. İşlem sonucunun da printf() fonksiyonunu formatlı kullanarak çıktı alırsınız. Eğer işlemler float ağırlıklı ise sprintf() fonksiyonunu kullanırsınız.
ŞEHİT KANIYLA ALINMIŞ BU GÜZELİM VATANIN TOPRAKLARI KARIŞ KARIŞ SATILIYOR!!  VATAN HAİNİ OLMA!!

fatihinanc

Hocam çok bilmişlik gibi olmasın ama atoi() diye bir fonksiyon vardı. o da aynı işlevi mi görüyor yoksa ben mi karıştırdım.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

BenC

Burda da integer veriyi basamaklarına ayırma olayı var yani int den char a dönüş.

/*******************************************************************************/
/***                 DECIMAL VERİYİ BASAMAKLARINA AYIRMAK                    ***/
/*******************************************************************************/
/*******************************************************************************/
/*Fonksiyon Adı  : void DecToDig()                                             */
/*Açıklama       : Fonksiyona giren 3 basamaklı decimal veriyi basamaklarına   */
/*                 ayırmak. Fonksiyon dönüş değerini Pointer kullanarak        */
/*                 gerçekleştirmektedir.                                       */
/*                                                                             */
/*                                                                             */
/*                                                                             */
/*                                                                             */
/*Yazar          : Armağan YILMAZ                                              */
/*Tarih          : 01.06.2009                                                  */
/*Version        : 1.0                                                         */
/*                                                                             */
/*Giriş          : int Deger                                                   */
/*               :                                                             */
/*Çıkış          : int *Dig1,int *Dig2,int *Dig3                               */
/*                                                                             */
/*                                                                             */
/*Kullanılan Veri: 1 byte                                                      */
/*******************************************************************************/
void DecToDig(int Deger,unsigned char *Dig1,unsigned char *Dig2,unsigned char *Dig3)

	{
		int d1,d2,d3,a,b,c;

			a=Deger/100;
			
			d1=Deger-a*100;
				
			b=d1/10;
				
			d2=d1-b*10;
			
			c=d2;
				
			*Dig1=a;
			*Dig2=b;
			*Dig3=c;


	}
/*******************************************************************************/
/*******************************************************************************/



Bu iki fonksiyonu birazcık geliştirerek hesap makinan da kullanabilirsin.
ŞEHİT KANIYLA ALINMIŞ BU GÜZELİM VATANIN TOPRAKLARI KARIŞ KARIŞ SATILIYOR!!  VATAN HAİNİ OLMA!!

BenC

Alıntı yapılan: fatihinanc - 05 Temmuz 2010, 00:39:41
Hocam çok bilmişlik gibi olmasın ama atoi() diye bir fonksiyon vardı. o da aynı işlevi mi görüyor yoksa ben mi karıştırdım.
Estafurullah üstad.

atoi() de aynı işlevi görüyor. Şuan hatırlamıyorum ama atoi() de bir sorun yaşamıştım (sanırım ondalıklı sayı girmede)ondan dolayı bu kodu yazmıştım. Hem arkadaş için güzerl bir örnek teşkil etmiş olur.
ŞEHİT KANIYLA ALINMIŞ BU GÜZELİM VATANIN TOPRAKLARI KARIŞ KARIŞ SATILIYOR!!  VATAN HAİNİ OLMA!!

fatihinanc

Evet hocam neticede oturup yazmışsınız buna saygı duyulur.aynı işi yapmasına rağmen sizinkinde Türkçe açıklamalar da mevcut. hem dönüştürme işleminin mantığını da kavramış oluruz böylece.
dediğiniz gibi güzel de bir örnek olmuş zaten.

float için de atof() fonksiyonunu kullanıyorduk yanlış hatırlamıyorsam.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

sigmoid

#9
veriyi char olarak aldiktan sonra 48 ile 57 arasinda bir değere sahip olup olmadiğini kontrol et. ascii tablosunda rakamlar bu değerler arasindadir. gelen değer bu aralikta ise 48 çikartip kullanabilirsin.

int sayi;
a=getch();
if(a>47 

hemso

Alıntı yapılan: BenC - 05 Temmuz 2010, 00:34:37
getch() ve putch() fonksiyonları adından da anlaşılacağı üzere char türünde veri döndürür veya ister.

Siz seri port dan veriyi char türünde alıp bunu bir fonksiyonla integer 'a dönüştüreceksiniz.  aşağıda ki vereceğim fonksiyon işinizi görecektir. Orda yanlız eklenmesi gereken bişey daha var girdiğiniz sayının kaç haneden oluştuğu. Bu değeride işleme sokara bu fonksiyon işinizi görür.

/*******************************************************************************/
/***                   DIGIT VERİYİ DECIMAL VERİYE DÖNÜŞTÜR                  ***/
/*******************************************************************************/
/*******************************************************************************/
/*Fonksiyon Adı  : int DigToDec()                                              */
/*Açıklama       : Fonksiyona giren 4 değişik digit verisini birleştirip       */
/*                 int türünde decimal veri üretmek.                           */
/*                 Örneğin herhangi bir cihazdan alınan 4 basamaklı veriyi 4   */
/*                 değişik değişkende saklamak yerine int türünden bir değiş-  */
/*                 kende decimal değeri olarak saklamak.                       */
/*                                                                             */
/*                                                                             */
/*Yazar          : Armağan YILMAZ                                              */
/*Tarih          : 01.06.2009                                                  */
/*Version        : 1.0                                                         */
/*                                                                             */
/*Giriş          : char xDeger1,char xDeger2,char xDeger3,char xDeger4         */
/*               :                                                             */
/*Çıkış          : int DigToDec()                                              */
/*                                                                             */
/*                                                                             */
/*Kullanılan Veri: 1 byte                                                      */
/*******************************************************************************/
int DigToDec(char xDeger1,char xDeger2,char xDeger3,char xDeger4,char xDeger5,char xDeger6,char xDeger7)

	{
		char tmp1,tmp2,tmp3,tmp4,tmp5,tmp6,tmp7,tmp8,tmp9,tmp10,tmp11,tmp12,tmp13,tmp14;

		tmp1 = xDeger1 << 4;		
		tmp2 = tmp1 >>4;

		tmp3 = xDeger2 << 4;		
		tmp4 = tmp3 >>4;

		tmp5 = xDeger3 << 4;		
		tmp6 = tmp5 >>4;

		tmp7 = xDeger4 << 4;		
		tmp8 = tmp7 >>4;

		tmp9  = xDeger5 << 4;		
		tmp10 = tmp9 >>4;

		tmp11  = xDeger6 << 4;		
		tmp12 = tmp11 >>4;

		tmp13  = xDeger7 << 4;		
		tmp14 = tmp13 >>4;



		return (((tmp2*1000000)+(tmp4*100000)+(tmp6*10000)+(tmp8*1000)+(tmp10*100) +(tmp12*10)+ (tmp14*1)));

	}	
/*******************************************************************************/
/*******************************************************************************/




getch() ile aldığınız  sayısal karakterleri bu fonksiyon ile decimal yani integer yaparsınız. Daha sonra matematiksel işlemi yaparsınız. İşlem sonucunun da printf() fonksiyonunu formatlı kullanarak çıktı alırsınız. Eğer işlemler float ağırlıklı ise sprintf() fonksiyonunu kullanırsınız.

sayın benc ve diger arkadaslar ilginiz icin cok tesekkür ederim.yalnız benc arkadasım üstteki digiti decimale cevirme kısmında anlamadıgım birkaç şey var.öncelikle mesela klavyeden 4 tane veri girildiyse orda parantez içinde xdeger1,xdeger2 seklinde giden karakterler neden 7 ye kadar gidiyor, xdeger 4 e kadar olması gerekmezmi.2. olarak orada yazdıgımız tmp nin tek degerli olanlarını(tmp1,tmp3 vs.)daha sonra kullanmıyoruz.yani sonuctanın tmpnin cift degerli olanlarını return ün icinde işleme sokuyoruz.o halde bu tekli tmpleri neden yazıyoruz?olaya yeni basladıgım icin biras gec anlıyor olablrim verdiğim zahmet icin şimdiden hakkınızı helal edin.

hemso

hocam bahsettiğiniz yöntemi dediğim gibi anlayamayınca  atoi ve atof ile yapmayı denedim.işlemleri integer için yapınca dogru.ama yukarıda belirttiğiniz gibi atof kullanınca yani float olarak yapınca sacma sapan sonuclar cıkartıyor.bunu nasıl cözebilirim bir yöntemi varmı.sürem biraz dar o yüzden su an icin bu yöntem üzerine yogunlastım.

fatihinanc

sadece o kısmın kodunu koyarsan daha iyi olur. çünkü birçok yerde hata olabiliyor. değişken türü ,atof() fonsiyonun özellikleri vs. pointer değer tanımlayıp onun üzerinden işlem yapıyorsunuz değil mi?
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

BenC

Bu fonksiyonu kullanabilirsin derken birazcık modifiye etmen gerekiyor. Çünkü yukarıdaki mesajlarım da da yazdım. Girilecek hane sayısınıda işlemden geçirmen gerekiyor. Yoksa sadece 7 hane girmen gerekir vya o haneleri 0 girmen gerekir. Bu fonksiyonu kendi projemde kullanmak için yazmıştım. GPS verilerini 7 hanede işleme sokuyordum onun için. orjinal atoi() fonsiyonuna bakarsan

atoi(register const char *s)  fonksiyona karakter dizisi sokuyorsun. Yukarıdaki yazmış olduğum fonksiyonlar sana fikir vermesi açısından uygun.

projenize math.h kütüphanesini eklemeyi unutmayın.

float işlemlerinde birde sprintf() fonksiyonunu deneyin. int üzeirinde matematiksel işlemlerinizi yapın daha sonra çıkan sonucu sprintf ile bir bufer'a yazdırın sonrada bunu çıktı olarak geri gönderin. 
ŞEHİT KANIYLA ALINMIŞ BU GÜZELİM VATANIN TOPRAKLARI KARIŞ KARIŞ SATILIYOR!!  VATAN HAİNİ OLMA!!

hemso

#include <htc.h>
#include <stdio.h>
#include <stdlib.h>
#include "delay.h"
#include "usart2.h"
#include <math.h>

void main(void) // Ana fonksiyon alanı
{

const char *c[15];
const char *d[15];
unsigned char e[2];
int i,;
float x,y;
float sonuc;

TRISC=0xF0; // USART pinleri giris olarak kabul ediliyor
usart_init(); // USART ilk ayarları yapılıyor

for(i=0;i<14;i++)
{
c=getch();
putch(c);

if(c==13)//yani enter a basılınca.
break;
}

for(i=0;i<2;i++)//bu şartı işlem işaretini yazdıktan sonra entera basınca assa gecmesi icin yazdık.
{
e=getch();
putch(e);
if(e==13)
break;
}

for(i=0;i<14;i++)
{
d=getch();
putch(d);
if(d==13)
break;
}

x=atof(c);
y=atof(d);

if(e[0]=='+')
sonuc=x+y;
if(e[0]=='-')
sonuc=x-y;
if(e[0]=='*')
sonuc=x*y;
if(e[0]=='/')
sonuc=x/y;
printf("=%d",sonuc);

for(;;);
}

oradakii float olan x,y ve sonuc degerlerini int olarak belirledigimde ve atof yerine atoi yazdıgımda işlemleri int olarak dogru bir sekilde yapıyor ancak yukarıdaki gibi olunca sonuc olarak ekrana hep 0 yazdırıyor bu seferde.anlayamadım sorunu bir türlü.