• .
  • Willkommen im Forum!
  • Alles beim Alten...
  • Du hast kaum etwas verpasst ;-)
  • Jetzt noch sicherer mit HTTPS
Hallo, Gast! Anmelden Registrieren


Tiny Tone
#1
Alle Jahre wieder kriecht der 8-beinige Attiny25 aus der Versenkung hervor. Die aktuelle Reinkarnation präsentiert sich als batteriebetriebener TestTonGenerator. Also habe ich das Baby auf den Namen TinyTone getauft. Die Schaltung drum herum ist überschaubar und zur Abwechslung mal ausschließlich mit Durchsteckbauteilen realisiert.
Auf einer 50x100mm Platine wird das Ganze dann etwa so aussehen:
[attachment=2930]

   
...mit der Lizenz zum Löten!
 
Reply
#2
Dazu der Schaltplan

.pdf   TinyTone_sch.pdf (Größe: 33,69 KB / Downloads: 35)
...mit der Lizenz zum Löten!
 
Reply
#3
Dazu einige Erläuterungen
Ziel
war ein kleines, simples Gerät zum schnellen Durchchecken von Audio-Verstärkern, Lautsprechern usw. So etwas was man in den Servicekoffer wirft. Auf besondere Verzerrungsarmut wird dabei kein Wert gelegt, wichtig ist vielmehr ein möglichst stromsparender Betrieb für eine lange Batterie-Lebensdauer. Hier spielt der Attiny seine Stärken aus: Bei einem erlaubten Betriebsspannungsbereich von 2,7~5,5V kann man auf eine Vielzahl von Batterietypen zurückgreifen ohne den sonst obligatorischen on-board-Spannungsregler. Am geeignetsten erscheinen da Li-ThionylChlorid Batterien. Bei einer nahezu waagerechten Entladekurve um 3,6V sind im Gehäuse 1/2 AA immerhin 1200mAh zu haben - und das wären beim aktuellen Stromverbrauch um 2mA an die 600 Betriebsstunden mit einer Batterie.
Die Tonerzeugung (DDS)
erfolgt in software hier nach dem DDS-Verfahren, d.h. die Momentanwerte der Ausgangsspannung werden aus einer abgespeicherten Kurvenformtabelle zyklisch ausgegeben. Die jeweilige Frequenz ergibt sich allein aus der Sprungweite des Adresspointers. Wie beim Class-D-amp wird ein "digitales" PWM-Signal ausgegeben. Dies durchläuft ein Tiefpassfilter zur Rekonstruktion der analogen Kurvenform - damit entfällt der Digital-Analog-Wandler. Es wurde die max mögliche PWM-Abtastrate von 16kHz gewählt und dazu passend die höchste Audio-Frequenz auf 1kHz begrenzt. In Verbindung mit dem LC-Ausgangsfilter ist die Signalrekonstruktion recht brauchbar.
Wenn schon nicht mehr als 1kHz drin liegen, möchte man aber wenigstens ein paar tiefere Frequenzen zur Auswahl haben. Das stellt technisch nun kein Problem dar, es stehen die Subharmonischen im Oktavabstand zur Verfügung bis hinab auf 15Hz. Die Auswahl erfolgt mit dem FrequenzPotentiometer dessen Stellung mit Hilfe des internen AD-Wandler abgefragt und digitalisiert wird auf die zur Verfügung stehenden Festfrequenzen.
Der Totmannschalter (watchdog timer)
Vergißt man einmal das Gerät nach Gebrauch ab zu schalten, fährt es nach einer vorgegeben Zeit von selbst herunter. Eingestellt sind derzeit ca 30Minuten. Dieser Wert ist per Programm noch in einem größeren Bereich modifizierbar. Nach dem shutdown muß man zur Wiederbelebung aus- und wieder einschalten. Hierbei ist zu beachten, dass vor dem Einschalten die beiden 100uF Stützelkos entladen sein müssen - andernfalls kommt der erforderliche Reset nicht zustande und der uP bleibt hängen. Bei einem auf <1uA gefallenen Betriebsstrom würde das schon einige Zeit dauern, und deshalb schließt der Einschalter im Aus-Zustand die Betriebsspannung kurz!
Wo hingegen Dauerbetrieb gefordert wird, läßt sich der  watchdog timer auch sperren: Ausgelegt für Batteriespannungen < 4V wird er abgeschaltet bei 4-5,5V Betriebsspannung, so dass man mit einer USB-Speisung dieses Problem gar nicht hat. Für Batteriebetrieb hingegen braucht man nur den unteren Teilerwiderstand (R22) am ADC-Eingang (pin2) zu entfernen und gaukelt damit eine hinreichend große Betriebsspannung vor.
Program flashen
erfolgt über das SPI interface. Die SPI-Ports sind bei insgesamt 8pins natürlich nicht frei, aber so beschaltet dass die Programmierung im eingebauten Zustand funktioniert. Die Versorgung kann hierbei sowohl von der Batterie als auch über das Interface erfolgen (jumper stecken). Nach dem FlashVorgang startet das Programm automatisch.

