giovedì 21 luglio 2011

Nuova avventura - Elettronica - MSP430 LaunchPad - 1° Parte


I post che seguiranno saranno dedicati mondo dell'elettronica, con qualche divagazione culturale.

MSP-EXP430G2 - MSP430 LaunchPad Value Line Development kit

Ho da qualche settimana il Kit Msp430-LaunchPad ( www.ti.com/launchpad ) per meno di 5 euro dalla Texas Istrumenet ed ho cominciato a sperimentare una semplice applicazione.
Ho infatti al necessità di realizzare un semplice sistema di sicurezza con n.3 contatti magnetici installati nelle porte di ingresso. I requisiti principali di questo semplice sistema sono:
  1. tempo di attivazione della sirena inferiore a 3 minuti
  2. n.3 ingressi distinti
  3. misura della tensione della batteria
  4. n.1 ingresso per chiave di attivazione del sistema
  5. led di segnalazione operativo e batteria scarica
  6. interfaccia seriale per gestire tramite comandi AT un modulo GSM per l'invio di SMS

In questa prima parte dello sviluppo, mi sono limitato a comprendere il bene lo sviluppo in ambiente Code Composer / GRACE dove ho incontrato non poche difficoltà, legate alla gestione delle versioni di XDCtools e GRACE.
Infatti la mia intenzione è di usare un microprocessore MSP430G2553 (28 pin TSSOP), molto più evoluto di quello già inserito nella scheda msp430.launcjapd che è un MPS430G2231 con soli 16 pin, ma se non si procede all'installazione della versione grace più recente (scaricabile a questo indirizzo) e non si cancellano le cartelle di XDCtools e GRACE obsolete, nel percorso C:\Programmi\Texas Instruments , il programma ECLIPSE fornisce l'errore di dispositivo MSP430g2553 non supportato.

Il pregio del sistema Grace è che la configurazione delle impostazioni iniziali avviene in modalità grafica.
Illustro le configurazioni utilizzate in questa  applicazione.



Verificato la fattibilità di migliorare le caratteristiche di questo prima fase applicativa, ho cominciato ad abbozzare il codice in C.
main.c
//*****************************************************************************
// Software UART using Timer_A
//
// Description: This example illustrates how to output characters
// to an RS-232 serial port without a UART peripheral.
//
// MSP430
//                   -----------------
//              /|\ |                 |
//               |  |                 |
//                --|RST              |
//                  |                 |
//          ZONA1 ->|P1.3             |
//          ZONA2 ->|P1.5         P1.1|-->TXD
//          ZONA3 ->|P1.7         P1.2|<--RXD
//                  |                 |
//      TENS_BATT ->|P1.4         P1.0|-->LED1 (SIRENA)
//                  |             P1.6|-->LED2 (OPERATIVO
//         CHIAVE ->|P2.6         P2.7|-->BATTERIA_SCARICA
//                  |_________________|
//
// RIEPILOGO
// P1.0 LED1 SIRENA
// P1.1 TXD
// P1.2 RXD
// P1.3 ZONA 1
// P1.4 TENS_BATT
// P1.5 ZONA 2
// P1.6 LED2 OPERATIVO
// P1.7 ZONA3
// P2.6 CHIAVE
// P2.7 FREE
// Texas Instruments Inc.
//*****************************************************************************

/*
* ======== Standard MSP430 includes ========
*/
#include <msp430.h>

/*
* ======== Grace related includes ========
*/
#include <ti/mcu/msp430/csl/CSL.h>



#define BITIME (13 * 4) // 125 KHz /(13*4) = 2404 bits/sec
unsigned char bitCnt; // number of bits to transmit
unsigned int txByte; // transmit buffer with start/stop bits
unsigned int AdcData[3] = {0}; // Store results A2,A1,A0
unsigned int const_volt = 0; // Determine ConstVoltage/ConstCurrent
unsigned int timedelay = 0; // Variable to Start Watchdog timer delay
unsigned int timercounts = 0; // Track time delay
unsigned int delayflag = 0;
void putstr(char *str); // transmit string
void transmit(unsigned char ch); // transmit a character
/*
* ==== platform-specific definitions ========
*/
#define LEDOUT P1OUT // GPIO port with LEDs
#define GREEN BIT6 // green LED location for the LaunchPad
#define RED BIT0 // red LED location

//======== globals ========

volatile int batt; // raw ADC10 value
volatile int degF; // temperature in degrees F
volatile int degC; // temperature in degrees C
volatile int initialDegF; // initial measurement in degrees F
unsigned int allarme;

