MSP430 İLE SAAT YAPIMI

Başlatan krhnFRDE, 10 Mayıs 2012, 12:59:50

krhnFRDE

MSP430 ile yapmam gereken proje konum:4 adet 7 parçalı göstergede saat bilgisi göstermek. Dahili TMR modülü kullanılarak..
diğer başlıklarıda inceledim ama sadece saat gösteren asm kodunu ve devre şemasını bulamadım.yardımlarınızı bekliyorum.çok acil.. :(

ayhan_eee

Basic timer kullanarak bir saniyelik kesme elde edip kolayca yapılır.Devre olarak herhangi 4 segmentli devre kullanabilirsiniz.Sadece kendinize göre düzenleyeceksiniz.Basic timer size ayarları düzgün yapılırsa 1 saniyelik kesme verecektir.Gerisi saymak olur.Belli süre takip edip geri kalma durumuna göre geri kalmayı hesaplayıp optimize edersiniz.Ben C ile yazmıştım o yüzden asm kodum yok

burak ozturk

hocam peki 2553 için iki ayrı timer ı iki ayrı saat kaynagından besleyebiliyormuyuz ? şöyleki ;

    TA0CTL = TASSEL_2 + MC_1;
  TA0CCTL0 = CCIE; //TMR INTERRUPT I ACIK
  TA0CCR0 = 5000-1;//5000E KADAR SAYACAK.
  
  TA1CTL = TASSEL_1 + MC_1;
  TA1CCTL0 = CCIE; //TMR INTERRUPT I ACIK
  TA1CCR0 = 32768-1;//32767 YE KADAR SAYACAK


yani timer 1 le aclk 32768 lik kristal ile 1mhz lik sinyal elde etmeye çalışsam, diger timer la da smclk ile tarama yapabilme imkanım var mıdır ?
happy coding.

fatihinanc

Alıntı yapılan: burak ozturk - 25 Kasım 2012, 23:13:39
hocam peki 2553 için iki ayrı timer ı iki ayrı saat kaynagından besleyebiliyormuyuz ? şöyleki ;

yani timer 1 le aclk 32768 lik kristal ile 1mhz lik sinyal elde etmeye çalışsam, diger timer la da smclk ile tarama yapabilme imkanım var mıdır ?

Evet. Timer ları bu şekilde kullanabilmek mümkün.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

burak ozturk

#4
hocam şu işi bir türlü beceremedim timer konusunda kafam hepten dagıldı.şöyleki ;

#include "io430.h"

const unsigned char segment[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};  // Seven segment sayıları
unsigned int sayi=0,i=0;


void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  
  BCSCTL1 = CALBC1_16MHZ;
  DCOCTL  = CALDCO_16MHZ;

  for(unsigned int i = 65000;i>0;i--);

  P1DIR = 0xFF; //port çıkışı
  P2DIR = 0xFF; //seçme pinleri
  //P2REN = 0X00;
  P2OUT = 0x00;
  P1OUT = segment[1];
  

  
  TA1CTL = MC_1 + TASSEL_2 ;
  TA1CCR0 =  50000;
  TA1CCTL0 = CCIE;
  
  TA0CTL = MC_1 + TASSEL_1;
  TA0CCR0 = 1;
  TA0CCTL0 = CCIE;
  

 __bis_SR_register(GIE);
  
for(;;){}
       
  
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void TA1_A0_ISR(void)
{
    i++;
    if(i==1)
    {
        P2OUT=0;                     // Önce tüm ledler kapanıyor
        P1OUT=segment[sayi/1000];    // Sonra bilgi gönderiliyor
        P2OUT=0x01;                  // Sonra segment açılıyor, böylelikle netlik sağlanıp, flu görüntü yok ediliyor.
    }
    else if(i==2)
    {
        P2OUT=0;
        P1OUT=segment[(sayi%1000)/100];
        P2OUT=0x02;
    }
    else if(i==3)
    {
        P2OUT=0;
        P1OUT=segment[(sayi%100)/10];
        P2OUT=0x04;
    }
    else if(i==4)
    {
        P2OUT=0;
        P1OUT=segment[(sayi%10)];
        P2OUT=0x08;
        i=0;
    }
    

    
}
    
    #pragma vector=TIMER0_A0_VECTOR
__interrupt void TA0_A0_ISR(void)
{
   
   P2OUT ^= BIT5;
   sayi++;
   //return sayi;
   
   
}
    
    
   


    hocam gördügünüz gibi ACLK ile kullandıgım timer 0 ı bir saydırsam dahi dura dura saydirabiliyorum , programda delay yok , timer larin birbirini sakatlamaması gerekiyor ancak muhtemel registerlar ile ilgili bir hata yapıyorum.bu da videosu ;

http://www.youtube.com/watch?v=7r_3t8x8iVY#

hocam dedigim gibi tmr ile kafam iyice karışmış durumda ,şimdi datasheet derki ;

Two 16-Bit Timer_A With Three Capture/Compare Registers

benim timer larim timer_a0 ve timer_a1 ancak timer şemasına bakınca tek saat kaynagıyla kullanabiliyorum hissine kapıldım;



ancak denedigimde gordumki farklı saat kaynaklarından kullanıyorum fakat adam gibi saydıramıyorum bu seferde hocam timer a ccr degerleri TA1CCR0 , TA0CCR0 şeklinde mi kullanılıyor?

açıkcası aclk ısrarım 32768 lik kristalden hassas zaman almak içindi  korkarım ds1302 ye tekrar dan merhaba demek zorunda kalacagım :)
   
   
happy coding.