Verzerrungsmessungen am Prototypen mit ARTA:
15Hz/0.48%
30Hz/0.33%
60Hz/0.31%
125Hz/0.52%
250Hz/0.6%
500Hz/0.92%
1000Hz/0.63%
...mit der Lizenz zum Löten!
 
Reply
#4
Feine Sache das, gefällt mir. Den Klirr bekommt man nicht noch kleiner? Mich wundert, warum die PWM nur mal 16kHz zulässt, das Teil kann doch vom internen Osc. 8MHz fahren. Wenn du den über die PLL (x8 + nachfolgend 1/4) ziehst, hast du sogar 16MHz. Am Ausgang der PLL stehen sogar 64MHz zur Verfügung, die mit dem Timer1 genutzt  werden können.

Referenz: https://ww1.microchip.com/downloads/en/D...asheet.pdf
Punkt 6.1.5 Seite 24

Kennst du den schon?

http://interface.khm.de/index.php/lab/in...generator/
 
Reply
#5
nett. Smile 
+
wie Chris schon meinte...der tiny25 sollte mit der PLL auf 64MHz genau 250kHz 8-bit-PWM machen. Wink
    Don't worry about getting older.  You're still gonna do dump stuff...only slower
 
Reply
#6
(15.01.2019, 01:55 PM)christianw. schrieb: Feine Sache das, gefällt mir. Den Klirr bekommt man nicht noch kleiner? Mich wundert, warum die PWM nur mal 16kHz zulässt, das Teil kann doch vom internen Osc. 8MHz fahren. Wenn du den über die PLL (x8 + nachfolgend 1/4) ziehst, hast du sogar 16MHz. Am Ausgang der PLL stehen sogar 64MHz zur Verfügung, die mit dem Timer1 genutzt  werden können.

Referenz: https://ww1.microchip.com/downloads/en/D...asheet.pdf
Punkt 6.1.5 Seite 24

Kennst du den schon?

http://interface.khm.de/index.php/lab/in...generator/

ok, komme ich später zu - jetzt ist erstmal technischer Dienst im Proberaum angesagt.
ansonsten - für 8 bit ist der THD ganz ok.
8MHz/512 = 16khz
Höhere Frequenz - egal wie, dürfte auch sofort die Stromaufnahme erhöhen - ist es das mir wert?
Wenn der Chinamann PCBs geliefert hat (status=fabricating), können ich ja hier welche im Club verteilen, und dann könnt Ihr mit der SW rumspielen.
...mit der Lizenz zum Löten!
 
Reply
#7
Der Stromverbrauch ist gleich, der Takt wird ja nur anders geroutet. Der interne Oszillator läuft ja eh mit 8MHz.
 
