Go Down

Topic: RS485 per programmare ATmega (Read 2806 times) previous topic - next topic

leo72



Usa però la manipolazione diretta delle porte logiche


Leo, ma per chi mi hai preso?

Repetita iuvant  :P

sciorty

Ma quale repetita, mai fatte queste cose  :(

Stavo vedendo la funzione flash_led, che dovrebbe essere quella che viene ripetuta due volte per segnalare l'inizio di caricamento dello sketch facendo accendere il led13. Pensavo che magari avrei potuto prenderne spunto e semplicemente andare a modificare la porta :smiley-mr-green: :

Code: [Select]
void flash_led(uint8_t count) {
  do {
    TCNT1 = -(F_CPU/(1024*16));
    TIFR1 = _BV(TOV1);
    while(!(TIFR1 & _BV(TOV1)));
#ifdef __AVR_ATmega8__
    LED_PORT ^= _BV(LED);
#else
    LED_PIN |= _BV(LED);
#endif
    watchdogReset();
  } while (--count);
}


Ma sono solo arrivato a capire che se il micro non è un atmega 8 fa un operazione or tra LED_PIN e la funzione _BV(LED)..
Ma tutta queste variabili cosa contengono? Non trovo le assegnazioni!


PS. Forse stava meglio in Software questo topic  :smiley-yell:

sciorty

Comunque leggendo nel reference:
Quote
PORTD is a built-in constant that refers to the output states of digital pins 0,1,2,3,4,5,6,7
PORTD = B00110001; we have made pins 2,3 & 7 HIGH.


Quote
DDRD = DDRD | B11111100; // set direction bits for pins 2 to 7, leave 0 and 1 untouched (xx | 00 == xx)


Non si leggevano in ordine crescente da sinistra verso destra?


Ma carine queste cose comunque :)

leo72

http://www.arduino.cc/en/Reference/PortManipulation

Per mettere in input un pin, devi prima vedere dalla piedinatura del microcontrollore a quale porta appartiene e poi imposti il suo bit.
Ad esempio, il pin D10 di Arduino è il piedino PB3, quindi porta "B", bit "3".
Ora, sapendo questo, col link che ti ho dato, vedi che il registro DDx regola la direzione dei pin di una porta.
Quindi se vuoi mettere quel pin come output, devi mettere a 1 il bit 3.
Code: [Select]
DDRB |= (1<<3);

Adesso lo stato del pin lo regoli con il registro PORTx corrispondente, quindi PORTB.
1 sul bit 3 mette "HIGH" quel pin, 0 lo mette LOW:
Code: [Select]
PORTB |= (1<<3); //mette HIGH
PORTB &= ~(1<<3); //mette LOW


Se vuoi metterlo su output, devi metterlo s

sciorty

Eh si, stavo giusto leggendo questi operatori e ora me li studio e provo un po' :) quindi posso adoperare queste porte nel file optiboot.c no?

Supponiamo che usi il pin 2 pensavo di fare così:
per impostare il pin come output   DDRD |=B0000100 

nella parte di trasmissione            PORTD |=B0000100

nella parte di ricezione                 PORTD &=B1111011

leo72

#20
Mar 06, 2013, 06:17 pm Last Edit: Mar 06, 2013, 11:38 pm by leo72 Reason: 1

Eh si, stavo giusto leggendo questi operatori e ora me li studio e provo un po' :) quindi posso adoperare queste porte nel file optiboot.c no?

Supponiamo che usi il pin 2 pensavo di fare così:
per impostare il pin come output   DDRD |=B0000100  

No.OK

Quote

nella parte di trasmissione            PORTD |=B0000100

No.OK

Quote

nella parte di ricezione                 PORTD &=B1111011

No.OK

Facendo come hai scritto te, cambi lo stato di TUTTI i pin di quella porta.
Devi usare la notazione che ho usato io.

PORTB |= (1<<3)
significa:
PORTB = PORTB | (1<<3)

1<<3 significa:
prendi il valore 1 e shiftalo a SX di 3 posizioni.
La sostanza finale è che accendi solo il bit n° 3 (quello in posizione 4).

