Wochenend-Projekt: elektronischer Würfel v1.06

Die Firmware vom Würfel habe ich optimiert. Nun fällt er in den Schlafmodus wenn er nicht gebraucht wird und verbraucht dann nur noch 0.06 µA. Nach dem Tastendruck wacht er wieder auf und wird vom Watchdog resetet.

/*
* Wuerfel_V01_06.c
*
* Created: 15.04.2018 20:57:00
* Author : Bernd
*
*
* Chip type: Attiny13a
* Clock frequency: SUT_CKSEL auf INTRCoSC_128KHZ_14CK_64MS (128kHz / 8 = 16kHz)
*
* +--------+
* [ rest (leer) (PB5) |1* 8| (VCC) Power ]
* [ Taster (PB3) |2 7| (PB2) LEDs - links unten | rechts oben ]
* [ LEDs - rechts unten | links oben (PB4) |3 6| (PB1) LEDs - mitte links | mitte rechts ]
* [ Ground (GND) |4 5| (PB0) LED1 ]
* +--------+
*
*/

#define F_CPU 12800UL //Dalay anpassen wegen Fusebit
//#define F_CPU 960000UL //Dalay anpassen wegen Fusebit

#define LED1_PIN PB0
#define Taster PB3
#define DELAY_MAX (512)
#define DELAY_MIN (0)

#include <avr/wdt.h>
#include <stdint.h>
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/power.h>
#include <avr/sleep.h>

int Augenanzahl = 0; // einfacher Zähler für Würfel Augenanzahl
uint16_t min, sek;

int StartStopAni(int AnzahlBlinken);

// Leere Interrupt-Routine
ISR(PCINT0_vect)
{
}



int main(void)
{

//Watchdog ausschalten!
MCUSR &= ~(1<<WDRF);
WDTCR |= (1<<WDCE) | (1<<WDE);
WDTCR = 0x00;

DDRB =((1<<LED1_PIN) | (1<<PB1) | (1<<PB2) | (1<<PB4)); // Ports auf Ausgang
DDRB= ~(1<<Taster); // Port auf Eingang
PORTB |= (1<<Taster); // Pullup für Eingang

StartStopAni(30);

PORTB =0b00001000;

while (1) // Endlos Schleife
{
for (min=10; min>=1; min--) //Schleifen-konstruckt, wegen Zeit bis zum einschlafen
{
for (sek=1500; sek>=1; sek--)
{
_delay_ms(50);

if (!(PINB & (1<<Taster))) // Abfrage ob Switch gedrückt
{
// Schleifenwerte nach betätigen der Taste wieder hoch setzen
min=10;
sek=1500;

PORTB =0b00001000;
_delay_ms(500); // kurze Pause - alle LEDs kurz aus, damit man sieht der Würfel würfelt.

switch(Augenanzahl) // i Auswerten
{
case 0:
{
// Zahl 1 --> i=0
PORTB =0b00000001;
break;
}
case 1:
{
// Zahl 2 --> i=1
PORTB =0b00000100;
break;
}
case 2:
{
// Zahl 3 --> i=2
PORTB =0b00000101;
break;
}
case 3:
{
// Zahl 4 --> i=3
PORTB =0b00010100;
break;
}
case 4:
{
// Zahl 5 --> i=4
PORTB =0b00010101;
break;
}
case 5:
{
//Zahl 6 --> i=5
PORTB =0b00010110;
break;
}
}

// Port wieder auf Eingang setzen (Pullup)
PORTB |= (1<<Taster);

}
Augenanzahl++; // bei jedem Schleifendurchlauf i Erhöhen
if (Augenanzahl==6) // Wenn i = 6 dann i wieder auf 0 setzen
{
Augenanzahl=0;
}
}

StartStopAni(30);

// Den ADC deaktivieren, brauchen wir nicht müsste aber pre Default aus sein.
power_adc_disable();

// Pin-Change Interrupt für die 4 Taster erlauben
GIMSK = (1<<PCIE);
PCMSK |= (1<<PB3);

sei();

PORTB =0b00001000; // Sollten LEDs noch Leuchten vor Schlafen ausschalten.

set_sleep_mode(SLEEP_MODE_PWR_DOWN);
sleep_mode();

// **************** Aufwachen und alles für den Reset über Watchdog vorbereiten ******
wdt_enable(WDTO_1S); // 1s Sekunden Watchdog einstellen
wdt_enable(WDTO_30MS); // 30ms Sekunden Watchdog einstellen

//tu nix und warte auf den Biss des Wachhundes
_delay_ms(5000); // Der Wachhund ist auf eine Sek gestellt. Im Delay sind es 5 Sekunden. - Also Reset
// wdt_reset();
}

}
return (0);
}




int StartStopAni(int AnzahlBlinken)
{
for (int blink=0; blink!=AnzahlBlinken; blink++) // Blinken bis der Watchdog dem Spuk ein Ende macht oder die AnzahlBlinken erreicht ist
{
PORTB ^= (1<<LED1_PIN); //Toogle (Ein-, Ausschalten der LED
_delay_ms(50); // Warten damit LED eine Change hat zu blinken
}
return (0);
}




// wdt_reset();

 

 

Dieser Beitrag wurde unter Elektronik, Microcontroller, Wochenend Projekte veröffentlicht. Setze ein Lesezeichen auf den Permalink.