rainalert
Üye
- Katılım
- 20 Eki 2009
- Mesajlar
- 4
- Puanları
- 1
Eklerde 433Mhz RF verici-alıcı ile tasarlanmış bir kablosuz termometre örnek devresi mevcut. PIC olarak verici tarafında PIC16F688 alıcı tarafında PIC16F877 kullanılmıştır. Veri iletişim kısmında PIC'lerin UART özelliği kullanılmıştır. RF çalışması yapacak arkadaşlar için fikir vereceğini umuyorum. Hex kodlar 9 bit çözünürlüklü DS1620 sıcaklık sensörüne göre derlenmiştir. Eklerde şemayı, isis dosyasını, hex kodları ve MikroC kaynak kodlarını bulabilirsiniz.
Alıcı taraf - 16F877
Verici taraf-16F688
Dosya, Dosya Paylaşım Sitesinden Silindiği İçin Konu Çöpe Taşınmıştır.
Alıcı taraf - 16F877
Kod:
#define DIGIT_GECIKMESI 1000 //herbir digitin ekranda bekletilme süresi (us olarak)
unsigned short d1,d2,d3,d4;
char text[10]="-1.0";
char tmp,pre_tmp;
char receive_flag,status_flag;
float sicaklik;
unsigned char count;
//7Segment displaye rakam yazılması
void ss_rakam_yaz(unsigned short sayi,unsigned short pos,unsigned short flag)
{
unsigned short i;
//PORTD kapatılıyor. A,B,C,D,E,F,G,DP
PORTD=0;
if (pos==1)
{
PORTB=0b00001110;
}
else if (pos==2)
{
PORTB=0b00001101;
}
else if (pos==3)
{
PORTB=0b00001011;
}
else if (pos==4)
{
PORTB=0b00000111;
}
if (sayi==0) i=0x3F;
else if (sayi==1) i=0x06;
else if (sayi==2) i=0x5B;
else if (sayi==3) i=0X4F;
else if (sayi==4) i=0X66;
else if (sayi==5) i=0X6D;
else if (sayi==6) i=0X7D;
else if (sayi==7) i=0X07;
else if (sayi==8) i=0X7F;
else if (sayi==9) i=0X6F;
else if (sayi==10) i=0x40;
else if (sayi==11) i=0x00;
else if (sayi==12) i=0x79;
//Rakamdan sonra noktada konuluyor
if (flag==1) i+=0x80;
PORTD=i;
Delay_us(DIGIT_GECIKMESI);
//PORTB nin ortak katotları kapatılıyor.
PORTB=0b00001111;
//PORTD kapatılıyor
PORTD=0;
}
//7Segment displaye sayı yazılması
void ss_sayi_yaz(float sayi,unsigned tekrar)
{
unsigned short i;
unsigned short flag;
//Sayiya bağlı olarak digitler hesaplanıyor
if (sayi<10 && sayi>0)
{
d1=11;
d2=11;
d3=floor(sayi);
d4=sayi*10.0-floor(sayi)*10.0;
flag=3;
}
else if (sayi>=10 && sayi<100)
{
d1=11;
d2=floor(sayi/10.0);
d3=floor(sayi)-d2*10;
d4=sayi*10.0-floor(sayi)*10.0;
flag=3;
}
else if (sayi>=100 && sayi<1000)
{
d1=floor(sayi/100.0);
d2=floor((sayi-floor(sayi/100.0)*100)/10.0);
d3=floor(sayi-floor(sayi/10.0)*10);
d4=sayi*10.0-floor(sayi)*10.0;
flag=3;
}
else if (sayi>=1000 && sayi<10000)
{
d1=floor(sayi/1000.0);
d2=floor((sayi-floor(sayi/1000.0)*1000)/100.0);
d3=floor((sayi-floor(sayi/100.0)*100)/10.0);
d4=sayi-floor(sayi/10.0)*10.0;
flag=0;
}
else if (sayi<0 && sayi>-10)
{
d1=11;
d2=10;
d3=fabs(ceil(sayi));
d4=fabs(sayi*10.0-ceil(sayi)*10.0);
flag=3;
}
else if (sayi<=-10 && sayi>-100)
{
d1=10;
d2=fabs(ceil(sayi/10.0));
d3=fabs(ceil(sayi))-d2*10;
d4=fabs(sayi*10.0-ceil(sayi)*10.0);
flag=3;
}
else if (sayi==0)
{
d1=11;
d2=11;
d3=0;
d4=0;
flag=3;
}
else
{
d1=11;
d2=11;
d3=11;
d4=12;
flag=0;
}
i=tekrar;
while(i!=0)
{
ss_rakam_yaz(d1,1,0);
ss_rakam_yaz(d2,2,0);
if (flag==3) ss_rakam_yaz(d3,3,1);
else ss_rakam_yaz(d3,3,0);
ss_rakam_yaz(d4,4,0);
i--;
}
}
void interrupt() //RF bilgi geldiğinde bu interrupt devreye giriyor.
{
INTCON=0;
tmp=UART1_Read();
if (pre_tmp==0x24 && tmp==0x45 && receive_flag==1)
{
text[count]=0;
receive_flag=0;
status_flag=1;
}
else if (pre_tmp==0x24 && tmp==0x42 && receive_flag==0)
{
receive_flag=1;
status_flag=0;
count=0;
}
else if (receive_flag==1)
{
text[count]=tmp;
count++;
status_flag=0;
}
pre_tmp=tmp;
INTCON=0b11000000;
}
void main() {
INTCON=0b11000000; // Peripheral ve unmaskked interruptlar açılıyor. Böylece data geldiğinde işlemci diğer işlemleri bırakıp gelen rf datayı alacak.
PIE1=0b00100000; //Diğer bir interrupt ayarlaması
ADCON1=0b00000111; //ADC Devre dışı
CCP1CON=0; //Komparatör kapatılıyor
TRISD=0; //D portu çıkış olarak ayarlanıyor
TRISB=0; //B portu çıkış olarak ayarlanıyor
Delay_ms(100);
UART1_Init(1200); //1200baudrate olarak ayarlanıyor. Kullandığım noname rf modülde problem çıkarmadı.
Delay_ms(100); //Stabilizasyon
pre_tmp=0;
receive_flag=0;
status=0;
sicaklik=10000;
while(1)
{
if (status_flag==1) sicaklik=atof(text); //Text değeri sicaklik çevrimi için uygunsa text değerini sıcaklığa çevir
ss_sayi_yaz(sicaklik,1); //Sıcaklık değerini 4 digit 7 segment displaye yazan alt program çağrılıyor
}
}
Verici taraf-16F688
Kod:
const unsigned short TEMP_RESOLUTION = 9;
char *text = "000.0000";
unsigned temp;
void get_temp() //Bu fonksiyon sıcaklık değerini DS18B20 üzerinde one-wire yöneti ile alarak değeri text olarak *text değeri içine atar
{
const unsigned short RES_SHIFT = TEMP_RESOLUTION - 8;
char temp_whole;
unsigned int temp_fraction;
Ow_Reset(&PORTC, 0);
Ow_Write(&PORTC, 0, 0xCC);
Ow_Write(&PORTC, 0, 0x44);
Delay_us(120);
Ow_Reset(&PORTC, 0);
Ow_Write(&PORTC, 0, 0xCC);
Ow_Write(&PORTC, 0, 0xBE);
Delay_ms(500);
temp = Ow_Read(&PORTC, 0);
temp = (Ow_Read(&PORTC, 0) << 8) + temp;
if (temp & 0x8000) {
text[0] = '-';
temp = ~temp + 1;
}
temp_whole = temp >> RES_SHIFT ;
if (temp_whole/100)
text[0] = temp_whole/100 + 48;
else
text[0] = '0';
text[1] = (temp_whole/10)%10 + 48;
text[2] = temp_whole%10 + 48;
temp_fraction = temp << (4-RES_SHIFT);
temp_fraction &= 0x000F;
temp_fraction *= 625;
text[4] = temp_fraction/1000 + 48;
text[5] = (temp_fraction/100)%10 + 48;
text[6] = (temp_fraction/10)%10 + 48;
text[7] = temp_fraction%10 + 48;
text[8]=0;
}
void preamble() //Bir aradan sonra rf modül tarafı ile rf alıcı tarafı arasındaki senkron kayboluyor. Preamble işi bu senkronu tekrar sağlıyor. Eğer gönderim sırasında bu programda olduğu gibi ara verildiğinde senkron kayboluyor.
{
//Preamble - Senkron sağlanamazsa 0x55 gönderim sayısı arttırılabilir.
UART1_Write(0x55);
UART1_Write(0x55);
UART1_Write(0x55);
UART1_Write(0x55);
UART1_Write(0x55);
//Senkron
UART1_Write(0x00);
UART1_Write(0x00);
UART1_Write(0x00);
UART1_Write(0x00);
UART1_Write(0x00);
UART1_Write(0xff);
UART1_Write(0xff);
UART1_Write(0xff);
UART1_Write(0xff);
UART1_Write(0xff);
}
void main() {
INTCON=0; // Interruptlar devre dışı
ANSEL=0; //ADC Devre dışı
CMCON0=0b00000111; //Komparatör devre dışı
TRISC=0b00000001;
Delay_ms(100);
get_temp();
UART1_Init(1200);
Delay_ms(100);
preamble();
while(1)
{
get_temp();
preamble();
UART1_Write_Text("$B"); //Başlangıç textini gönder
UART1_Write_Text(text); //Sıcaklığı gönder
UART1_Write_Text("$E"); //Bitiş textini gönder
RC1_bit=1; //Ledi kısa bir süre aç ve kapa
Delay_ms(100);
RC1_bit=0;
Delay_ms(1000); //Veriyi 10sn bir gönder.Esas amacım buraya pic'in sleep özelliğini koyup güç tasarrufu sağlamtı. Programın genel yapısının karışmaması için sadece Delay_ms fonksiyonu ile yetindim.
}
}
Dosya, Dosya Paylaşım Sitesinden Silindiği İçin Konu Çöpe Taşınmıştır.