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.