Reply
#8
(15.01.2019, 06:41 PM)voltwide schrieb:
(15.01.2019, 01:55 PM)christianw. schrieb: Feine Sache das, gefällt mir. Den Klirr bekommt man nicht noch kleiner? Mich wundert, warum die PWM nur mal 16kHz zulässt, das Teil kann doch vom internen Osc. 8MHz fahren. Wenn du den über die PLL (x8 + nachfolgend 1/4) ziehst, hast du sogar 16MHz. Am Ausgang der PLL stehen sogar 64MHz zur Verfügung, die mit dem Timer1 genutzt  werden können.

Referenz: https://ww1.microchip.com/downloads/en/D...asheet.pdf
Punkt 6.1.5 Seite 24

Kennst du den schon?

http://interface.khm.de/index.php/lab/in...generator/

ok, komme ich später zu - jetzt ist erstmal technischer Dienst im Proberaum angesagt.
ansonsten - für 8 bit ist der THD ganz ok.
8MHz/512 = 16khz
Höhere Frequenz - egal wie, dürfte auch sofort die Stromaufnahme erhöhen - ist es das mir wert?
Wenn der Chinamann PCBs geliefert hat (status=fabricating), können ich ja hier welche im Club verteilen, und dann könnt Ihr mit der SW rumspielen.

Zur Frage nach der Verbesserung des klirrgrades: Der PWM-Timer hat nur 8bit - und damit sind nur 256 Amplitudenwerte darstellbar.
...mit der Lizenz zum Löten!
 
Reply
#9
Naja, man könnte ja jittern. Big Grin
 
Reply
#10
Hab eben noch mal über höhere PWM-Abtastrate nachgedacht. Es ist ja nicht damit getan, den PWM-timer höher zu takten. Es muss ja auch jedesmal ein neues sample aus der lookup-Tabelle ausgegeben werden - und das geschieht derzeit im Interrupt im 16kHz Takt. Nun ist der IRQ recht kurz, bei unverändertem CPU-Takt dürfte also noch so ein Faktor 10 in etwa drin liegen bevor die CPU "zugestopft" wird. Wenn man also die Interruptdichte um den Faktor 8 erhöht (2.Timer?!) wären schon mal 8kHz machbar.
Also höherer timer-clock = höherer PWM-Takt & höhere IRQ-Dichte = insgesamt höhere Abtastrate bei gleicher CPU-Frequenz (ich denke gerade während des Schreibens).
Alternativ kann man den Ausgangsfilter um weitere Stufen erweitern und damit die Tiefpass-Eckfrequenz nach oben verschieben, s. Arduino Projekt. Das wollte ich aber aus Gründen der Einfachheit vermeiden.
...mit der Lizenz zum Löten!
 
Reply
#11
(15.01.2019, 01:55 PM)christianw. schrieb: Feine Sache das, gefällt mir. Den Klirr bekommt man nicht noch kleiner? Mich wundert, warum die PWM nur mal 16kHz zulässt, das Teil kann doch vom internen Osc. 8MHz fahren. Wenn du den über die PLL (x8 + nachfolgend 1/4) ziehst, hast du sogar 16MHz. Am Ausgang der PLL stehen sogar 64MHz zur Verfügung, die mit dem Timer1 genutzt  werden können.

Referenz: https://ww1.microchip.com/downloads/en/D...asheet.pdf
Punkt 6.1.5 Seite 24
Danke für den Link, man hat das Datenblatt hinsichtlich der pdf-Lesbarkeit deutlich verbessert.

"Both internal RC oscillator and PLL are switched off in power down and stand-by sleep modes"

Damit wäre Stromsparen im sleep modus also nicht möglich....
...mit der Lizenz zum Löten!
 
Reply
#12
>Damit wäre Stromsparen im sleep modus also nicht möglich.... 

