× MSP430, Microcontrollori 16 bit Ultra Low Power

_delay_cycles()

9 Anni 11 Mesi fa #1 da elpablito
_delay_cycles() è stato creato da elpablito
buona sera
Per pura curiosità dove definisce questa funzione che non sono riuscito a trovarla da nessuna parte?
Saluti
Paolo

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • elpablito
  • Platinum Member
  • Platinum Member
Di più
9 Anni 11 Mesi fa #2 da elpablito
Risposta da elpablito al topic _delay_cycles()
Buon giorno
Mi spiego che così forse ci capiamo.
Ho fatto un contasecondi per la signora al posto del cinese che è il terzo che pattumo. Ho così adoperato un LCD, uno di quelli che si usano nei tester 3 cifre e 1/2 e un pò di simboli,che non vi dico da quanto tempo giace in un cassettino, così non vi impressionate, è un 40 segmenti pilotato da un AY0438 a sua volta gestito da un MPS430G2211. Riesco quindi a smaltire 3 pezzi giacenti in un sol colpo.
Se vi serve la libreria per scrivere il display con l'AY0430 battete un colpo che ve la passo.
Dovevo creare un ritardo sulla pressione del tasto di settaggio, per es dei minuti, per dar tempo di leggere e di togliere il dito dal pulsante. Mi ricordavo dell'esistenza di una funzione intrinseca _delay-Qualchecosa che non sono riuscito a trovare e ho quindi risolto decrementando una variabile con un for. A qualche giorno di distanza mi capita sott'occhio un pezzo di carta dove c'è scritto _dely_cycles(x), poichè mi piace di più del ciclo di ritardo con for, sostituisco quest'ultimo con _delay_cycles(32000) che con il quarzo da orologio fa un po meno di un secondo (Pensavo). Sugo della faccenda le cifre girano alla velocità della luce.
Guardando il disassemblato c'è una routine di ritardo
$1_$7
DEC.W R13
JNE ($1_$7)
che va a decrementare il registro R13, dove ovviamente carica un valore, che alla fine dovrebbe dare 32000 cicli di clock, pari a un terzo. Sugo la rutine di ritardo esiste, però o il clock non è 32786, il che non è vero perchè il timer funziona correttamente, o il clock del main è diverso dal clock del timer. A voi l'ardua sentenza io non riesco a trovare il bacherozzo.
Chiaramente allego pezzo di listato


