RS485 per programmare ATmega

sciorty:
Eh si, stavo giusto leggendo questi operatori e ora me li studio e provo un po' :slight_smile: 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

nella parte di trasmissione PORTD |=B0000100

~~No.~~OK

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.

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

Perchè vanno letti da destra verso sinistra, ecco perchè.. ora posso andare a letto tranquillo :stuck_out_tongue:

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!

Perché mi sono confuso....
Scusami... :sweat_smile: :sweat_smile:

sciorty:

leo72:
Usa però la manipolazione diretta delle porte logiche

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

Prova a leggere qui:

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

Ok, in questa posizione vanno bene?

DDRD |=B0000100  
int main(void) {
uint8_t getch(void) {
 PORTD &=B1111011
 [..]
}
void putch(char ch) {
PORTD |=B0000100
[...]
PORTD &=B1111011
}

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()

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..? :sweat_smile:

sciorty:
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..? :sweat_smile:

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.

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?

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?

Per scrupolo, copia tutta la cartella /optiboot, così puoi rimettere tutto a posto e ripristinare l'Optiboot originale.

Poi suppongo che debba fare un burn bootloader with arduino as isp?

Sì, devi programmare l'Atmega tramite Arduino. Però devi crearti prima una board virtuale, come descritto nella guida di Menniti.

Uhmm nell‘istruzione non mi riconosce atmega328.. io ho fatto una copia della csrtella optiboot, modificato il file optiboot.c, e posizionatomi col terminale sulla cartella optiboot.
Ma quest‘operazione esattamente a cosa serve? Sarebbe una compulazione dei codici? Se lo faccio sul mio pc linux, posso poi semplicemente copiare su windowsla cartella optiboot ricavata e quindi fare il burning del bootloader?

sciorty:
Uhmm nell‘istruzione non mi riconosce atmega328.. io ho fatto una copia della csrtella optiboot, modificato il file optiboot.c, e posizionatomi col terminale sulla cartella optiboot.

deve funzionare con "make atmega328". Prova sennò dando un "make" generico e guarda se compila per tutti i micro.

Ma quest‘operazione esattamente a cosa serve? Sarebbe una compulazione dei codici? Se lo faccio sul mio pc linux, posso poi semplicemente copiare su windowsla cartella optiboot ricavata e quindi fare il burning del bootloader?

Serve a compilare il bootloader, cioè a creare l'eseguibile partendo dai sorgenti modificati che hai scritto tu.
Se compili su Linux puoi semplicemente prendere il file optiboot_atmega328.hex, è quello che serve, e copiarlo sulla tua installazione Windows (salva quello originale, per scrupolo).

Ho letto che su windows c'è il file omake.bat all'interno della cartella optiboot quindi si può fare, ma ho riscontrato un problema dovuto a qualche errore di sintassi all'interno di optiboot.c, allego anche lo screen.

Tolgo un po' di roba a caso altrimenti non rientro con il numero di caratteri, le modifiche sono in maiuscolo:

int main(void) {

  // Adaboot no-wait mod
  ch = MCUSR;
  MCUSR = 0;
  if (!(ch & _BV(EXTRF))) appStart();
[b]DDRD |=B0000100;  [/b]
#if LED_START_FLASHES > 0
  // Set up Timer 1 for timeout counter
  TCCR1B = _BV(CS12) | _BV(CS10); // div 1024
#endif

}

void putch(char ch) {
[b]PORTD |=B0000100;[/b]
#ifndef SOFT_UART
  while (!(UCSR0A & _BV(UDRE0)));
  UDR0 = ch;
#else
  __asm__ __volatile__ (
    "   com %[ch]\n" // ones complement, carry set
    "   sec\n"
    "1: brcc 2f\n"
    "   cbi %[uartPort],%[uartBit]\n"
    "   rjmp 3f\n"
    "2: sbi %[uartPort],%[uartBit]\n"
    "   nop\n"
    "3: rcall uartDelay\n"
    "   rcall uartDelay\n"
    "   lsr %[ch]\n"
    "   dec %[bitcnt]\n"
    "   brne 1b\n"
    :
    :
      [bitcnt] "d" (10),
      [ch] "r" (ch),
      [uartPort] "I" (_SFR_IO_ADDR(UART_PORT)),
      [uartBit] "I" (UART_TX_BIT)
    :
      "r25"
  );
#endif
[b]PORTD &=B1111011;[/b]
}

uint8_t getch(void) {
[b] PORTD &=B1111011;[/b]
  uint8_t ch;

#ifdef LED_DATA_FLASH
#ifdef __AVR_ATmega8__
  LED_PORT ^= _BV(LED);
#else
  LED_PIN |= _BV(LED);
#endif
#endif

#ifdef SOFT_UART
  __asm__ __volatile__ (
    "1: sbic  %[uartPin],%[uartBit]\n"  // Wait for start edge
    "   rjmp  1b\n"
    "   rcall uartDelay\n"          // Get to middle of start bit
    "2: rcall uartDelay\n"              // Wait 1 bit period
    "   rcall uartDelay\n"              // Wait 1 bit period
    "   clc\n"
    "   sbic  %[uartPin],%[uartBit]\n"
    "   sec\n"
    "   dec   %[bitCnt]\n"
    "   breq  3f\n"
    "   ror   %[ch]\n"
    "   rjmp  2b\n"
    "3:\n"
    :
      [ch] "=r" (ch)
    :
      [bitCnt] "d" (9),
      [uartPin] "I" (_SFR_IO_ADDR(UART_PIN)),
      [uartBit] "I" (UART_RX_BIT)
    :
      "r25"
);
#else
  while(!(UCSR0A & _BV(RXC0)))
    ;
  if (!(UCSR0A & _BV(FE0))) {
      /*
       * A Framing Error indicates (probably) that something is talking
       * to us at the wrong bit rate.  Assume that this is because it
       * expects to be talking to the application, and DON'T reset the
       * watchdog.  This should cause the bootloader to abort and run
       * the application "soon", if it keeps happening.  (Note that we
       * don't care that an invalid char is returned...)
       */
    watchdogReset();
  }

Secondo problema: Il mio convertitore non ha un pinout del reset, quindi non posso mandarlo allo standalone.. mi sa che stiamo facendo un lavoro inutile!! http://www.sparkfun.com/datasheets/BreakoutBoards/USB-to-RS485-Breakout-v11.pdf

Immagineazsd.bmp (658 KB)

1° problema:
per la compilazione su Windows non so aiutarti. Al max posso compilarti il file su Linux, se mi passi il sorgente.

2° problema:
devi replicare lo schema del reset che era usato sull'Arduino 2009, che usava anch'essa l'FT232, dove erano usate le linee DTR/RTS:

No la compilazione la fa, il problema sta appunto nel sorgente in cui avrò sbagliato qualcosa! :sweat_smile:

2- Il problema sta nel fatto che sul convertitore non ho un "buco" che vada al reset o agli altri pin del ft232! (non si chiama pinout?)

Il grassetto non funziona all'interno del tag code.
A me pare che tu stia usando un valore a 7 bit, non ad 8 :wink:

:sweat_smile:

Direi che ora rimanga il problema del reset:
O compro un altro convertitore che abbia un pinout sul reset (non fatemelo fare, vi prego), oppure..?

Il tuo è un convertitore USB/RS485, a te serviva questo prodotto:

che è un convertitore USB/seriale e che, a differenza della schedina che hai tu, tira fuori tutte le linee dall'FT232, comprese RTS e DTR.