Bu çalışmamdaki amacım iki ayrı devre oluşturarak bir kablosuz alıcı verici devresi yapmak. Bunun için daha önceki çalışmalarımda yaptığım motor kontrol devresini yapacağım. Yani alıcı kısımın da benim motorum olacak ve onu sürecek olan devre verici kısmında ise benim analog potuma bağlı olan ayrı bir devre. Yani analog pot hızı kontrol edecek.
Kullanacağım alıcı verici çifti;
http://www.direnc.net/433MHZ-RF-ALICI-VERICI-KRISTALLI-TAKIM,PR-1580.html |
Aslında alıcı ve verici sanki iki devre arasında bir kablo varmış gibi davranır alıcı ve verici modüllerinin yerine bir kablo ile bağlasanız da aynı işi yapar. Ama amacımız kablosuz iletişim olduğunda buna gerek yok.
Ve devre şemam;
ve donanım birimi olarak da ADC ve EUSART donanım birimleri kullanıldı.
MikroC programında yazılım yazılırken EUSART donanım biriminin hazır kod kullanılmadı onun yerine kendim yeninden inşa ettim herşeyi.
Eusart modulu ASCII karaketer alır ve gönderir ve bu yüznden stringlerle iş yaparsınız bu önemli bir nokta. Örneğin; Siz vericinizden 255 sayısını göndereceksiniz diyelim bunu stringe çevirmelisiz yani "255" bunun gibi yoksa 255 gönderilmez alıcı doğru veri almaz. Alıcı da ise alına bu string üzerinde bir işlem yapmak isterseniz eğer bu "255" stringini decimal sayıya çevirmelisiz. Yani vericiniz "255"
datasını gönderdi ama bu string siz alıcı kısmında alınan bu data üzerine +10 sayısını ilave etmek istiyorsunuz direk "255"+10 diyemezsiniz yanlış bu. Bun yerine "255" alınan bu stringi decimal sayıya çevirip öyle eklersiniz 255+10 gibi.
Bende bu çalışmamda bunun gibi yaptım verici kısmında potdan aldığı değeri yani decimal sayıyı stringe çevirip öyle alıcıya gönderdim orada onu decimal sayıya çevirip öyle işlem yaptım.
/* UART MODULU YAPILANDIRILMASI */
TXSTA=0; //ILK ANDA SIFIR
RCSTA=0;
SPBRG=103; //16 MHZ İÇİN 9600 BİT/SN hızında baundrate
TXSTA=0X26;
RCSTA=0X90;
INTCON=0XC0;
PIE1.RCIE=1; //RSR DEN RCREG VERI AKTARILDIĞINDA KESME OLUŞSUN
Yukarıdaki kodda, Euart donanım birimin yapılandırılması gösterilmiştir. Alıcı kısmında 16mhz kristal kullanılıp SPBRG register içine 103 yazılarak 9600 baud da ayarlanmıştır. Verici kısmında 20Mhz kristal kullanılıp SPBRG=129 yazılmıştır önemli olan nokta her ikisinde de 9600 baud olmalıdır. Yani saniye 9600 bit gönderilir ve alınır.
void interrupt(){
if(PIR1.RCIF){
if(RCSTA.FERR || RCSTA.OERR){// Eğer karakter almada FIFO register ile sorun oluşursa
RCSTA.CREN=0; // normal duruma getirmek için bunları yap
delay_us(1);
RCSTA.CREN=0;
PIR1.RCIF=0;
}
RxBuffer=RCREG; // Vericinden alınan karakteri kopyala
control=1;
PIR1.RCIF=0;
}
}
Yukarıda olan kesme kodunda eğer veri yani string geldiyse kesme olur veri ilk stringi RxBuffer içine yazılır.
Alıcı kısmın MikroC kodu;
#define SIFRE_1 0x41
#define SIFRE_2 0x42
sbit LCD_RS at RB1_bit;
sbit LCD_EN at RB2_bit;
sbit LCD_D7 at RD3_bit;
sbit LCD_D6 at RD2_bit;
sbit LCD_D5 at RD1_bit;
sbit LCD_D4 at RD0_bit;
sbit LCD_RS_Direction at TRISB1_bit;
sbit LCD_EN_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISD3_bit;
sbit LCD_D6_Direction at TRISD2_bit;
sbit LCD_D5_Direction at TRISD1_bit;
sbit LCD_D4_Direction at TRISD0_bit;
unsigned char RxBuffer,control=0;
void interrupt(){
if(PIR1.RCIF){
if(RCSTA.FERR || RCSTA.OERR){// Eğer karakter almada FIFO register ile sorun oluşursa
RCSTA.CREN=0; // normal duruma getirmek için bunları yap
delay_us(1);
RCSTA.CREN=0;
PIR1.RCIF=0;
}
RxBuffer=RCREG; // Vericinden alınan karakteri kopyala
control=1;
PIR1.RCIF=0;
}
}
void init(){
/* UART MODULU YAPILANDIRILMASI */
TXSTA=0; //ILK ANDA SIFIR
RCSTA=0;
SPBRG=103; //16 MHZ İÇİN 9600 BİT/SN hızında baundrate
TXSTA=0X26;
RCSTA=0X90;
INTCON=0XC0;
PIE1.RCIE=1; //RSR DEN RCREG VERI AKTARILDIĞINDA KESME OLUŞSUN
// LCD AYARLARI//
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
//ADC AYARLARI//
ADCON1 |=0X0F;
CMCON |=7;
/* pwm için 4.975Hzlik sinyal üretilip sinyalin 1 kalma oranıyla ADC ile ayarlanıp
motoru hızlandırıp veya yaşlatabiliriz */
TRISC.RC2=0; // FULL-BRIDGE CIKISLARI ICIN AYARLAMALAR
PORTC.RC2=0;
TRISD.RD5=0;
TRISD.RD6=0;
TRISD.RD7=0;
PORTD.RD5=0;
TRISD.RD6=0;
TRISD.RD7=0;
CCP1CON=0b01001100; // Full Bridge Forward; P1A, P1C active-high; P1B, P1D active-high
CCPR1L=0X00; // Start with zero Duty Cycle
// PWM Period = 4 x Tosc x (PR2 + 1) x TMR2 Prescale Value
// Tosc = 1/16 Mhz = 0.0000000625
// PWM Period = 4 x 0.0000000625 x 201 x 4 = 0.000201
// PWM Frequency = 1/PWM Period = 1/0.000201 = 4.975 kHz
T2CON=0b00000101; // Postscale: 1:1, Timer2=On, Prescale = 1:4
PR2=200; // Frequency: 4.975 kHz
TMR2=0; // Start with zero Counter
}
char KarakterAl();
void GonderKarakter(char harf);
void StringYaz(char *str);
unsigned short RF_Read();
char strtobyte(char *str);
char verim[]=" ";
char ham_verim[2];
char datam[2];
unsigned short say=0,i=0;
unsigned int duty_cycle;
char kelime1[4];
char toplam;
void main() {
init();
while(1){
say=0;
do{
verim[say]=RF_Read();
say++;
}while(say<3);
ham_verim[i]=strtobyte(&verim[0]);
i++;
if(i>=3){
Lcd_Cmd(_LCD_CLEAR); // Clear display
if(ham_verim[0]==3){
CCPR1L = 0;
duty_cycle=0;
lcd_out(1,1," MOTOR DURDU ! ");
}else{
if(ham_verim[0]==2){
while(!(P1M1_BIT==0&&P1M0_BIT==1)){
Lcd_Cmd(_LCD_CLEAR);
P1M1_BIT=0; // MOTOR'A SAGA CEVİRDI
P1M0_BIT=1;
}
lcd_out(2,1," SAGA % ");
CCPR1L=ham_verim[2];
duty_cycle=(ham_verim[2]/250.0) * 100.0;
bytetostr(duty_cycle,kelime1);
lcd_out(2,9,kelime1);
}
if(ham_verim[0]==1){
while(!(P1M1_BIT==1&&P1M0_BIT==1)){
Lcd_Cmd(_LCD_CLEAR);
P1M1_BIT=1; // MOTOR'A SAGA CEVİRDI
P1M0_BIT=1;
}
lcd_out(2,1," SOLA % ");
CCPR1L=ham_verim[1];
duty_cycle=(ham_verim[1]/250.0) * 100.0;
bytetostr(duty_cycle,kelime1);
lcd_out(2,9,kelime1);
}
}
i=0;
}
}
}
unsigned short RF_Read(){ // Karşı tarafatan karakter almaya başla.
char tmp,i,say=0;i=0;
do{
tmp=KarakterAl();
switch(i){
case 0: if(tmp==SIFRE_1){ datam[0]=tmp;i++;} break;
case 1: if(tmp==SIFRE_2){ datam[1]=tmp;i++;}else i=0; break;
case 2: datam[2]=tmp;i++;break; // asıl karakterim
default:break;
}
}while(i<3);
return tmp;
}
void StringYaz(char *str){
char i=0;
while(*(str+i)!=0){ // 0\ işareti geldiğindeçıkar bu kelimeden
GonderKarakter(*(str+i)); // string içindeki karakterleri tek tek gönder
i++;
}
}
void GonderKarakter(char harf){
if(!(TXSTA.TXEN)) TXSTA.TXEN=1; //gönderme yetkisi verildimi ?
while(!(PIR1.TXIF)); PIR1.TXIF=1; // eğer TXREG deki veri TSR'ye gönderildimi.
TXREG=harf; // gönderildiyse yeni karakter yükle.
}
char KarakterAl(){
while(!control);
control=0;
return RxBuffer;
}
char strtobyte(char *str){ // Vericiden alınan string tipinde karakterleri byte çevirme. Eğer çevirme
//yapılmaz ise üzerinden işlemler yapamayız.
char S,onlar,birler,sayi,yuzler;
for(S=0;S<3;S++){
if(*(str+S)==0x20) *(str+S)=0x30; //bOŞLUĞU SIFIRA ÇEVİRME
}
yuzler=( *(str+0)-48)*100;
onlar=( *(str+1)-48)*10;
birler=( *(str+2)-48);
sayi=yuzler+onlar+birler;
if(sayi>255) sayi=255; // bir byte 255 değerini tutbilir bunu aşmasın diye sınırladık.
return sayi;
}
Verici kısmın MikroC kodu;
#define SIFRE_1 0x41
#define SIFRE_2 0x42
void init(){
/* ADC AYARLARI */
ADCON0=0b00000011;
ADCON1=0b00001110;
TXSTA=0; //ILK ANDA SIFIR
RCSTA=0;
SPBRG=129; //16 MHZ İÇİN 9600 BİT/SN hızında baundrate
TXSTA=0X26;
RCSTA=0X90;
TRISB.RB6=0;
TRISB.RB7=0;
TRISB.RB5=0;
PORTB.RB6=0;
PORTB.RB7=0;
PORTB.RB5=1;
}
void data_gonder(char *veri);
void GonderKarakter(char harf);
void StringYaz(char *str);
unsigned int x_axis_ham; // analogdan alınan sinyal
unsigned char x_axis;
char ham_veri[3]; // 3 bytelık verileri tutsun diye biz dizi oluşturuldu.
void main() {
init();
while(1){
x_axis_ham=ADC_read(0);
if ((x_axis_ham>=501) & (x_axis_ham<=529)){ //EĞER ANALOG POT TAM ORTADAYSA
PORTB.RB6=0;
PORTB.RB7=0;
ham_veri[0]=3; /* MOTOR DURDUR BILGISI*/
ham_veri[1]=0;
ham_veri[2]=0;
data_gonder(&ham_veri[0]);
}else{
if (x_axis_ham<500){
PORTB.RB6=1; /* SOLA DONECEK SINYALİ*/
PORTB.RB7=0;
while(x_axis_ham<=500){
x_axis_ham=ADC_read(0);
x_axis =(500-x_axis_ham)/2 ;
ham_veri[0]=1; /*P1M1_BIT=1, P1M0_BIT=1; sola karşı taraf için*/
ham_veri[1]=x_axis;
ham_veri[2]=0;
data_gonder(&ham_veri[0]);
}
}
if (x_axis_ham>530){
PORTB.RB6=0; /* SAGA DONECEK SINYALİ*/
PORTB.RB7=1;
while(x_axis_ham>530){
x_axis_ham=ADC_read(0);
x_axis=(x_axis_ham-530)/2;
ham_veri[0]=2; /*P1M1_BIT=0, P1M0_BIT=1; saga*/
ham_veri[1]=0;
ham_veri[2]=x_axis;
data_gonder(&ham_veri[0]);
}
}
}
}
}
void data_gonder(char *veri){ //ham_veri deki değeleri gönderir
char say,kelime[4];
say=0;
delay_ms(300);
do{ //0 1 2
bytetostr(*(veri+say),kelime);// kelime ( _ _ _)
StringYaz(&kelime[0]);
say++;
}while(say<3);
}
void StringYaz(char *str){
char i=0;
while(*(str+i)!=0){ // 0\ işareti geldiğindeçıkar bu kelimeden
GonderKarakter(SIFRE_1);// starT1 byte
GonderKarakter(SIFRE_2);// starT2 byte //0 1 2
GonderKarakter(*(str+i)); // string içindeki karakterleri tek tek gönder
i++;
}
}
void GonderKarakter(char harf){
if(!(TXSTA.TXEN)) TXSTA.TXEN=1; //gönderme yetkisi verildimi ?
while(!(PIR1.TXIF)); PIR1.TXIF=1; // eğer TXREG deki veri TSR'ye gönderildimi.
TXREG=harf; // gönderildiyse yeni karakter yükle.
}
Kaynaklar
1) Altaş yayıncılık Pıc Programlama Teknikleri ve PIC16F877A
2) Altaş yayıncılık MıkroC ile PIC 18f4550 Programlama
Hiç yorum yok:
Yorum Gönder