Uživatelské jméno:   Heslo:   Pamatuj si mě  

Jednoduché hodiny nebo čítač s MSP430G22x1

 Tisknout 
Popisované hodiny jsou spíše takovým víkendovým projektem, který původně ani neměl vzniknout. Postavil jsem jej k tomu, aby si zájemci, za pomocí vývojového kitu LaunchPad MSP-EXP430G2 od TI,  mohli vyzkoušet i nějakou reálnou aplikaci. LaunchPad je k dostání za značně dotovanou cenu 4.30USD a obsahuje i emulační kit, který stačí připojit pomocí 3-4 drátů (RST,TEST,GND, případně VCC ) k popisované desce a ladit tak program přímo.

Důvodem vzniku této aplikace hodin, případně čítače bylo obdržení objednaných displejů pro digitální stupnici BITX z Ebay. K mému rozčarování tyto displeje sice mají desetinné tečky a dvojtečku, ale lze rozsvítit pouze dvojtečku. Bohužel datasheet k tomuto displeji CL5642BH jsem nesehnal, ale vzhledem k ceně 8.33USD vč. poštovného za 10ks jsem jej objednal.
Z důvodu využití těchto displejů alespoň k něčemu, vznikla tato aplikace. Vzhledem k dostupnému vývojovému kitu MSP-EXP430G2 (u TI v eshopu za 4.30USD, Farnel za 98Kč bez DPH) jsem zvolil řadu MSP430.
Kit obashuje 2ks obvodů a to MSP430G2211 a MSP430G2231 v pouzdře DIL14. Na hodiny plně vyhoví prvně jmenovaný 2211.


 deska kitu MSP-EXP430G2

 
Reálný vzorek prototypu desky - aktuální verze má navíc oddělovací diodu pro připojení VCC z emulačního kitu. Fotografie více nasvícená a navíc v prototypu použity resistory 100R namísto finálních 22R, takže svit segmentů je menší.


Hodiny jsou vzhledem k malému počtu portů rozšířeny o shift registr. Vzhledem k ne zcela dostupným stabilizátorům 3.3V jsem použil 7805 (78L05) se snížením napětí pomocí 2 diod 1N4148. Lze však použít např. LE33CZ v pouzdře TO92 a diody D1, D2 nahradit zkratovací propojkou. Zapojení LE33CZ je stejné jako 78L05.

 

Jako další možnost je na PCB místo pro vstupní tvarovač pro jednoduchý čítač, prozatím neosazen,

Tlačítka jsou klasické "žabky", já na prototypu použil co jsem našel v šuplíku. Neosazeny jsou pozice R12-R14, T5,C4 a X2.

 
 
 

K vývoji s těmito procesory je k dispozici několik různých vývojovách prostředí, používám IAR, který generuje značně optimalizovaný kód a do 4kB přeloženého kódu je zdarma.
Více na stránkách TI zde
Ke stažení poslední verze a popis změn od předchozích verzí zde

Pár linků na datasheet a popis celé rodiny, ačkoliv toto může vypadat jako jakási forma reklamy, dělám to spíše kvůli omezení dotazů typu "kde najdu" a snadnějšímu hledání. Je možné, že při další revizi dokumentů výrobcem již nebudou linky fungovat korektně, pak je nutné hledat přímo na stránkách TI.

Datasheet obvodu MSP430G2211 zde
User guide od celé rodiny CPU MSP430x2xx zde

Obsazení paměti po zkompilování:
772 bytes of CODE memory
64 bytes of DATA memory (+ 19 absolute )
11 bytes of CONST memory


Listing aktuálního programu pro hodiny, bohužel formátování textu vzalo za své, v sekci ke stažení je celý projekt a další soubory k dispozici.
 
//******************************************************************************
//  Ridici program pro hodiny
//
//  Robert Kucera
//  OK2UWQ
//  c 2012
//  Built with IAR Embedded Workbench Version: 5.10
//
//******************************************************************************

#include "msp430g2211.h"

const unsigned char table[]={0x21,0xe7,0x34,0xa4,0xe2,0xa8,0x28,0xe5,0x20,0xa0,0xff}; //tabulka znaku 0-9
static unsigned char disp[4];


static unsigned char locksw;  // pro osetreni zakmitu tlacitek
static unsigned char autoinc; // povoleni automatickeho pricitani pri nastavovani casu
static unsigned char autotmr; // cas zpozdeni od stisku tlacitka k povoleni autoinc (*0,5sec)
static unsigned char autocnt; // zpozdeni - rychlost pricitani hodnoty
static unsigned char showpos; // pozice zobrazovaneho segmentu v multiplexu
static unsigned char display; // navesti k zobrazeni dalsi pozice - zobrazeni mimo preruseni
static unsigned char divsec;  // pomocne pocitadlo pro 0.5sec
static unsigned char sec;  // pocitadlo 1/2 sec
static unsigned char min;  // pocitadlo minut
static unsigned char hod;  // pocitadlo hodin