/*
* ======== main ========
*/
int main(void)
{
CSL_init(); // Activate Grace-generated config
ADC10CTL0 |= ENC; // Abilità conversione ADC
P1IES |= BIT3; // high -> low is selected with IES.x = 1.
P1IFG &= ~BIT3; // To prevent an immediate interrupt, clear the flag for
// P1.3 before enabling the interrupt.
P1IE |= BIT3; // Enable interrupts for P1.3
__enable_interrupt(); // Abilità interrupt globale
allarme =0;

P1OUT &= ~BIT0; // Commuta a off il LED (P1.0)
WDTCTL = WDTPW + WDTHOLD; // Stop WDT


while (1) {
  __no_operation(); // utilizzato solo per il debug
  //putstr("Hello world.\n\r");
  if(allarme == 1)
   {
    allarme =0;
   delayflag = 1;
   // WDTCTL = WDT_ADLY_1000; // WDT 1s, ACLK, interval timer 
   /* Use WDT as an interval counter for button debounce */
   IFG1 &= ~WDTIFG; // Clear any pre-existing WDT interrupt
   WDTCTL = (WDTCTL & 7) + WDTCNTCL // Reset watchdog with same divider,
    + WDTPW + WDTTMSEL; // write password, and timer mode
   IE1 |= WDTIE; // Enable WDT interrupt
   __bis_SR_register(LPM0_bits); // Enter LPM0
  }
}
/*
* ======== putstr ========
*/
void putstr(char *str)
{
char *cp;
for (cp = str; *cp != '\0'; cp++) {
transmit(cp[0]);
}
}

/*
* ======== transmit ========
* Transmit specified character
*/
void transmit(unsigned char ch)
{
bitCnt = 0xA; // Load Bit counter, 8data + ST/SP
txByte = (unsigned int)ch | 0x100; // Add mark stop bit to txByte
txByte = txByte << 1; // Add space start bit

CCR0 = TAR + BITIME; // Some time till first bit
CCTL0 = OUTMOD0 + CCIE; // TXD = mark = idle
while (CCTL0 & CCIE); // Wait for ISR to complete TX
}

/*
* ======== timer_A_ISR ========
* Timer A0 interrupt service routine
*/
void timer_A_ISR(void)
{
CCR0 += BITIME; // Schedule next interrupt
if (bitCnt == 0) {
CCTL0 &= ~CCIE; // All bits TXed, disable interrupt
}
else {
if (txByte & 0x01) {
CCTL0 &= ~OUTMOD2; // TX Mark
}
else {
CCTL0 |= OUTMOD2; // TX Space
}
txByte = txByte >> 1;
bitCnt--;
}
}

/*
* ======== adcIsr ========
* ADC10 conversion ISR
*
* This ISR moves the conversion result into global variable. Doing so
* will also clear the associated interrupt flag ADC10IFG.
*
* This interrupt handler routine gets assigned in the ADC10 Grace view.
*/
void adcIsr(void)
{
batt = ADC10MEM; // read ADC10 sampled temperature
}

void watchdogIsr(void)
{
   if(timercounts == 700)
    {
     TACTL = 0; // before stop charging
     P1SEL = 0;
     P1OUT = 0;
    ADC10CTL0 = 0;
    timercounts = 0;
    timedelay = 0;
    delayflag = 0;
    IE1 &= ~WDTIE; // Disable this (WDT) interrupt
    P1IFG &= ~BIT3; // Ensure button interrupt flag is clear
    P1IE |= BIT3; // Re-enable button/zone interrupt
    P1OUT &= ~BIT0; // Turn off LED (P1.0)
   }
  else
   {
    timercounts++;
      P1OUT |= BIT0;; // Turn on LED (P1.0)
  }
}

void pioIsr(void)
{
switch(P1IFG&BIT3) {
case BIT3:
P1IFG &= ~BIT3; // Clear the port 1.3 interrupt flag
allarme =1 ;
//BCSCTL1 = bcs_vals[i];
//DCOCTL = dco_vals[i];
//if (++i == 3)
// i = 0;
return;
default:
allarme =0;
P1IFG = 0; // probably unnecessary, but if another flag occurs
// in P1, this will clear it. No error handling is
// provided this way, though.
return;
}
} // P1_ISR
/*

Il codice funziona correttamente se si preme infatti il pulsantino P1.3 si assiste all'accensione per circa 3 minuti del led P1.3. Durante la fase di accensione del led ulteriori pressione del pulsantino sono ignorati, cosi come avviene negli impianti di allarme. Evidentemente una volta trascorsi i tre minuti, il sistema è di nuovo in stato di pronto.

Come è visibile ho utilizzato come base di partenza l'esempio GRACE per realizzare l'UART.

In questa fase la parte di programma più interessante è l'utilizzo del Watchdog (WDT+). La funzione watchdogIsr (associata all'interrupt WDT) viene innescata nella ciclo while di main se la condizione if(allarme == 1) è vera. Quando l'interruput WDT è attivo la funzione watchdogIsr viene richiamata finche non raggiunge 680 cicli, in questo modo otteniamo un tempo di attivazione della sirena (connessa a P1.0) di 680 * 0,262s = 178 secondi.

In questa prima parte come è evidente ci sono molte funzione del codice C incomplete. Come ho già detto la cosa più importante è prendere familiarità con il kit e software di sviluppo.
Nella seconda parte ci sarà lo sviluppo con EAGLE PCB Freeware di una scheda pcb per il supporto della CPU MSP430G2553 e dell'ulteriore sviluppo e debug del codice C.
A presto!

Nessun commento:

Posta un commento