PİC'le Termometre Kontrolü

spiritevil

Üye
Katılım
21 Tem 2009
Mesajlar
21
Puanları
1
Yaş
38
ARKADASLAR AŞAGIDAKİ KODLAR Bİ TERMOMETRE CALIŞTIRIYOR BEN PİC 16F877A NIN 30. BACAGINA ROLE 29.BACAGINADA Bİ LED TAKICAM SICAKLIK DEĞERİ 35 İN ÜSTÜNDE İSE ROL ÇEKTİRECEM (YANİ 30 BACAKTAN ENERJİ ALICAK) 35 İN ALTINDA İSE LED YANMASINI İSTEYECEM(29. BACAK) BU KODU AŞAGIDAİ KOD DİZİLİŞİNE GÖREEKLEYE BİLİRMİSİNİZ?? LÜTFEN PAZARTESİ PROJEYİ TESLİM ETMEM LAZIM PİC CCS USTALARINDAN YARDIMLARINI ESİRGEMEMELERİNİ RİCA EDİYORUM ŞİMDİDEN COK TEŞEKKÜR EDERİM.....







#include <16f877.h>
#device ADC=10 // 10 bitlik ADC
#use delay (clock=4000000) //Clock frekansı
#use fast_io(a)//D B ve A portları kullanılacak
#use fast_io(b)
#use fast_io(d)
#define zaman 100//basamaklar arasındaki ms kadar zaman

unsigned long int ad1; // ADC den ölçülecek değer
float voltaj,sicaklik,filterval; // Değişkenler

void yazdir(int bas1 , int bas2 , int ond1 )//Göstergeye yazdıran fonksiyon
{
// 0 1 2 3 4 5 6 7 8 9
int dizi[10]={0x03,0x9F,0x25,0x0D,0x99,0x49,0xC1,0x1F,0x01,0x09};
int i=1000;

set_tris_b(0x00);
set_tris_d(0x00);

output_d(0x00);
output_B(0x00);

while(--i)
{
delay_us(zaman);
output_d(0x01);
output_b(0x63);

delay_us(zaman);
output_d(0x02);
output_b(*(dizi+ond1));

delay_us(zaman);
output_d(0x04);
output_b(*(dizi+bas2));


delay_us(zaman);
output_d(0x04);
output_b(0xFE);

delay_us(zaman);
output_d(0x08);
output_b(*(dizi+bas1));
}
}


