Richiesta info utilizzo linguaggio assembly all'interno dell'IDE di ARDUINO

Per necessità legate alle tempistiche particolarmente stringenti ho la necessità di implementare una parte del programma in assembly per ATMEGA 238P. Ho consultato vari esempi, ho scaricato un testo "Inline Assembler Cookbook" che mi ha chiarito molti dubbi. Ho scritto il programma regolarmente compilato, ma quando effettuo la verifica funzionale mi accorgo che commette un errore, in particolare l'operazione di mascheratura non funziona correttamente e solo il MSB viene riconosciuto, tutti gli altri vengono rappresentati con uno 0.

Altra informazione: eseiste un modo più elegante e compatto per scrivere lo stesso codice?

Grazie per le vostre risposte e fatemi sapere se, essendo il primo post, ho commesso delle scorrettezze. Buona giornata
Questo è il programma:

#define DATA_IN     4 // Pin IN del chip WS8212B
#define NUM_LED     36
#define numvals     3

uint8_t pixels[12]= {0xFF,0xFF,0xFF,0x10,0x08,0x04,0x02,0x01,0xAA,0x55,0x55,0xAA};

uint16_t  cb = numvals; // Loop counter
uint8_t   *ptr = pixels; // Pointer to next val
uint8_t   b;   
uint8_t   *port; 
uint8_t   pinMask = (0x1 << DATA_IN); // maschera sul bit da tx
uint8_t   Maschera, Nbit  ;
uint8_t   hi, lo;

void setup() 
{
  pinMode(DATA_IN, OUTPUT);
  digitalWrite(DATA_IN, LOW);
      
  port = &PORTD;   
  hi = *port | pinMask;
  lo = *port & ~pinMask;
  Maschera  = 0x80;  // preset maschera bit
  Nbit=8;
  
  Serial.begin(115200);
  
  Serial.print("PORT  "); Serial.print(*port, HEX);

  Serial.print("  pinMask  "); Serial.print(pinMask, HEX);
  Serial.print("  hi  "); Serial.print(hi, HEX);
  Serial.print("  lo  "); Serial.print(lo, HEX);

  b = *ptr++; // val corrente da trasmettere
  
  Serial.print("  b  "); Serial.println(b, HEX);

  asm volatile( 
    "cli"                  "\n\t"  // 1      cli = globai Interrup disble 
 
 "Ciclo:"               "\n\t"  // Clk    Descrizione
    "out  %[port], %[hi]"  "\n\t"  // 1      Alza lo stato del bit da tx
    **"and  %[val], %[Maschera]"   "\n\t"  // 1-2    Verifica se il bit mascherato è 1 o 0**
    "breq Ciclo_0"         "\n\t"  // 2      ... se "0" salta a Ciclo_0
    "brne Ciclo_1"         "\n\t"  // 2      ... se "1" salta a Ciclo_1
 
 "Ciclo_0:"            "\n\t"  // 
    "call Bit_0"           "\n\t"  // 1-2   Chiama la Sub Bit_0 
    "jmp Ciclo_com"        "\n\t"  // 2      salta al punto comune
    
 "Ciclo_1:"            "\n\t"  // 
    "call Bit_1"           "\n\t"  // 1-2   Chiama la Sub Bit_1 
    
 "Ciclo_com:"           "\n\t"  // 
    **"lsr  %[Maschera]"           "\n\t"  // 1      Genera la nuova maschera**
    "dec  %[Nbit]"           "\n\t"  // 1
    "brne Ciclo"           "\n\t"  // 1      ... se != da 0 ripete ...

    "sbiw %[count], 1"     "\n\t"  // 2      ... aggiorna il contatore dei val da tx 
    "breq Fine"            "\n\t"  // 2      ... se non ce ne sono termina
    "ld   %[val], %a[ptr]+"  "\n\t"  // 2    altrimenti carica il nuovo val da tx
    "ldi  %[Maschera], 0x80"     "\n\t"  // 1       Riparte con la maschera iniziale
    "ldi  %[Nbit], 0x08"     "\n\t"  // 1 
    "jmp Ciclo"            "\n\t"  // 2      ...e ripete il ciclo
    
 "Bit_0:"               "\n\t"  //
    "nop"                  "\n\t"  // 1      nop 
    "out  %[port], %[lo]"  "\n\t"  // 1      Abbassa lo stato del bit da tx
    "nop"                  "\n\t"  // 1      nop 
    "nop"                  "\n\t"  // 1      nop        
    "ret"                  "\n\t"  // 4      ritorno dalla sub. 
    
 "Bit_1:"               "\n\t"  //    
    "nop"                  "\n\t"  // 1      nop 
    "nop"                  "\n\t"  // 1      nop        
    "nop"                  "\n\t"  // 1      nop 
    "nop"                  "\n\t"  // 1      nop
    "nop"                  "\n\t"  // 1      nop
    "out  %[port], %[lo]"  "\n\t"  // 1      Abbassa lo stato del bit da tx
    "ret"                  "\n\t"  // 4      ritorno dalla sub.     
    
 "Fine:"                "\n\t"  //
    "sei"                  "\n"  // 1      cli = globai Interrup disble 

    : [count]"+w"(cb),[val]"+r"(b),[Maschera]"+r"(Maschera),[Nbit]"+r"(Nbit),[hi]"+r"(hi), [lo]"+r"(lo)
    : [port] "I"(_SFR_IO_ADDR(PORTD)), [ptr]"e"(ptr)
    : );
}

void loop() 
{
}

Buonasera e benvenuto nella sezione Italiana del forum,

cortesemente, come prima cosa, leggi attentamente il REGOLAMENTO di detta sezione, (... e, per evitare future possibili discussioni/incomprensioni, prestando molta attenzione al punto 15), dopo di che, come da suddetto regolamento (punto 16.7), fai la tua presentazione NELL'APPOSITA DISCUSSIONE spiegando bene quali esperienze hai in elettronica e programmazione, affinché noi possiamo conoscere la tua esperienza ed esprimerci con termini adeguati.

Grazie,

Guglielmo

P.S.: Ti ricordo che, purtroppo, fino a quando non sarà fatta la presentazione nell’apposita discussione, nel rispetto del succitato regolamento nessuno ti risponderà (eventuali risposte o tuoi ulteriori post, verrebbero temporaneamente nascosti), quindi ti consiglio di farla al più presto. :wink:

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.