hä?  sleep hat < 1uA....was willst da genau noch "sparen" ??
    Don't worry about getting older.  You're still gonna do dump stuff...only slower
 
Reply
#13
(16.01.2019, 02:12 AM)alfsch schrieb: >Damit wäre Stromsparen im sleep modus also nicht möglich.... 

hä?  sleep hat < 1uA....was willst da genau noch "sparen" ??

Nö, es ging ja darum die PLL zu nutzen - und die wird aber schon im standby Modus deaktiviert.
Den progagierten Stromverbrauch erreiche ich ja darüber dass der uP die meiste Zeit im standby-Mode verweilt.
Echter power-down nach WDT-TimeOut ist eine andere Baustelle.

Code:
/* A Very Basic USB/LiIon-Battery-Powered Audio Sine-Wave Test Generator
created: 2014-01-21
update: 2019-01-07a
author: VoltWide
target                                                       ATTINY25-20
clock frequency           ...............                    8Mhz/1 internal
fuses                                                        uncheck CLKDIV8
                                                             check untouch EEPROM
hfuse readout, bitEna=0                                       11010111b
WDTON = bit4                                                  disabled=safety level1

prototype data
output function                                              pwm sine
max output level, peak-peak                                  >90% of Vsupply
pwm sample rate                                              8MHz/512 = 16khz
output frequencies/THD                                       15Hz/0.48%
                                                             30Hz/0.33%
                                                             60Hz/0.31%
                                                             125Hz/0.52%
                                                             250Hz/0.6%
                                                             500Hz/0.92%
                                                             1000Hz/0.63%
power supply                                                 2.7~5.5V: USB, 3V-LiBatt, 2~3xAA..
power consumption active, no load, 2*ADC/17+17ms, LED        5V*2.68mA, 4V*2.05mA, 3V*1.41mA
power consumption sleep-idle, cli, max prr, PORTB=0          3V*0.7mA
Atmel specs page 166
power consumption idle @8MHz                                 5V*1.2mA
power consumption ref1.1.....................................2.7V*15uA
cpu load irq  on/off                                         7.4us/56.4us
eof battery charge threshold = watchdog disable              4V
UVLO shut down threshold                                     disabled
shut down current consumption                                <1uA

DIP8/SOIC8 multilevel-pinning:
pin1 PB5 PCINT5 /RESET ADC0 dW
pin2 PB3 PCINT3 XTAL1 CLKI /OC1B ADC3
pin3 PB4 PCINT4 XTAL2 CLKO OC1B ADC2
pin4 GND
pin5 PB0 MOSI DI SDA AIN0 OC0A /OC1A AREF PCINT0
pin6 PB1 MISO DO AIN1 OC0B OC1A PCINT1
pin7 PB2 SCK USCK SCL ADC1 T0 INT0 PCINT2
pin8 VCC
*/

#include <stdlib.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include <avr/wdt.h>