void main()
{
int bas1;
int bas2;
int ond1;
/*
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
setup_CCP1(CCP_OFF);
setup_CCP2(CCP_OFF);*/
setup_adc(adc_clock_div_32);
setup_adc_ports(AN0);
//RA0/AN0 girişi analog
set_adc_channel(0); // A/D işlemi yapılacak
delay_us(20);

while(TRUE) // sonsuz döngü
{

ad1=read_adc();
voltaj=(0.0048828125*ad1)*1000; //Dijitale çevrilmiş değerin mV değeri
sicaklik=(voltaj/10)+0.25; // Her 10mV'ta 1 derece artış
delay_ms(3);

filterval=(0.9*filterval)+(0.1*sicaklik);

bas1=filterval/10;
bas1=bas1%10;

bas2=filterval/1;
bas2=bas2%10;

ond1=filterval*10;
ond1=ond1%10;

yazdir(bas1,bas2,ond1);
}
 
Moderatör tarafında düzenlendi:
Ben size yolu tarif edeyim, programı siz düzenleyin.

Portd yi displayde kullandığınız için orada modifikasyona gitmeniz gerekir. Normalde iki tane 4 bitten oluşan ve ilk 4 biti display için kullanılacak bir structure tanımlayın ve bunu #byte preprocessor talimatı ile portd ye bağlayın. o zaman output_d(....) yerine doğrudan structure'ın ilk dört bitlik değişkenine 1 2 4 ve 8 rakamları atayarak dijitleri sürebilirsiniz.

Structure'ın ikinci 4 bitini de sıcaklık değerini 35 ile karşılaştırarak istediğiniz şekilde kolayca yapabilirsiniz sanırım. Yardım istemekteki amacınız kodun bu kısmını yazdırmak değil de portd deki display ile röle çakışmasını yapamıyor olmanızdı, yani o olması lazım. Yoksa bu kadar kodu yazan birisinin if karşılaştırmasını yapamayacağını düşünemem bile :)

Bir de display sürme mantığınız sağlıklı değil. Yani normalde 4 ms lik bir timer kesmesi oluşturup display sürme işini oradan yapsanız profesyonelce birşey yapmış olursunuz.

Bir de (bu son) satırlarda neler yapılmak istendiğini ileride kendiniz hatırlamak, yardım istediğiniz kişilere ne yapmak istediğinizi bildirmek açısından yorum eklemenizde fayda var.

Kolay gelsin.
 
if (sicaklik>30)
output_d(128);
else
output_d(64);


ben boyle denedim olmadıgı için yardım istedim yeni basladım bu biraz kopya cekerek yapmamda bi sakınca yok heralde :D

bide ben dediklerinizden bişi anlamadım eklerseniz cok sevinirim ....
 
Moderatör tarafında düzenlendi:
if (sicaklik>30)
output_d(128);
else
output_d(64);

bu şekilde yaparsanız display sürerken 128 değeri yani d6 bacağının değeri 0 a döner ve istediğiniz röle çekmesi durur. Benim de bahsettiğim bu. Eğer C de program yazıyorsanız structure oluşturmayı biliyor olmanız lazım. oluşturduğunuz structur ı bir porta #byte tanımı ile atabilirsiniz. Bunun en güzel örneği ccs deki Lcd.c driveridır. CCS yi yüklediğiniz yerden bulup bakabilirsiniz. lcd isminde bir structure tanımlanmış ve bu port b veya d ye atanmış. Ondan sonraki kullanımlarında output_d(sayı) yerine lcd.data=sayı şeklinde kullanılmış. aynı mantık sizin programda kullanılacak.

Bir de bu yöntem uzun derseniz, port d ye atanacak sayıyı doğrudan output_d(sayi) şeklinde göndermeyin. bir değişken yanımlayın. Bu değişkende röle ve dijit değerleri saklı kalsın. output_d ile bu değişkeni çıkışa verin. değişkenin ilk 4 bitini dijitler için diğer 4 bitini röle ve led için kullanın. structure tanımı ile otomatik yapılan işi siz kendiniz yapacaksınız. örneğin, değişken ismi tmp olsun. Çıkışta röleyi çekiyor olsun. Aynı zamanda da birinci dijit sürülüyor olsun. bu durumda değişken içeriği 0b01000001. İkinci dijiti sürmek için,
tmp = (tmp & 0xF0)|(0b00000010);
output_d(tmp);

sadece röleyi serbest bırakmak istediğinizde
tmp = (tmp & 0b10111111);
output_d(tmp);

yazmanız yeterli. Programınızın her yerinde output_d(tmp); olacak.
 
ya kusura bakmayında okadar ugrastım sacımı yoldum gerçekten yapamıyorum kodları siz derleyip verebilirmisiniz zahmet olmazsa çünkü kod yazmayada pic de yeni basladım ödev sadece bu işe ilk adım calışsın yeter ilk aşama için derlryebilirseniz minettar olurum uğraşınız için teşekkürler iyi geceler

-------------------------------------------------------------------------

şimdi tamam ya kimsenin yardım mardım edeceği yok ben bunaldm ya braktım proje de vermicem peki bişi ricaedeyim sıfırdan ayacam bu işe inat ettim öğrenecem de burda bi yol göster bilecek varmı ??
 
Moderatör tarafında düzenlendi:
Arkadaşım, eğer kodlar basic veya protonla yazılmış olsaydı yardım edebilirdim. Ama senin dil bana çok uzak:(
 
..... ödev sadece.....

-----------------------------------------------------

şimdi tamam ya kimsenin yardım mardım edeceği yok ben bunaldm ya braktım proje de vermicem peki bişi ricaedeyim sıfırdan ayacam bu işe inat ettim öğrenecem de burda bi yol göster bilecek varmı ??

daha nasıl bir yardım beklendiğini çözemedim?
yapmanız gerekenler anlatılmış. eğer hazır devreyi istiyorsanız zaman burası uygun değil.

ödevin amacı birşeyler öğrenmek/öğretmek bildiğim kadarıyla.herşeyi hazır olarak dışarıdan alınacaksa halledilecekse onu, ödevi veren kişi de zaten yapabilir.

üzerinde uğraşın, takıldığınız yerlerde yardımcı olunabilir.
 
arkadaşlar bende rf Lcd li termometre var ve fan ekleyeceğim bu fan 20 veya üstünde fan açmasını istiyorum hoca if else dedi ama çalışmadı nasıl yapabilirim.

ilgilenirseniz sevinirim
 
ben PIC16F877 ENTEGRESİ VE PCF8583(SAAT VE TARİH İÇİN ENTEGRE),LM35 ISI SENSÖRÜ İE TARİH SAAT VE SICAKLIĞI Lcd EKRANDA GÖSTERMEK İSTİYORUM..
BUNUNLA İLGİLİ BİR PROGRAMA SAHİBİM AMA BENİM PROGRAMIMDA SICAKLIĞI GAYET İYİ GÖSTERİYOR SICAKLIKTA SORUN YOK.. AMA TARİH VE SAAT SABİT BİR ŞEKİLDE KALIYOR İLERLEMİYOR
MESELA SAAAT 12:10:09 BİR TÜRLÜ 12:10:10 OLMUYOR SABİT KALIYOR BEN MİCROC PRO FOR PİC PROGRAMIYLA YAZILMIŞ BİR PROGRAM...
PROTEUSDA SİMULASYON YAPTIĞIM ZAMAN DEVAMLI SAAT KONUSUNDA SORUN YAŞIYORUM...BEN DEVREMDE KULLANDIĞIM MALZEMELERİ,PROTEUSDA ÇİZİLMİŞ DEVREMİ VE PROGRAMIMI
ATACAĞIM YARDIMCI OLURSANZ ÇOK SEVİNİRİM...BUNU YAPAMAZSAM DERSTEN KALACAĞIM
KULLANDIĞIM MALZEMELE: Materials: RS232 İLETİŞİM KABLOSU,PIC16F877 ENTEGRESİ,LCD 2*16 Ekran,LM35 SICAKLIK SENSÖRÜ,12 volt AC/DC Adaptor,ButtonLAR,
4 pieces 10k resistance,3 pieces 560 resistance,2 pieces 22 Pf capacitor,
5 PARÇA 1 mf KONDANSATÖR,2 PARÇA 100 mf KONDANSATÖR ,3 pARÇA 100 nf KONDANSATÖR,1 PARÇA 25 pf KONDANSATÖR,Max232 ENTERGRESİ,7805 ENTEGRESİ,
1 pARÇA 9 PİNLİ CONNECTOR,1 PARÇA KRYSTAL KONDANSATÖR 25-40 MHZ ARASI,1 PARÇA PERTİNAX,
10K LIK POTANSİYOMETRE(POTANSİYOMETRE İLE 2 MİLİSANİYELİK GECİKTİRME YAPRAK 2 TANE LEDİMİN YANIP SÖNMESİNİ SAĞLIYORUM)


MİCROC PRO FOR PİC C KODUM:

#define uchar unsigned char
// LCD module connections
sbit LCD_RS at RD2_bit;
sbit LCD_EN at RD3_bit;
sbit LCD_D4 at RD4_bit;
sbit LCD_D5 at RD5_bit;
sbit LCD_D6 at RD6_bit;
sbit LCD_D7 at RD7_bit;

sbit LCD_RS_Direction at TRISD2_bit;
sbit LCD_EN_Direction at TRISD3_bit;
sbit LCD_D4_Direction at TRISD4_bit;
sbit LCD_D5_Direction at TRISD5_bit;
sbit LCD_D6_Direction at TRISD6_bit;
sbit LCD_D7_Direction at TRISD7_bit;
// End LCD module connections
//output definitions
#define backlight PORTC.F0
#define sistemled portb.f1
#define outled portc.f2
//buttons definitions
#define btnEnter porte.f2
#define btnEsc porta.f2
#define btnUp porte.f0
#define btnDown porta.f4
#define btnLeft porta.f5
#define btnRight porte.f1
//
uchar seconds = 0;
uchar minutes = 0;
uchar hours = 0;
uchar day = 0;
uchar month = 0;
uchar year = 0;

uchar gorev=0;
// fonksiyon prototipleri
void initial();
void Read_Time();
void Transform_Time();
void Display_Time();
void clockprogramming();
void timetask();
void temperaturetask();
void menufunc();
void sicaklikoku(unsigned char kanal,unsigned char* dizi);
//fonksiyon prototipleri sonu

void main() {
initial();
while(1){
switch (gorev){
case 1: timetask();break;
case 2: temperaturetask();Delay_Ms(250);break;
//case 3: break;
default: ;
}
if(!btnEnter) menufunc();



} // main while

} // void main

void initial(){

PORTA=0;
TRISA=0xff;
ADCON0=0xa0; // Configure AN pins porta.f0,f1 analog;porta.f3 analog; diğerleri dijital
ADCON1=0x85; //
PORTB = 0;
TRISB = 0;
PORTC=0;
TRISC=0X80;
PORTD=0;
TRISD=0;
PORTE=0;
TRISE=7;
I2C1_Init(100000); // initialize I2C communication
UART1_Init(9600); // Initialize UART module at 9600 bps
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
backlight=1;
Lcd_Out(1,1,"merhaba");
sistemled=1;
outled=1;
clockprogramming();
OPTION_REG=0;
INTCON=0X90;
}
//--------------------- Reads time and date information from RTC (PCF8583)
void interrupt(){
if(intcon.intf){
intcon.intf=0;
gorev=1;
sistemled=~sistemled;
/*
Read_Time();
Transform_Time();
Display_Time();
*/
}


}// interrupt
/////////////////////////////
void menufunc(){
gorev=2;
Lcd_Out(1,3,"TEMPERATURE");

}
////////////////////////////
void Read_Time() {

I2C1_Start(); // Issue start signal
I2C1_Wr(0xA0); // Address PCF8583, see PCF8583 datasheet
I2C1_Wr(2); // Start from address 2
I2C1_Start(); // Issue repeated start signal
I2C1_Wr(0xA1); // Address PCF8583 for reading R/W=1

seconds = I2C1_Rd(1); // Read seconds byte
minutes = I2C1_Rd(1); // Read minutes byte
hours = I2C1_Rd(1); // Read hours byte
day = I2C1_Rd(1); // Read year/day byte
month = I2C1_Rd(0); // Read weekday/month byte
I2C1_Stop(); // Issue stop signal

}

//-------------------- Formats date and time
void Transform_Time() {
seconds = ((seconds & 0xF0) >> 4)*10 + (seconds & 0x0F); // Transform seconds
minutes = ((minutes & 0xF0) >> 4)*10 + (minutes & 0x0F); // Transform months
hours = ((hours & 0xF0) >> 4)*10 + (hours & 0x0F); // Transform hours
year = (day & 0xC0) >> 6; // Transform year
day = ((day & 0x30) >> 4)*10 + (day & 0x0F); // Transform day
month = ((month & 0x10) >> 4)*10 + (month & 0x0F); // Transform month
}

//-------------------- Output values to LCD
void Display_Time() {

Lcd_Chr(1, 6, (day / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1, 7, (day % 10) + 48); // Print oness digit of day variable
Lcd_Chr(1, 9, (month / 10) + 48);
Lcd_Chr(1,10, (month % 10) + 48);
Lcd_Chr(1,15, year + 56); // Print year vaiable + 8 (start from year 2008)

Lcd_Chr(2, 6, (hours / 10) + 48);
Lcd_Chr(2, 7, (hours % 10) + 48);
Lcd_Chr(2, 9, (minutes / 10) + 48);
Lcd_Chr(2,10, (minutes % 10) + 48);
Lcd_Chr(2,12, (seconds / 10) + 48);
Lcd_Chr(2,13, (seconds % 10) + 48);
}
/////////////////////////////////////////
void clockprogramming(){

I2C1_Start(); // Issue start signal
I2C1_Wr(0xA0); // Address PCF8583, see PCF8583 datasheet
I2C1_Wr(0); // Start from address 0 (configuration memory location)
I2C1_Wr(0x80); // Write 0x80 to configuration memory location (pause counter...)
I2C1_Wr(0); // Write 0 to cents memory location
I2C1_Wr(0); // Write 0 to seconds memory location
I2C1_Wr(0x30); // Write 0x30 to minutes memory location
I2C1_Wr(0x12); // Write 0x12 to hours memory location
I2C1_Wr(0x24); // Write 0x24 to year/date memory location
I2C1_Wr(0x08); // Write 0x08 to weekday/month memory location
I2C1_Stop(); // Issue stop signal

I2C1_Start(); // Issue start signal
I2C1_Wr(0xA0); // Address PCF8530
I2C1_Wr(0); // Start from address 0
I2C1_Wr(0); // Write 0 to configuration memory location (enable counting)
I2C1_Stop(); // Issue stop signal
} //
//////////

void menufunc(){
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,5,"MENU");
Lcd_Out(2,1,"1: Mod Sel");
}
void timetask(){
Read_Time();
Transform_Time();
Display_Time();
}
////////////////
float adimbuyuklugu=5/1023;
unsigned long temperature=0;
unsigned int sicaklik=0;
unsigned int isi=0;
unsigned char isidegeri[16];
unsigned char setdegeri[16];
unsigned int isideger=0;
unsigned int setdeger=0;
unsigned char offset=20;
//////////////
void temperaturetask(){
unsigned char temp=0;
isideger=setdeger=0;
sicaklikoku(0,isidegeri);
sicaklikoku(1,setdegeri);
if(outled==1)if(isideger<=(setdeger-(unsigned int)offset))outled=0;
if(outled==0) {if(isideger>=setdeger)outled=1;}

Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
Lcd_Out(1,1,"Set : ");Lcd_Out_Cp(setdegeri);
Lcd_Out(2,1,"Temp: ");Lcd_Out_Cp(isidegeri);
}

void sicaklikoku(unsigned char kanal,unsigned char* dizi){
uchar i=0;
sicaklik=ADC_Read(kanal);
for(i=0;i<11;i++){
sicaklik += ADC_Read(kanal);
sicaklik=sicaklik/2;
}

if(kanal==0) {temperature = (long)sicaklik*1000;}
else if(kanal==1){ temperature = (long)sicaklik*100;}
temperature=(temperature/1023)*5;
sicaklik = (unsigned int)temperature;
if(kanal==0)isideger=sicaklik;else setdeger=sicaklik;
// sicaklik = 4999;
isi = sicaklik/1000;
if(isi==0) dizi[0]=32;else dizi[0]=48+isi;

isi = sicaklik-(isi*1000);
isi = isi/100;
if(isi==0){ if(dizi[0]==32)dizi[1]=32;else dizi[1]=48;}
else if(isi>0){dizi[1]=48+isi;}

sicaklik = sicaklik%100;
isi = sicaklik/10;
dizi[2]=48+isi;dizi[3]='.';

isi=sicaklik%10;
dizi[4]=48+isi;dizi[5]=0;

}//
//////////////////////


proteus devrem bu ekte
 

Ekli dosyalar

  • date,clock,and temperature.DSN.zip
    28.3 KB · Görüntüleme: 0

Forum istatistikleri

Konular
129,847
Mesajlar
930,725
Kullanıcılar
452,702
Son üye
hsyn35

Yeni konular

Geri
Üst