MAX6675

Başlatan x-nomek, 08 Temmuz 2014, 17:43:26

x-nomek

Max6675 entegresinden yazılımsal olarak sıcaklık degerini okuyabiliyorum fakat donanimsal spi ile okuyamadım
donanimsal spi ile yapan arkdaşlar varmı ?

ilhan_mkp

Hocam neyin donanimsal spi modülü bu ve biraz kod parçasi olursa mutlaka kullanan vardir.

quarko

CPOL ve CPHA değerleri ile alakalı bir problem olabilir. Bir de MAX6675 in speklerinde belirtilen maximum hızı 4.3 MHz. Donanımsal SPI ile haberleşirken bu hızı geçiyor olabilirsiniz.
"Vicdanın ziyası ulum-u diniyedir. Aklın nuru fünun-u medeniyedir. İkisinin imtizacıyla hakikat tecelli eder."

x-nomek

nNeyin derken piclerde olcak 18f877a serisi kullanacagım

Kabil ATICI

#define CSLO() PORTC &= ~0x01 
#define CSHI() PORTC |=  0x01 

#define C1LO() PORTC &= ~0x02 
#define C1HI() PORTC |=  0x02 

unsigned int raw; //raw bits from max6675 (1/16th degrees) 
float fqdeg,fqdegsm; 
//---------------------------- 
void readmax6675(void){ 
//read max6675 thermocouple preamp     takes 220ms! 
unsigned int dh,dl; 
unsigned int qdeg; //quarter degrees 

  INTR_OFF(); 
  SPCR=0x5B;    //0x5b =0x53 | 0x08 slow spi, clk pol flipped for max6675 
  CSLO();       //conv halt, output bit 0 
  spiout8(0);   //send dummy byte 
  dh=readspi(); //read hi byte 
  spiout8(0);   //send dummy byte 
  dl=readspi(); //read lo byte 
  CSHI();       //conv resume 
  SPCR=0x50;    //fastest spi back on for needle  
  INTR_ON(); 
  
  raw=dh*256 + dl; //raw thermocouple reading 1/16th deg C 
  qdeg=raw >> 2;  //12 bit unsigned integer number (quarter degrees C) 
  fqdeg=qdeg; 
  fqdegsm += 0.1*(fqdeg-fqdegsm); 
  degC=fqdegsm*0.25;  
  degF=degC*1.8 + 32.0;  
}

bu Atmel serisi işlemciler için yapılmış bir program. En azından fikir verebilir. (C ile yazıldığından düşünce yapısı yardımcı olabilir) Tabii ki chip select ucunu mutlaka aktif ederek. (sanırım lojik-0)
Bu durumda SPI MOSI ucu

pic SPI ile uğraşmadım, ATMEL serisi ile asm düzen uğraştım.
Normalde,
spi ile saat frekansı, inen kenar master/slave ve yükselen kenar seçimini yapabiliyorsunuz.
Belirttiğiniz ADC diyebileceğimiz alet sadece veri çıkışı oluyor.
Buna göre SPI giriş ucuna bağlıyoruz demektir. SPI Veri alması için SPI veri registerine veri yüklüyor ve gönderiyoruz. Veris MOSI ucundan gönderilirken  ADC'den veri MISO ucuna gerilir. Veri tamamlandığında (bir bayrakla bildirilir, zaten C kullanıldığında  işi otomatik halleder) veri alınır ve 2. bayt için işlem tekrarlanır.

Sadece bunu kendi işlemciniz için uyarlamanız gerekecek...

İsis 8 öncesi programda pic18f452 için bir örnek var isede spi ile değilde yazılım ile halledilmiş. (Samples klasöründe)
ambar7

x-nomek

Sorunumun bir kısmını halletim ama şimdide seğment dispilaylerde sıcaklık değeri kırpık kırpık geliyor
timer1 kesmesini kullanarak sıcaklık değerini dispilaylara gönderiyorum ama buradaki kırpılmayı nasıl çözerim.

Proteus7.10 kullanıyorum
Linkde Kodu ve proteus dosyasını ekledim

https://yadi.sk/d/YxJUWlzDWSHbC

#include <16f877.h>  
#DEVICE  ICD=TRUE

#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOPUT,NOWRT,NODEBUG,NOCPD

#use delay (clock=20000000)