const __flash char SineTab[] = {                        // 8bit sinewave lookup table
0x80,0x83,0x86,0x89,0x8c,0x8f,0x92,0x95,0x98,0x9c,0x9f,0xa2,0xa5,0xa8,0xab,0xae,
0xb0,0xb3,0xb6,0xb9,0xbc,0xbf,0xc1,0xc4,0xc7,0xc9,0xcc,0xce,0xd1,0xd3,0xd5,0xd8,
0xda,0xdc,0xde,0xe0,0xe2,0xe4,0xe6,0xe8,0xea,0xec,0xed,0xef,0xf0,0xf2,0xf3,0xf5,
0xf6,0xf7,0xf8,0xf9,0xfa,0xfb,0xfc,0xfc,0xfd,0xfe,0xfe,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0xfe,0xfd,0xfc,0xfc,0xfb,0xfa,0xf9,0xf8,0xf7,
0xf6,0xf5,0xf3,0xf2,0xf0,0xef,0xed,0xec,0xea,0xe8,0xe6,0xe4,0xe2,0xe0,0xde,0xdc,
0xda,0xd8,0xd5,0xd3,0xd1,0xce,0xcc,0xc9,0xc7,0xc4,0xc1,0xbf,0xbc,0xb9,0xb6,0xb3,
0xb0,0xae,0xab,0xa8,0xa5,0xa2,0x9f,0x9c,0x98,0x95,0x92,0x8f,0x8c,0x89,0x86,0x83,
0x80,0x7c,0x79,0x76,0x73,0x70,0x6d,0x6a,0x67,0x63,0x60,0x5d,0x5a,0x57,0x54,0x51,
0x4f,0x4c,0x49,0x46,0x43,0x40,0x3e,0x3b,0x38,0x36,0x33,0x31,0x2e,0x2c,0x2a,0x27,
0x25,0x23,0x21,0x1f,0x1d,0x1b,0x19,0x17,0x15,0x13,0x12,0x10,0x0f,0x0d,0x0c,0x0a,
0x09,0x08,0x07,0x06,0x05,0x04,0x03,0x03,0x02,0x01,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x08,
0x09,0x0a,0x0c,0x0d,0x0f,0x10,0x12,0x13,0x15,0x17,0x19,0x1b,0x1d,0x1f,0x21,0x23,
0x25,0x27,0x2a,0x2c,0x2e,0x31,0x33,0x36,0x38,0x3b,0x3e,0x40,0x43,0x46,0x49,0x4c,
0x4f,0x51,0x54,0x57,0x5a,0x5d,0x60,0x63,0x67,0x6a,0x6d,0x70,0x73,0x76,0x79,0x7c
};
const __flash uint16_t FqTab[] = {
//64,128,256,512,1024,2048,4096,8192,16384,32768
63,126,250,526,1047,2089,4188                                   //2018-12-27 customized!!
};
const int8_t FrequIdxMax = 6;                                   //2018-12-27

// i/o mapping
#define pin1 (1<<PB5)
#define pin2 (1<<PB3)
#define pin3 (1<<PB4)
#define pin5 (1<<PB0)
#define pin6 (1<<PB1)
#define pin7 (1<<PB2)

#define OutSine pin6
#define OutChargeReq pin5
#define OutPoti pin7
#define InVcc pin2
#define InPoti pin3
//input divider Rhi/Rlo=10k/2k2 Cin=0 Vref=1V1 VBattMin=3V VBattMax=4V:
//Vin(max,min) = 0.72/0.54V
//ADCin(maxs,min) =167/125
#define VBattMax 167
#define VBattHyst 5
#define EmptyBattCountDown 200
//!!! 2count/sec:
#define WDTirqCountDown 3600

//++++++++ global vars

volatile uint16_t Phase16,PhaseOfs16,WDTirqCount;               // 2019-01-06
uint8_t PotiResult,VccResult,EmptyBattcount,FrequIdx,EnaGetVcc,LoopCount;    //2018-12-27

//++++++++ Initialisation

