// *** Piepser V1.1 (c) Oliver Mezger 12.10.2010 *** #include #include // C-Dur Frequenzen als Periodendauer const unsigned int tone[]={1000000/264,1000000/297,1000000/330,1000000/352,1000000/396,1000000/440,1000000/495,1000000/528}; unsigned char keyOld = 0; // alter Tasten-Zustand unsigned char keyEnter,keyExit; // gedrueckte und losgelassene Tasten void spaceSound(){ // Unterprogramm fuer Testzwecke for(int i = 2000;i>100;i--){ OCR1A = i; for (int k = i/2; k>2;k--){ OCR1B = k; } } } void tonleiter(){ // Unterprogramm fuer Testzwecke for(int i=0;i<=7;i++){ OCR1A = tone[i]/2; OCR1B = tone[i]/4; _delay_ms(200); } } void keyCheck(){ // Tastaturabfrage mit Flankendedektion unsigned char keyTest,tmp; keyEnter = 0, keyExit = 0; keyTest = ~PIND & 0b01111111; // Einlesen und zurechtschieben if (keyOld != keyTest){ // hat sich was getan _delay_ms(10); // Prellen abwarten tmp = ~PIND & 0b01111111; // nochmal Einlesen und zurechtschieben if (tmp == keyTest){ // ist es stabil? keyEnter = (~keyOld) & keyTest; // steigende Flanke !alt und neu keyExit = keyOld & (~keyTest); // fallende Flanke alt und !neu keyOld = keyTest; } } } unsigned char tasteInWert(unsigned char n){ // Zuordnung einer Taste zu einem Ton switch (n){ case 128: return 0; case 64: return 1; case 32: return 2; case 16: return 3; case 8: return 4; case 4: return 5; case 2: return 6; case 1: return 7; default: return 8; } } int main(){ unsigned char i; DDRB = 0b00010000; // PB4 als Ausgang TCCR1A = 0b00100011; // Ausgang OC1B bei 0 setzen und bei OCR1B loeschen TCCR1B = 0b00011001; // Waveform Generation Mode: Fast PWM it OCR1A als Top, Timer mit CPU-CLK OCR1A = 1000; // Timer 1ms OCR1B = 500; // Impulslaenge 500us while (1){ // Endlosschleife keyCheck(); // Tastaturabfrage if (keyEnter > 0){ // wurde Taste gedrueckt? i = tasteInWert(keyEnter); // wandle in Tonzahl um if (i<8){ // wenn gueltiger Ton OCR1A = tone[i]; // Periodendauer OCR1B = tone[i]/2; // Impulsdauer DDRB |= 1<