#byte PORTA = 0x05 
#byte PORTB = 0x06 
#byte PORTC = 0x07 
#byte PORTD = 0x08 
#byte TRISA = 0x85 
#byte TRISB = 0x86 
#byte TRISC = 0x87 
#byte TRISD = 0x88 

#define use_portb_lcd TRUE   

#include <lcd.c>  

const int digit[10]={0x3F,0x06,0x5B,0X4F,0X66,0X6D,0X7D,0X07,0X7F,0X6F};
                //    0  ,  1,   2,  3  ,  4,  5  , 6  ,  7 , 8  ,  9
const int disaktif[9]={0XFF,0XFE,0XFD,0XFB,0XF7};
               //      KAPA, DİS1,DİS2,DİS3,DİS4               
int8  sicaklikbirler=0,sicaklikonlar=0,sicaklikbinler=0,sicaklikyuzler=0;   
int16 sicak1=0;
int16 i;



#int_timer1 // timer kesmesi 
void dispilay()
{
    set_timer1(0);    
    sicaklikbirler =  sicak1        % 10;
    sicaklikonlar  = (sicak1 /10)   % 10;
    sicaklikyuzler = (sicak1 /100)  % 10;
    output_a(disaktif[1]);
    output_c(digit[sicaklikbirler]);
    delay_ms(1);
    output_a(disaktif[2]);
    output_c(digit[sicaklikonlar]);
    delay_ms(1);    
    output_a(disaktif[3]);
    output_c(digit[sicaklikyuzler]);
    delay_ms(1);
    

 
}

 float max6675_oku (void)   // sicaklik okunuyor           
 {  
    output_low(pin_D0);                         
    delay_ms(1) ;            
      for (i=0;i<16;i++)
    { 
      output_high(pin_D1);      
      shift_left(&sicak1,2, input(PIN_D2));
      output_low(pin_D1);   
    } 
     output_high(pin_D0);  
     sicak1=(sicak1>>3);
     sicak1 /= 4;       
     return ((sicak1));
  
 }
 

 

 
void main ( )
{
   setup_psp(PSP_DISABLED);        // PSP birimi devre dışı
   setup_spi(SPI_DISABLED);     // SPI birimi devre dışı
   
      
   setup_timer_2(T2_DISABLED,0,1); // T2 zamanlayıcısı devre dışı
   setup_adc_ports(NO_ANALOGS);    // ANALOG giriş yok
   setup_adc(ADC_OFF);             // ADC birimi devre dışı
   setup_CCP1(CCP_OFF);            // CCP1 birimi devre dışı
   setup_CCP2(CCP_OFF);            // CCP2 birimi devre dışı
   Set_Tris_C(0B00000000);
   Set_Tris_D(0B00001100);
   Set_Tris_A(0B00000000);
   lcd_init();   // LCD hazırlanıyor 
   enable_interrupts(global);
   enable_interrupts(int_timer1);
   setup_timer_1(T1_INTERNAL|T1_DIV_BY_1 );
   set_timer1(0);
 
   while(true) // Sonsuz döngü
   {
   
    max6675_oku(); 
    lcd_gotoxy(1,1);
    printf(lcd_putc, "Temp=%f\r\n",((float)sicak1)); 
    
   }
  
   
}




baran123

Programının ayarlarını bilmiyorum ama proteus işlemleri yavaşlatıyor sen devreyi board da kur ona göre ayar yapasın ama sıkıntı yok gibi zaten 1 milisaniye vermişsin

Kabil ATICI

#7
@x-nomek
Simülasyonda analog özellikli eleman kullanıyorsun.
Direncin üzerine 2 kez tıkla veya direncin üzerinde iken fare sağ tıkla "Edit Properties" açılır menü öğesini seç. Sizinkinde "Model Type" Analog yazacaktır. Bunu dijital olarak değiştirin. "Ok" butonuna tıklayıp işlemi onaylayın. Bu işleti tüm dirençlere uygulayın.

Bu arada MAX6675 ile işlemci arasındaki elemanları silin , burası veri hattı. İşlemci ile MAX6675 aynı gerilimde oldukça bunlara gerek yok. Farklı ise sadece dirençler ekle, kondansatör koyma...

Programın okuma bölümünü kontrol et 2 derece eksik gösteriyor..

İsis klasöründe "Samples" -> "VSM for PIC18" -> "MAX6675 Thermometer" klasörü içinde  MAX6675 ve pic18f452 ile yapılmış bir örnek var. Oradaki okuma ile ilgili bölüm
#include "max6675lib.h"