void Boot(void){
   //Timer
   GTCCR = (1<<TSM) | (1<<PSR0);                               // timer0: reset pre-scaler
   TCCR0A = (1<<COM0B1) | (1<<COM0B0) | (1<<WGM00);            // 2018-12-27 output pin6 only
   TCCR0B = ( 1<<CS00 );                                       // clk=cpuclk/1
   TCNT0 = 0;                                                  // clear counter
   OCR0A = 0;                                                  // clear pwm output compare register A
   OCR0B = 0;                                                  // clear pwm output compare register B
   TIMSK = (1<<TOIE0);                                         // timer0-irq on counter overflow
   GTCCR = 0;                                                  // start counter(s)
   //Ports
   MCUCR |= (1<<PUD);                                          // 2018-12-26 pullup,sleep=off, sleepmode=idle
   DDRB = OutSine | OutChargeReq | OutPoti;                    // 2018-12-26 output ports
   PINB = -1;                                                  // 2018-12-26 power reduction of dig input buffers
   DIDR0 = (1<<ADC0D) | (1<<ADC1D) | (1<<ADC2D) | (1<<ADC3D);  // 2018-12-26 dig inputs=off
   //ADC
   ADMUX = (1<<ADLAR) | (1<<REFS1) | (1<<MUX0) | (1<<MUX1);    // 2018-12-27 adcref=1V1, result left adj, in=ADC3/PB3/pin2
   ACSR = (1<<ACD);                                            // 2018-12-26 comp=off
   ADCSRA = 0;                                                 // 2018-12-26 ADCen,ADCstart,ADCtrig,ADCirq=off, adcclk=cpuclk/2
   ADCSRB = 0;                                                 // 2018-12-26 unipolar, polarity=tru,free running
   //Misc
   PRR = (1<<PRTIM1) | (1<<PRUSI) | (1<<PRADC);                // power timer1,usi,adc=off
   PhaseOfs16 = FqTab[FrequIdx];
   Phase16 = 0;
   LoopCount=-1;                                               // 2018-12-27!!
   WDTirqCount = WDTirqCountDown;                              // 2019-01-06
   EnaGetVcc=1;                                                // 2019-01-06
   sei();
  }
void ShutDown(void) {
   cli();                                                      // 2018-12-26
   ADCSRA = 0;                                                 // 2018-12-26 dis ADC???
   TCCR0A = 0;                                                 // 2018-12-27 disconn sine port from timer, PRIOR! to powersave
   MCUSR = 0;                                                  // 2019-01-06 clear WDRF
   WDTCR |= (1<<WDCE) | (1<<WDE);                              // 2019-01-06
   WDTCR = 0;                                                  // 2019-01-06 clear WDE
   ADMUX = 0;                                                  // 2019-01-06 disable ref1V1
   PRR = (1<<PRTIM0) | (1<<PRTIM1) | (1<<PRUSI) | (1<<PRADC);  // 2018-12-26 power timer0+1,usi,adc=off
   PORTB = 0;                                                  // 2018-12-26 LED=off
   set_sleep_mode(SLEEP_MODE_PWR_DOWN);                        // 2018-12-26
   sleep_enable();                                             // 2018-12-26
   sleep_cpu();                                                // shut down
}
ISR(WDT_vect){                                                  // ca 2x/s: autoclears WDIE, must be set again to avoid wdt-reset
   sleep_disable();                                            // wakeup!
   WDTirqCount--;                                              // 2019-01-07 shutdown not here, but in main loop
   WDTCR |= (1<<WDIE);                                         // continue wdt irq, not wdt reset
}
void WDTon(void) {                                              // 2019-01-06 p.45, safety level 1
   WDTCR = (1<<WDIE) | (1<<WDE) | (1<<WDP2) | (1<<WDP0);       // Watchdog timer 0.5sec ticker
   MCUSR |= (1<<WDRF);                                          // 2019-01-07 overrides WDE
}
void WDToff(void) {                                             // 2019-01-06 p.45, safety level 1, timed sequence:
   MCUSR = 0;                                                  // c.code example 8.4.2: clear WDRF
   WDTCR |= (1<<WDCE) | (1<<WDE);
   WDTCR = 0;                                                  // clear WDE
}
ISR(TIM0_OVF_vect) {                                            // DDS-irq: output next sound sample
   uint8_t Voltage,Phase8;                                     //2019-01-06
   Phase16 += PhaseOfs16;                                      //16bit phase pointer
   Phase8 = Phase16 >> 8;                                      // 8bit table index
   Voltage = (SineTab[Phase8]);                                // drive h-bridge:
   OCR0B = Voltage;                                            // 2018-12-27 sinewave true output
}
void GetPoti (void) {
   ADCSRA |= (1<<ADEN) | (1<<ADSC);                            // 2018-12-26 start ad-conversion fsample=clk/2 adcirq=off
   while (0 == (ADCSRA & (1<<ADIF)));                          // A/D-conversion
   ADCSRA |= (1<<ADIF);                                         // 2019-01-07
   PotiResult = ADCH;                                          // bit9..2 , 8bit result
   ADMUX = (1<<ADLAR) | (1<<REFS1) | (1<<MUX0) | (1<<MUX1);    // 2018-12-27 ref-1V1 early turn-on, ADC3=PB3
}
void GetVcc (void) {
   ADCSRA |= (1<<ADEN) | (1<<ADSC);                            //2019-01-06 start adc fsample=clk/2 adcirq=off
   while (0 == (ADCSRA & (1<<ADIF)));                          //
   ADCSRA |= (1<<ADIF);                                        // 2019-01-07
   VccResult = ADCH;                                           // bit9..2 , 8bit result
   ADMUX = (1<<ADLAR) | (1<<MUX1);                             // 2019-01-06 ref-1V1 early turn-off!!!
   if (VccResult>=VBattMax){
       WDToff();                                               // 2019-01-06 WDT=off
       WDTirqCount = WDTirqCountDown;                          // 2019-01-06
   }
   if (VccResult<=(VBattMax-VBattHyst)) {
       WDTon();                                                // 2019-01-06 hysteresis!! WDT=on
   }
}
void GetFrequ (void) {                                          // 2018-12-26
   FrequIdx = PotiResult>>5;                                   // 2018-12-26
   if (FrequIdx>FrequIdxMax)  FrequIdx=FrequIdxMax;            // 2018-12-27
   PhaseOfs16 = FqTab[FrequIdx];                               // 2018-12-26
}
//++++++++ Main Program