/*
* main.c
*/
int main(void) {

WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

//****************************************
// Impostazioni modulo Clock
//****************************************

BCSCTL2 = SELM_0 | DIVM_0 | DIVS_0;
BCSCTL1 |= XT2OFF | DIVA_0;
BCSCTL3 = XT2S_0 | LFXT1S_0 | XCAP_1; // extern xtal 32.768 Khz

//****************************************
// Impostazioni Porte I/O
//****************************************
// Configure P1.0, P1.2, P1.3, P1.4 OUT
P1DIR = BIT0 + BIT1 + BIT2 + BIT7;
P1OUT = BIT4 + BIT5 + BIT6;
P1REN = BIT4 + BIT5 + BIT6;

flag = 0;
dots = 0x00; //è il puntino sul display
_enable_interrupts();
dys_clr();

while (1) {
if ((P1IN & 0x30) == 0x20) { // BIT5 ->0 incremento minuti
// for (dly = 40000; dly > 0; dly--) {} //loop di ritardo
_delay_cycles(32000);
if ((P1IN & 0x30) == 0x20) {
min++;
if (min > 90)
min = 0;
}
}
if ((P1IN & 0x30) == 0x10) { // BIT4 ->0 incremento secondi
// for (dly = 40000; dly > 0; dly--) {} //loop di ritardo
_delay_cycles(32000);
if ((P1IN & 0x30) == 0x10) {
sec = sec + 10;
if (sec > 60)
sec = 0;
}
}

if ((P1IN & 0x30) == 0x00) { // BIT4 e BIT5 ->0 azzero
// for (dly = 20000; dly > 0; dly--) {} //loop di ritardo
_delay_cycles(32000);
if ((P1IN & 0x30) == 0x00) {
min = 0;
sec = 0;
}
}

if ((P1IN & 0x40) == 0x00) { // BIT6 ->0 azzero start
// for (dly = 40000; dly > 0; dly--) {} //loop di ritardo
_delay_cycles(32000);
if ((P1IN & 0x40) == 0x00) {
minuti = min;
secondi = sec;
P1OUT |= BIT7; // Cicalino ON
for (dly = 4000; dly > 0; dly--) {}
P1OUT &= 0x7F; //Cicalino OFF
/*
* Abilito il timer, IRQ su overflow di TAR ogno 2 sec
*/
TAR = 0; // Contatore a zero
TACTL = TASSEL_1 + MC_2 + TAIE; // ACLK, contmode UP, interrupt enable
}
}

time_write(); // Scrive il display

} // While 1

Saluti al gruppo
Paolo

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • elpablito
  • Platinum Member
  • Platinum Member
Di più
9 Anni 11 Mesi fa #3 da elpablito
Risposta da elpablito al topic _delay_cycles()
@ Mauro & C
La faccio più breve
quale è la ragione per cui il led non resta acceso per circa 5 sec

#include <msp430.h>

unsigned char k;

/*
* main.c
*/
int main(void) {
WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer


//****************************************
// Impostazioni Porte I/O
//****************************************
P1OUT = 0x00;
P1DIR = BIT6;
//****************************************
// Impostazioni modulo Clock
//****************************************
BCSCTL2 = SELM_3 | DIVM_0 |SELS| DIVS_0;

BCSCTL1 |=XT2OFF | DIVA_0;

BCSCTL3 = XT2S_0 | LFXT1S_0 | XCAP_1; //oscillatore esterno 32.768 khz

//****************************************
// Applicazione principale
//****************************************


P1OUT ^= BIT6; //accendo
for(k=5;k>0;k--){
_delay_cycles(32768);
}
P1OUT ^= BIT6; //spengo


}

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • elpablito
  • Platinum Member
  • Platinum Member
Di più
9 Anni 11 Mesi fa #4 da Mauro Laurenti
Risposta da Mauro Laurenti al topic _delay_cycles()
Ciao Paolo,

per le funzioni inline l'opzione got to declaration non funziona. Ricordo di aver cercato tempo fa la funzione ma se memoria non mi inganna non la trovai. Per le funzioni inline per impostare lo status register si trova la dichiarazione ma non l'implementazione (poco male visto che sono semplici).

Il modo migliore per fare il debug e' controllare direttamente l'assembly.
Questo mostrera' eventuali problemi.

In ogni modo mi aspetto che:

_delay_cycles(...);

sia implementata con un ciclo for (in assembly), che ripete n volte un nop.
Per tale ragione non mi aspetto grandi precisioni e sconsiglio di usarla per un orologio.
Usa direttamente un timer e vai in LPM3.

Il codice Assembly mostrera' ogni segreto.

Saluti,

Mauro

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Moderator
  • Moderator
Di più
9 Anni 11 Mesi fa #5 da elpablito
Risposta da elpablito al topic _delay_cycles()
Buona sera al Mauro
Con l'affermazione "per le funzioni inline l'opzione got to declaration non funziona" mi hai quasi messo in crisi. Transeat.
L'assembler l'avevo già guardato ed è per quello che sono rimasto di c...ca lui carica R13 con un valore pari a 1/3 del numero dei cicli(0x8000/3=2aa8) poi decrementa e ritorna (facilmente fa tre cicli) se non è zero
$C$L1:
f890: 120D PUSH R13
f892: 403D 2AA8 MOV.W #0x2aa8,R13
$1_$2:
f896: 831D DEC.W R13
f898: 23FE JNE ($1_$2)

Era una semplice routine di ritardo su un pulsante premuto, non si cercava precisione, per l'oggetto ho risolto banalmente con un

for (dly = 40000; dly > 0; dly--) {} //loop di ritardo

Quello che mi ha lasciato perplesso è che la velocità con cui esegue il ciclo

for(k=5;k>0;k--){
_delay_cycles(32768);
}

pari a una frazione di secondo. Il chè porta a ritenere che il MCLK il clock di sistema non sia il 32786 nonostante il SELM_3 (BCSCTL2 = SELM_3 | DIVM_0 |SELS| DIVS_0; ) altrimenti vista la routine di ritardo in assembler il ritardo doveva essere decisamente superiore. Quindi :evil:
Ciao a tutti
Paolo

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • elpablito
  • Platinum Member
  • Platinum Member
Di più
Moderatori: Mauro LaurentiMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Login