// MAX6675 initialization. Starts a conversion 
void max6675_init(void)
 { ck_tris = 0;                           // make clock bit as an output pin
   ck_out  = 0;                           // initialize it low
   cs_tris = 0;                           // make chip select as an output pin 
   cs_out  = 1;                           // initialize conversion
   so_tris = 1;                           // make serial output as an input pin
 }

// MAX6675 conversion 
int max6675_read_temp (void)              
 { static char i; 
   static int temp = 0; 
   cs_out = 0;                            // Stop a conversion in progress 
   nop();                                 //  
   for (i=0;i<16;i++)
    { shift_left(temp, so_in);
      ck_out = 1; 
      nop();                                 
      ck_out = 0; 
    } 
   if (temp.2)                           // Thermocouple continuity check. 
      isthcopen = 1;
   else 
      isthcopen = 0;
   cs_out = 1;                            // Initiate a new conversion  
   return (temp>>3); 
 }


shift_left(temp, so_in); öğesi  saat darbelerinden önce yer alıyor.
ambar7

x-nomek

@ambar7
Yardımların için çok Teşşekkür ederim .

Alıntı YapBu arada MAX6675 ile işlemci arasındaki elemanları silin , burası veri hattı. İşlemci ile MAX6675 aynı gerilimde oldukça bunlara gerek yok. Farklı ise sadece dirençler ekle, kondansatör koyma...

Bende bahsettiğiniz isisin sample klasöründeki devredeki  şekilde yaptım onlar direnç kondansatör koyduğu için eklemiştim gerek yoksa çıkartırım.
"max6675lib.h" buradaki nop();  ları tam anlayamadım araştırdım . no operation diye birşey bunu eklememe gerek varmidir ?

Alıntı Yapshift_left(temp, so_in); öğesi  saat darbelerinden önce yer alıyor.
Darbelerin yerlerini bilerek değiştiriyorum merak dan dolayı acaba nasıl ne sonuç oluyor farkları görmek için :)

Alıntı YapSimülasyonda analog özellikli eleman kullanıyorsun.

Dirençlerin hepsini dijital yaptım Fakat sorunum aynı yine çözemedim.
Peki bilgi amaçlı soruyorum Simülasyonda  da dijital veya analog yapmamızın ne gibi faydası oluyor Ne tür hatalarla karşılaşabiliriz ?

Lakin kesmenin içinde sıcaklık okumayı yapıp normal programın akışında dispiley lere değeri yazdırmam da sorun yok ama tersinde kesmenin için de dispileyler sıcaklık değerini yazdırmam da sorun oluyor :(

@baranekrem9
Alıntı YapProgramının ayarlarını bilmiyorum ama proteus işlemleri yavaşlatıyor sen devreyi board da kur ona göre ayar yapasın ama sıkıntı yok gibi zaten 1 milisaniye vermişsin

Bunuda deneyeceğim.

Kabil ATICI

nop(); asm komutunun C'de fonksiyonu. 1 tck bekleme veya gecikme için. C'de yazanlar genellikle delay() fonksiyonunu kullanıyor. nop(); çok kısa süreli delay diyelim.

Analog diyelim ki opamp ile simülasyon yapıyorsun, o zaman analog kullanman gerekir, isis bunu son noktasına kadar hesap kitap işini yapıyor(direnç modeline göre). Dijital de ise olay belli, pull up olarak bağlanmışsa bağlandığı noktayı Vcc'ye çekmek veya bir led'e seri bağlı ise sadece LED' ışık vermesini sağlamak ve yanmasını önleme. Bu durumda isis fazla hesap kitaba girmeden konuyu kısa yoldan hallediyor.

Yani analog ile dijital arasındaki fark isis'in hesaplama durumu.

Sanırım örnek klasörlerimizde dosya farklı. Çünkü benim örnekte o direnç ve kondansatörler yok  Sizin isis dosyasındakilerin tümünü kaldırdım. Direnç olarak sade reset ucundaki kaldı. Normal çalıştı.  (Tüm dirençlerin dijital olsun)

Sıcaklık gösterimini kesme dışında ,Main fonksiyonu içinde yapman gerekir. Kesme süren uzunsa  ekran gösteriminde gecikme yapabilir.  Bu nedenle LED ekran gösterimini ya başka bir timer'a devret yana Main  içinde yap...
ambar7

x-nomek

Sende ekranda geçikme yaptımı peki ?