/*******************************************/
void Set164(unsigned char data) // posle 8bitu na vystup registru
{
  unsigned char i,j;
  i = data;
  for(j=0;j<8;j++){
    P1OUT &= ~0x80;
    P1OUT |= (i & 0x80);
    P1OUT |= 0x40;  //clk high - posun registru o 1
    i = i<<1;
    P1OUT &= ~0x40; //clk low
  }
}

void DecodeTime(void) // nacte aktualni cas do registru pro zobrazeni
{
  disp[0] = hod / 10; // desitky hodin
  disp[1] = hod % 10; // jednotky hodin
  disp[2] = min / 10; // desitky minut
  disp[3] = min % 10; // jednotky minut
}

#pragma vector=PORT1_VECTOR
__interrupt void port1_irq (void) //osetreni preruseni os stisku tlacitka
{
  if(P1IFG & 0x01){
    P1IFG ^= 0x01;
    if(!locksw){
      min++;                          // pri stisku tlacitka pricteni +1 a
      sec=0;
      divsec=0;                       // nulovani sekund a pom. pocitadla
      if(min==60)min=0;
      locksw++;                       // zpozdeni - osetreni zakmitu
      DecodeTime();
      autotmr=6;                      // reset pocitadla autoinc na 3sec
    }
  }
  if(P1IFG & 0x02){                   // obdobne pro stisk tlacitka hodin
    P1IFG ^= 0x02;
    if(!locksw){
      hod++;
      if(hod==24)hod=0;
      locksw++;
      DecodeTime();
      autotmr=6;
    }
  }
}


// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void) // obsluha preruseni od citace - takt 512Hz
{
    display++;            //priznak - po ukonceni preruseni posun na zobrazeni dalsiho segmentu
    divsec++;             // citac /256 - vysledny takt 0,5sec pro blikani dvojtecky a dalsi pocitani
    if((P1IN & 0x03)==0x03){
      autotmr=0;
      autocnt=0;
      autoinc=0;
    }
    if(divsec==0){
      sec++;
      if(autotmr>0){
        autotmr--;
        if(autotmr==0)autoinc++;  //citac zpozdeni autoinc
      }
      locksw=0;
      if(sec==120){               // citani jedne minuty - 120*0,5sec
        sec=2;                    //kompenzace chyby cca 1sec/min
        min++;
        if(min==60){              // citani hodin - 60min
          min=0;
          hod++;
          if(hod==24)hod=0;
        }
        DecodeTime();             // obnova zobrazeni aktualniho casu na displeji
      }
    }
    if(autoinc){                  // povolen autoinc
      autocnt++;
      if(autocnt==64){            // cekani na napocitani zpozdeni
        if(~P1IN & 0x01){         // test stisknuteho tlacitka minut
          min++;
          sec=0;
          divsec=0;
          if(min==60)min=0;
        }
        if(~P1IN & 0x02){         // test stisknuteho tlacitka hodin
          hod++;
          if(hod==24)hod=0;
        }
        DecodeTime();
        autocnt=0;
      }        
    }
}


int main( void )
{
    unsigned char dt;
  // Stop watchdog timer to prevent time out reset
    WDTCTL = WDTPW + WDTHOLD;

    BCSCTL1 = CALBC1_1MHZ;               // Set DCO
    DCOCTL = CALDCO_1MHZ;

    CCTL0 = CCIE;                             // CCR0 interrupt enabled
    CCR0 = 64;                              // interrupt timming
    TACTL = TASSEL_1 + MC_1;                  // ACLK, up mode

    P1DIR = 0xfc;                        
    P1REN = 0x03;
    P1OUT = 0x3f;                       
    P1IE  |= 0x03;                            // Enable interrupt for all pins
    P1IES |= 0x03;                            // set H-L transition to set IRQ
    P1IFG = 0;

    showpos = 0;                              // nulovani pomocnych pocitadel a navesti
    divsec = 0;
    sec = 0;
    min = 0;
    hod = 0;
    DecodeTime();
   
    _BIS_SR(GIE);                           // povoleni preruseni 
       
  while(1){
    if(display){
      P1OUT |=(0x04 << showpos);            // zhasnuti predchoziho segmentu
      showpos++;                            // posun na dalsi pozici
      dt = 0;
      if((showpos==1)&((sec&0x01)==0x01))dt=0x20; //je-li dvojtecka, zobraz co 0,5sec
      if(showpos>3)showpos=0;               // max. 4 segmenty, pak navrat na prvni
      Set164(table[disp[showpos]]&~dt);     // zobrazeni obsahu disp a prevod podle table
      P1OUT &=~(0x04 << showpos);           // rozsviceni segmentu
      display=0;                            // nulovani navesti
    }
  }
}
 




Počet shlédnutí: 3312