fatihinanc

Selamlar,

Kodda birkaç yerde problem var gibi.

  TA1CTL = MC_1 + TASSEL_2 ;
  TA1CCR0 =  50000;
  TA1CCTL0 = CCIE;
  
  TA0CTL = MC_1 + TASSEL_1;
  TA0CCR0 = 1;
  TA0CCTL0 = CCIE;


Eğer sorunuzu yanlış anlamadıysam burada TA0 ı 1 saniye için TA1 i de segmentleri sürmek için kullanmışsınız. TA0 ile tam olarak 1 saniye saydırabilmeniz için TA0CCR0 içerisine 32768-1 yüklemeniz gerekiyor.

Bir de işlemciyi 16MHZ de çalıştırmaya aslında pek gerek yok. 1MHZ de TA1 periyodunu 5ms yapsanız yeterlidir.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

burak ozturk

#6
hocam dediginiz gibi TA0 ı saniye, TA1 segment surucu olarak kullandım.16 mhz le , TA0CCR0 içerisine 1 degerini video da gösterebilmek için yükledim .TA0CCR0 a 32768-1 yükledigimde saymıyor sanıyordum fakat 1 degerini verdigimde dahi dura dura ve aynı zamanda artar şekilde saymıyor. sanki arada pause var mış ta dura dura yüklüyormuş gibi.
happy coding.

fatihinanc

Şu kodu bir dener misiniz ?

//LaunchPad Üzerindeki TXD ve RXD Jumplerlarını Çıkarınız

#include "msp430.h"

#define   SEGMENT0   BIT0       // P2.0
#define   SEGMENT1   BIT1       // P2.1
#define   SEGMENT2   BIT2       // P2.2
#define   SEGMENT3   BIT3       // P2.3

const unsigned char segment[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};  
unsigned int sayi=0,i=0;

void segment_yaz(unsigned char, char);

void main( void )
{
  WDTCTL = WDTPW + WDTHOLD;
  
  BCSCTL1 = CALBC1_1MHZ;
  DCOCTL  = CALDCO_1MHZ;
  __delay_cycles(1000000);

  P1DIR = 0xFF;                      // P1 Tum Pinler Çikis
  P2DIR = BIT0 + BIT1 + BIT2 + BIT3; // Segment Seçme Pinleri
  
  P1OUT = 0x00;
  P2OUT = 0x00;
  
 // SMCLK = 1MHz;
  TA0CTL   = MC_1 + TASSEL_2;
  TA0CCR0  = 5000 - 1;
  TA0CCTL0 = CCIE;
  
 // ACLK = 32.768 kHz
  TA1CTL   = MC_1 + TASSEL_1;
  TA1CCR0  = 32768 - 1;
  TA1CCTL0 = CCIE;
  
  __bis_SR_register(LPM1_bits + GIE);
}

void segment_yaz(unsigned char sayi_f,char seg)
{
  P2OUT = 0;
  P1OUT = sayi_f;
  P2OUT = seg;  
}

#pragma vector=TIMER1_A0_VECTOR
__interrupt void TA1_A0_ISR(void)
{
  sayi++;

  if(sayi > 9999)            
    sayi=0;
}
  
#pragma vector=TIMER0_A0_VECTOR
__interrupt void TA0_A0_ISR(void)
{
  i++;
  
  switch(i)
  {
  case 1 : segment_yaz( segment[sayi/1000],    SEGMENT0);      break;
  case 2 : segment_yaz((segment[sayi/100 %10]),SEGMENT1);      break;
  case 3 : segment_yaz( segment[sayi/10  %10], SEGMENT2);      break;
  case 4 : segment_yaz( segment[sayi%10],      SEGMENT3); i=0; break;
  } 
}
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