int main(void) {
   Boot();
   for (;;) {
       while (LoopCount!=0) {                                  // 2019-01-06 skip main loops
           LoopCount--;
           sleep_cpu();                                        // 2019-01-06 power down
       };                                                      // skip main program
       PRR &= ~(1<<PRADC);                                     // 2018-12-27 ADC-power-reduction=off
       PORTB |= OutPoti;                                       // 2019-01-06 tpulse=0
       if ( EnaGetVcc) {                                       // 1.pass: battery monitor first for max ref1V1 setup time
           GetVcc();
           EnaGetVcc=0;
       }
       else {                                                  // 2.pass
           GetPoti();
           GetFrequ();
           LoopCount=-1;                                       // 2019-01-06 done, skip main loops
           EnaGetVcc=1;                                        // 2019-01-06
           PORTB &= ~OutPoti;                                  // 2019-01-06 disconnect Vcc from poti
       }                                                       // 2019-01-06 tpulse=21.6us/16.2ms
   if (WDTirqCount==0) ShutDown();                             // 2019-01-06
       PRR = (1<<PRTIM1) | (1<<PRUSI) | (1<<PRADC);            // 2019-01-06 power timer1,usi,adc=off
       set_sleep_mode(SLEEP_MODE_IDLE);                        // 2019-01-06 cpu & i/o clocks active
       sleep_enable();
       sleep_cpu();                                            // 2019-01-06 power down
   }
}
...mit der Lizenz zum Löten!
 
Reply
#14
(16.01.2019, 02:21 AM)voltwide schrieb:
(16.01.2019, 02:12 AM)alfsch schrieb: >Damit wäre Stromsparen im sleep modus also nicht möglich.... 

hä?  sleep hat < 1uA....was willst da genau noch "sparen" ??

Nö, es ging ja darum die PLL zu nutzen - und die wird aber schon im standby Modus deaktiviert.
Den progagierten Stromverbrauch erreiche ich ja darüber dass der uP die meiste Zeit im standby-Mode verweilt.

Hmm, hmm die Ausgabe der PWM läuft also auch im Standby?
 
