Timer 1 e attiny85, non riesco a farlo partire !

Ciao sto cercando disperatamente di far generare all'attiny85 un segnale pwm a 16Khz con duty cycle variabile mediante un potenziometro.

Inizialmente ho usato il timer 0 seguendo le indicazioni riportate sul datasheet e usando l'oscillatore interno a 8Mhz sono riuscito ad ottenere ciò che volevo però con una risoluzione bassa dovuta al fatto che il prescaler per il timer 0 è limitato a poche configurazioni.

Volevo usare il timer 1 poichè il prescaler associato a questo timer da molte più configurazioni disponibili che mi permettono una risoluzione massima proprio di 8 bit (8Mhz/2/256=15625hz), ma non riesco ad usarlo, in praica sembra non partire, uso i registri TCCR1 e GTCCR per settare il timer e infine i registri OCR1A e OCR1C per settare il duty cycle.

Qualcuno ha mai usato il timer 1 del tiny85 ?

Il timer 1 è a 8 bit, come il timer 0. A parte questo, che core stai usando? Se usi il core Tiny, sai che questo core utilizza il timer 1 per generare le funzioni temporali millis e delay?
Puoi postare il codice che stai usando per generare il segnale?

Certamente, ecco il codice:

void setup()  { 
  pinMode(1, OUTPUT);
  TCCR0A = _BV(COM0A0) | _BV(COM0B1) | _BV(WGM01) | _BV(WGM00);
  TCCR0B = _BV(WGM02) | _BV(CS01);
  OCR0A = 64;
  OCR0B = 0;
} 

void loop()  { 
  int value=map(analogRead(3), 0, 1023, 0, 64);  
  OCR0B = value;
                
}

questo è il codice che genera un onda quadra a 16Khz con il timer 0, la risoluzione è di 6 bit.

Il codice per usare il timer 1 non funzionava è lo cancellato, ma comunque settavo solo il registro TCCR1 per abilitare il pwm, per impostare il clock prescaler a 2 e per settare l'uscita PB1 a 0 quando il timer faceva il match con i valori nei registri OCR1A e OCR1C, poi ho tentato di impostare qualcosa anche nel registro GTCCR ma alla fine non funzionava niente e non ho la minima idea di come fare.

ps. uso il core tiny, a me non interessa usare millis e delay, più che altro sfruttando il fattore di prescaler a 2 con il timer 1 riesco ad ottenere una risoluzione di 8 bit.

Mi pare che tu imposti il timer 0 in fast PWM mode, giusto? Però ricordati che il timer 1 ed il timer 0 sono un po’ diversi, vedo da datasheet.

Per impostare il prescale /2 sul timer 1 vedo che devi settare i bit CS13/12/11/10 del regitro GTCCR rispettivamente a 0/0/1/0.
Quindi
GTCCR &= ~((1<<CS13) | (1<<CS11) | (1<<CS10));
GTCCR |= (1<<CS11);

Tu vorresti un fast PWM con match top e bottom su ORC1A e OCR1B. Dovrei guardare il datasheet, non ho manipolato il timer 1 ma solo il timer 0.

Leo scusami forse intendevi dire che devo settare i bit CS1x del registro TCCR1 a 0010 per ottenere un prescaler a 2.

Il registro GTCCR non ha i bit CS1x da impostare, almeno cosi mi sembra di vedere da datasheet a pagina 93.

Comunque settavo quei bit ma il timer non andava comunque, più tardi vedo di postarti il codice che secondo me è corretto e che non va.

grazie

Sì, giusto. Ho preso il nome sbagliato del registro.

Non andava più.... ma poi attivavi il timer?
Di solito per attivare un timer io faccio così:

  • disattivo tutti gli interrupt sul timer (registro TIMSK)
  • imposto la modalità (counter, pwm, ecc... - bit COMxx)
  • imposto le info aggiuntive (bit WGMxx)
  • imposto il prescaler (bit CSxx)
  • imposto i valori iniziali dei registri interni
  • reimposto gli interrupt sul timer (TIMSK)

Leo ho riprovato anche con i passi che descrivi ma niente, il timer 1 non ne vuole sapere.
Peccato, ma comunque mi va bene anche una risoluzione di 6 bit, magari se scopri qualcosa fammi sapere.
Grazie

ulver85:
Leo ho riprovato anche con i passi che descrivi ma niente, il timer 1 non ne vuole sapere.
Peccato, ma comunque mi va bene anche una risoluzione di 6 bit, magari se scopri qualcosa fammi sapere.
Grazie

Il problema è che tra lavoro, figlioli e breadboard tutte occupate ultimamente sono un po' bloccato nei test :sweat_smile:
Vedo se riesco a pensare a qualcosa.

Si ma non preoccuparti, se ti capita di lavorare con il tiny85 magari gli dai uno sguardo se ti ricordi.

Non voglio mica spingerti con il forcone ahahahah ]:smiley:

Non conosco il core in uso, leo dice che il timer 1 è già usato e c'è da vedere se è possibile riservarsene l'uso esclusivo. Magari tu imposti i registri correttamente poi il core li reimposta a modo suo.

Ho dato uno sguardo al datasheet e vedo che il timer1 è molto più flessibile e permette anche una modalità detta tiny15 di cui nulla so.

al limite prova a scrivere codice e compilare senza linkare con il core.

Ciao.

A dire il vero stavo pensando di usare avr studio con avr dragon, li teoricamente non dovrei avere probelmi, appena ho un pò di tempo provo e vi faccio sapere.

Grazie per i consigli.

@mauro:

il timer 1 viene impostato di default nel core Tiny come contatore per le funzioni temporali delay e millis. Basta però alterare una variabile d'impostazione in un determinato file per spostare quelle funzioni sul timer 0 e poter accedere al timer 1 liberamente.
La modalità "attiny15" non è una modalità particolare, è una modalità introdotta per retrocompatibilità con i precedenti Tiny15 tutto quo.

@ulver:
apri il file /hardware/tiny/cores/tiny/core_build_options.h e modifica la riga 108 (o dintorni)

#define TIMER_TO_USE_FOR_MILLIS                   1

mettendo "0" per spostare delay sul timer 0.
Questa riga è nella sezione denominata:

Build options for the ATtiny85 processor

Fatto questo puoi manipolare il timer 1 senza interferenze da parte del core Tiny.

Prova con questo codice: non l’ho testato, non so se funziona (l’ho scritto leggendo il datasheet) e non so se funziona (come detto non ho un oscilloscopio):

TCCR1A |= (1<<PWM1A); //attiva il PWM su OC1A
TCCR1A |= (1<<COM1A0); //toggle on OCR1A 
TCCR1A |= ((1<<CS12) | (11<<CS10 ); //prescaler /64
OCR1A = 0;
OCR1C = 199;

Secondo la tabella a pag. 91 dovrebbe generare un segnale a 20 kHz.
Prima però fai quella modifica che ti ho detto al file del core Tiny in modo da togliere le funzioni temporali dal timer 1 e spostarle sul timer 0.