Con PORTB &= ~(1<<3)
fai l'opposto, ossia spengi solo il bit n° 3.
Equivale a
PORTB = PORTB & ~(1<<3)
Il segno "~" inverte i bit.
Quindi 1<<3 diventa 00001000
Invertendolo diventa 11110111
Facendo un AND logico, lasci tutti gli altri bit inalterati e metti a 0 solo quello che ti serve.

sciorty

Aspe, evidentemente ho capito male qualcosa.. a prescindere dalle tue operazioni:

PIN13=PB5, quindi se volessi fare un esempio di blink perchè non ci riesco così?

DDRB=B000001 ;

PORTB=B000001;
aspetto
PORTB=B000000;
aspetto

sciorty

Perchè vanno letti da destra verso sinistra, ecco perchè.. ora posso andare a letto tranquillo  :P
Code: [Select]
void setup(){
DDRB |=B100000 ;
}
void loop(){
PORTB |=B100000;
delay(1000);
PORTB &=B011111;
delay(1000);
}



Tornando al discorso di prima:
DDRB |=B100000 ; fa una OR, un'addizione, di conseguenza se sommo 0 alle altre porte non cambia nessun valore..

PORTB &=B011111; invece fa una AND, moltiplicazione, stessa cosa se moltiplico per 1
sarebbe stato lo stesso con una EXOR, sottrazione, facendo così PORTB ^=B100000

Ovviamente è uno sbattimento scrivere tutti i bit e mi studierò il metodo shift e _BV ma non capisco perchè mi hai detto che fosse sbagliato!


leo72

Perché mi sono confuso....
Scusami...  :smiley-sweat: :smiley-sweat:

Janos



Usa però la manipolazione diretta delle porte logiche


Leo, ma per chi mi hai preso? :p vedo se riesco in qualche maniera a farmi aiutare a scuola :)


Prova a leggere qui:
http://arduino.cc/forum/index.php/topic,72628.msg545828.html#msg545828

P.S. Ma se sei neofita, perché parti dal più difficile?

sciorty

Ok, in questa posizione vanno bene?

Code: [Select]
DDRD |=B0000100 
int main(void) {


Code: [Select]
uint8_t getch(void) {
PORTD &=B1111011
[..]
}


Code: [Select]
void putch(char ch) {
PORTD |=B0000100
[...]
PORTD &=B1111011
}

leo72

Il primo mettilo dove ti avevo segnalato alcuni post fa.
Sul terzo, non metterei in uscita da putch() un altro PORD &=, non si sa se la prox chiamata è sempre un putch() o un getch()

sciorty

#27
Mar 10, 2013, 07:55 pm Last Edit: Mar 10, 2013, 07:58 pm by sciorty Reason: 1
Il PORTD &= l'ho messo per riportare a 0 il pin. Cioè, il pin deve stare sempre a 0 cioè in ascolto, nel momento in cui devo "parlare" metto il pin ad 1 e quando finisco lo riporto a 0 (fine della funzione put)

Ah, e per flashare..?  :smiley-sweat:

leo72


Il PORTD &= l'ho messo per riportare a 0 il pin. Cioè, il pin deve stare sempre a 0 cioè in ascolto, nel momento in cui devo "parlare" metto il pin ad 1 e quando finisco lo riporto a 0 (fine della funzione put)

Ah, e per flashare..?  :smiley-sweat:

Se hai Linux la cosa è semplice.
Apri un terminale nella cartella dove hai i sorgenti del bootloader, rinomini il file "optiboot_atmega328.hex" in qualcos'altro (per avere il bootloader originale in caso di problemi) e dai un "make atmega328".
Con Windows non so come si fa a compilare. Ti devi informare.

Dopo che hai creato il firmware, hai bisogno di un altro Arduino per scrivere il bootloader su un chip standalone oppure di un programmatore. E da IDE con l'opzione "Scrivi bootloader" flashi il nuovo bootloader.

Prima verifica con avr-size se il bootloader è grande 512 byte altrimenti esce dallo spazio che l'Arduino riserva per l'Optiboot.

sciorty

Ok linux posso prenderlo su un altro pc di cui non posso disporre subito..

Cioè devo semplicemente salvarmi l'optiboot.h originale, posizionarmi sulla cartella che contiene questo file che stiamo modificando e lanciare il comando?
Poi suppongo che debba fare un burn bootloader with arduino as isp?

Go Up