Reply
#15
(16.01.2019, 02:34 PM)christianw. schrieb:
(16.01.2019, 02:21 AM)voltwide schrieb:
(16.01.2019, 02:12 AM)alfsch schrieb: >Damit wäre Stromsparen im sleep modus also nicht möglich.... 

hä?  sleep hat < 1uA....was willst da genau noch "sparen" ??

Nö, es ging ja darum die PLL zu nutzen - und die wird aber schon im standby Modus deaktiviert.
Den progagierten Stromverbrauch erreiche ich ja darüber dass der uP die meiste Zeit im standby-Mode verweilt.

Hmm, hmm die Ausgabe der PWM läuft also auch im Standby?

Jau, so isses - die meiste Zeit verbringt der uP im StandbyModus. Der Timer Irq aktualisiert die Ausgabe und weckt jedesmal die CPU aus dem standby-Modus auf.
Wenn man etwas mehr Stromverbrauch in Kauf nehmen mag  - so ca 5mA - kann man natürlich mal an der oberen Frequenzgrenze drehen. Bei Betrieb o. Batterie aus ner aktiven USB - Buchse wäre das in jedem Falle egal - und selbst 200 Betriebsstunden / Batterieladung wären ja auch nicht zu verachten.
...mit der Lizenz zum Löten!
 
Reply
#16
"Both internal RC oscillator and PLL are switched off in power down and stand-by sleep modes"

Btw. Wie geht denn das mit deinem Setup zusammen, wenn das Teil gar keinen Takt mehr hat, da ja auch der Osc. Abgeschaltet ist? 32kHz hat der ja nicht.

Nach 7.1 im DB geht das mit der PLL im Idle-Mode, weil Timer/Interrupts weiter laufen. Sparen kann man noch mit Einstellungen im Power Reduction Register (PRR). Einen anderen Sleep-Mode mit funktionierenden internen Interrupts sehe ich ersteinmal nicht.
 
Reply
#17
Nachtrag: Mit der PLL kannst du den Chipper erstmal mit 16MHz fahren, die Timer1 entsprechend 64MHz. Wenn du jetzt noch per OSCCAL trimmst, kommst du bis ca. 30/120MHz hoch. Big Grin Den Eeprom solltest du dann aber nicht mehr nutzen.
 
Reply
#18
(16.01.2019, 10:43 PM)christianw. schrieb: Nachtrag: Mit der PLL kannst du den Chipper erstmal mit 16MHz fahren, die Timer1 entsprechend 64MHz. Wenn du jetzt noch per OSCCAL trimmst, kommst du bis ca. 30/120MHz hoch. Big Grin Den Eeprom solltest du dann aber nicht mehr nutzen.

Die PCBs sind da: Mo in der Nacht hochgeladen, Fr im Briefkasten! Unglaublich Wink
...mit der Lizenz zum Löten!
 
Reply
#19
Wo hast du bestellt, JLCPCB?
 
Reply
#20
(18.01.2019, 08:51 PM)christianw. schrieb: Wo hast du bestellt, JLCPCB?
Bin abonniert auf AllPCB - die versenden per DHL (und NICHT per DHL Express)
Die Kommunikation bei auftretenden Fertigungsproblemen funktioniert bestens.
Und schneller gehts einfach nicht.

Neues vom Attiny:
Hab mal die PLL angeworfen - der Stromverbrauch steigt etwas.
Aber an der TimerIrq-Rate ändert sich -
Nichts!
Und inzwischen weiß ich auch, warum.
PWM läuft ausschließlich über Timer0.
64MHz-PLL-periphal clock speist ausschließlich Timer1.
Bliebe also noch die Möglichkeit, den PLL-Takt als Systemtakt zu routen.
Dann aber wird er durch 4 geteilt - ergo im besten Falle komme ich von bisherigen 8 MHz auf 16MHz.
Kann irgendjemand dieses ernüchternde Resultat entkräften? Rolleyes
...mit der Lizenz zum Löten!
 
Reply