burak ozturk

Selamlar hocam ;

hocam TA1CCR0 = 32768 - 1 iken yine saymıyor gozukuyor(cok yavaş sayıyor hemen hemen 5 dakikada bir atıyor), degeri degiştirip 3 , 2 gibi bir değer yaptıgımda sayıyor ve bir önceki koddaki gibi dura dura degil stabil sayıyor ancak farklı degerlerde kitleniyor , ancak kristali adam gibi kullanabilsem bunu aşacagımı düşünüyorum.

bir de hocam sizi hazır bulmuşken

  __bis_SR_register(LPM1_bits + GIE);

GIE , global interruptları açıyor,
lpm için ise ;

SCG1 SCG0 OSCOFF CPUOFF Mode CPU and Clocks Status
0          0         0           0        Active CPU is active, all enabled clocks are active
0          0         0           1        LPM0 CPU, MCLK are disabled, SMCLK, ACLK are active
0          1         0           1        CPU, MCLK are disabled. DCO and DC generator are disabled if the DCO is not used for SMCLK. ACLK is active.
1          0         0           1        LPM2 CPU, MCLK, SMCLK, DCO are disabled. DC generator remains enabled. ACLK is active.
1          1         0           1        LPM3 CPU, MCLK, SMCLK, DCO are disabled. DC generator disabled. ACLK is active.
1          1         1           1        LPM4 CPU and all clocks disabled

hocam sizin programda lpm1 i kullanmanız mantıklı gözüküyor ama bazı programlarda bakıyorum lpm4 kullanılmış.lpm4 modunu bir nevi uyku modu gibi mi kullanılıyor? bütün clokları disabled ediyorsam programım nasıl çalışıyor ?
happy coding.

fatihinanc

Program düzgün olup da istenildiği gibi çalışmıyorsa kristalde bir problem olabilir. Lehimleme işlemi uzun sürdüyse kristalin zarar görmüş olma olasılığı çok yüksek.

LPM4 te ise CPU sadece harici kesmelere tepki veriyor. Mesela işlemciyi bir buton vasıtası ile uyandırabilirsiniz. Veya UART'dan bir veri bekliyorsunuz, START bitini pin kesmesi sayesinde tesbit edebilir ve işlemciyi uykudan uyandırabilrsiniz. Fakat bütük clock kaynakları kapatıldığı için LPM4 içerisinde ise ACLK / SMCLK kullanamazsınız.
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)

burak ozturk

#10
hocam kristal olayı olabilir, kullandıgım lehim teli çamur gibi olmustu sonradan tekrardan söküp lehimlemek zorunda kalmıştım neyse ki elimde bir launchpad daha var ya onun pinlerini uydururum yada kristali değiştiririm artık . ancak muhtemel kristalim sağlam hocam , çünkü

  TA1CTL   = MC_1 + TASSEL_1;
  TA1CCR0  = 32768 - 1;
  TA1CCTL0 = CCIE;

kodlarıyla kesmede bit tersleyince saniyede bir kesme yapabiliyorum.


lpm lerle ilgili ;

hocam lpm1 mantıklı dedim ama ve çalışıyor ama

LPM1
CPU Off, MCLK Off,
DCO off, SMCLK On,
ACLK On

dco off, mclk off iken programım nasıl 1 mhz de koşuyor, sürekli bu konuda kafamı karıştırıp duruyorum.

hocam ben biraz daha ugrasayım gelişmeleri buradan yazarım boyle fazla hazıra konmusum hissine kapılıyorum :) bu arada yardımlarınız için teşekkürler hocam.
happy coding.

fatihinanc

Alıntı yapılan: burak ozturk - 07 Aralık 2012, 21:35:34

LPM1
CPU Off, MCLK Off,
DCO off, SMCLK On,
ACLK On

dco off, mclk off iken programım nasıl 1 mhz de koşuyor, sürekli bu konuda kafamı karıştırıp duruyorum.

İşte olay burada zaten. CPU, DCO ve MCLK yı kapatarak güçten tasarruf ediyorsun aynı zamanda arka tarafta timer, SMCLK kullanarak sürekli çalışıyor ;)
Kainat dediğimiz kitap, yazıldığı dil ve harfler öğrenilmedikçe anlaşılamaz.  (Galileo Galilei)