Pagina 1 di 1

Flag su PIC16F876A

MessaggioInviato: 22 mar 2014, 15:40
da mattia281193
Ciao a tutti,
ho la necessità di attivare la PORTB0 del micro "simulando un bistabile"in uscita ovvero utilizzando un flag che mi permetta di cambiare stato della porta in corrispondenza dell'incremento o decremento di una variabile .
Ho collegato un led in uscita alla portb0, ma a parte durante i 100 ms iniziali rimane spento, mentre dovrebbe accendersi all'invio da seriale di 0x61.
premetto che non sono un esperto quindi il codice non è il massimo.
Codice: Seleziona tutto
char uart_rd;
bit oldstate;
void main() {
  TRISB=0;
  UART1_Init(9600);
  Delay_ms(100);
  PORTB=0x01;
  Delay_ms(100);
  PORTB=0x00;
  oldstate = 0;
  while (1) {
RB0_bit=oldstate;
    if (UART1_Data_Ready()) {
      uart_rd = UART1_Read();
      if (uart_rd==0x61){
      if(oldstate==0){
      oldstate=1;
       }
      }
     if (uart_rd==0x61){
     if(oldstate==1){
      oldstate=0;
      }
     }
  }
}
}

Re: Flag su 16f876a

MessaggioInviato: 22 mar 2014, 18:06
da c1b8
Ti riporto una parte di codice commentandola
Codice: Seleziona tutto
// verifica se ricevo un carattere
if (UART1_Data_Ready()) {
    // leggo il carattere ricevuto
    uart_rd = UART1_Read();

    // 1) se il carattere ricevuto è 0x61 e oldstate è 0 allora oldstate=1
    if (uart_rd==0x61){
        if(oldstate==0){
            oldstate=1;
        }
    }

    // 2) se il carattere ricevuto è 0x61 e oldstate è 1 allora oldstate=0
    if (uart_rd==0x61){
        if(oldstate==1){
            oldstate=0;
        }
    }
}

Come puoi vedere quando il programma riceve un carattere esegue le due if ai punti 1) e 2) in succesione.
Quando è verificata la 1) imposta oldstate a 1, questo però fa si che la 2) immediatamente dopo sia anch'essa valida: quando il programma arriva a verificare la 2), oladstate vale 1 perché appena impostato dallo 1) e quindi torna ad essere 0.

Prova a modificare così:
Codice: Seleziona tutto
// verifica se ricevo un carattere
if (UART1_Data_Ready()) {
    // leggo il carattere ricevuto
    uart_rd = UART1_Read();

    // 1) se il carattere ricevuto è 0x61
    if (uart_rd==0x61){
        if(oldstate==0){
            oldstate=1;
        } else {
           //  altrimenti oldstate=0
            oldstate=0;
        }
    }
}

Re: Flag su PIC16F876A

MessaggioInviato: 22 mar 2014, 19:47
da mattia281193
Ok grazie, il problema è che io con lo stesso carattere voglio stesso carattere voglio spegnere il led, cosi facendo con ogni carattere lo potrei fare. :(

Re: Flag su PIC16F876A

MessaggioInviato: 22 mar 2014, 19:54
da c1b8
No, se guardi bene il codice che ti ho scritto il controllo sul valore del LED viene fatto solo quando ricevi il carattere 0x61, non per qualsiasi carattere. Quindi solo con il carattere 0x61 accendi e/o spegni il led

Re: Flag su PIC16F876A

MessaggioInviato: 22 mar 2014, 20:19
da karl246
Credo si possa snellire il codice facendo la xor su oldstate ogni volta che si riceve il carattere 0x61.... praticamente se è accesso lo spegne e viceversa. :ok:


Codice: Seleziona tutto
    char uart_rd;
    bit oldstate;
    void main() {
      TRISB=0;
      UART1_Init(9600);
      Delay_ms(100);
      PORTB=0x01;
      Delay_ms(100);
      PORTB=0x00;
      oldstate = 0;
      while (1) {
               RB0_bit=oldstate;
               if (UART1_Data_Ready()) {
                       uart_rd = UART1_Read();
                       if (uart_rd==0x61) oldstate ^= 1;   //XOR su oldstate       
                 }      //fine if
       }                //fine while
    }

Re: Flag su PIC16F876A

MessaggioInviato: 22 mar 2014, 20:21
da karl246
oldstate ^= 1 è un modo contratto per dire
oldstate = oldstate ^ 1
oldstate = oldstate xor 1

O_/

Re: Flag su PIC16F876A

MessaggioInviato: 23 mar 2014, 23:39
da mattia281193
Grazie per l'aiuto... Mi ero focalizzato su altro quando alla fine bastava un else ... Grazie ancora!! :ok: