/* Zadání: Po stisku tlačítka „0“ až „9“ bude k výstupu přidán sinusový signál 1,66 V šš, s frekvencí podle následující řady: [264, 297, 330, 352, 396, 440, 495, 528, 594, 660] Hz (noty cdefgahcde). Pokud bude již generován signál se stejnou frekvencí, odstraní se starý signál (slábnoucí) a nahradí se novým. Při držení tlačítka přidávaný signál drží svoji amplitudu. Při puštění tlačítka bude amplituda přidaného signálu lineárně klesat k nule. Doba poklesu je přesně 2 sekundy. Program musí využívat časovač a přerušení. Tedy program může současně generovat až 10 frekvencí (teoreticky). Pokud bylo stisknuto jedno tlačítko a následně dojde ke stisknutí jiného tlačítka, jednotlivé amplitudy sinusovek se sečtou. V případě kdy amplituda přesáhne max. možnou mez, může být výsledný signál ořezán. */ #include __CONFIG(HS & WDTDIS & LVPDIS); //---------------------definice-------------------// #define Drive RE0 #define LEDs PORTD #define KBO PORTA #define KBI PORTB #define Tlacitko RB4 //-----------------definice globálních proměných a konstant-------------------// unsigned int TMR1@ ((unsigned)&TMR1L); unsigned char Frekvence = 0; unsigned char Stlaceno = 0; unsigned char Tla[10] = {0,0,0,0,0,0,0,0,0,0}; unsigned char frek[] = {180, 160, 144, 135, 120, 108, 96, 90, 80, 72}; unsigned char sin[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char frekCit[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char del[] = {3, 3, 3, 3, 3, 3, 3, 3, 3, 3}; unsigned char snizeni[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; unsigned char stalStlac[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; //---------------definice pole SINUS------------------// const unsigned char sinus[] = {63,65,66,68,69,71,73,74,76,77,79,80,82,83,85,86,88,89,91,92,93,95,96,97,99,100,101,102,104,105,106,107,108,109,110,112,113,114,114,115,116,117,118,119,119,120,121,122,122,123,123,124,124,125,125,125,126,126,126,127,127,127,127,127,127,127,127,127,127,127,126,126,126,125,125,125,124,124,123,123,122,122,121,120,119,119,118,117,116,115,114,114,113,112,110,109,108,107,106,105,104,102,101,100,99,97,96,95,93,92,91,89,88,86,85,83,82,80,79,77,76,74,73,71,69,68,66,65,63,62,60,59,57,55,54,52,51,49,48,46,45,43,42,40,39,37,36,35,33,32,30,29,28,27,25,24,23,22,20,19,18,17,16,15,14,13,12,11,10,9,9,8,7,6,6,5,4,4,3,3,2,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,2,2,3,3,4,4,5,6,6,7,8,9,9,10,11,12,13,14,15,16,17,18,19,20,22,23,24,25,27,28,29,30,32,33,35,36,37,39,40,42,43,45,46,48,49,51,52,54,55,57,59,60,62}; //-------------------Funkce Delay chvilku čeká, mohlo by to být i kratší--------------// void Delay() { unsigned char Cas; while(Cas--) { } } //------------------Vrací číslo stisknuté klávesy---------------------// /*unsigned char GetKey() { KBO=0b00011100; // Řádek 0 (123) dej do nuly Delay(); // Chvilku počkej switch(KBI&0xE0) // Pokud je hodnota (KBI AND 0xE0) rovna z následujících uvedených { case 0b11000000:return 1; // Vrať jako výsledek funkce číslo 1 case 0b10100000:return 2; // Vrať jako výsledek funkce číslo 2 case 0b01100000:return 3; // Vrať jako výsledek funkce číslo 3 } KBO=0b00101100; Delay(); switch(KBI&0xE0) { case 0b11000000:return 4; case 0b10100000:return 5; case 0b01100000:return 6; } KBO=0b00110100; Delay(); switch(KBI&0xE0) { case 0b11000000:return 7; case 0b10100000:return 8; case 0b01100000:return 9; } KBO=0b00111000; Delay(); switch(KBI&0xE0) { case 0b11000000:return 0x81; // Vrať jako výsledek funkce číslo 0x81 case 0b10100000:return 10; case 0b01100000:return 0x82; } return 0; // Pokud jsem se dostali až sem, žádná klávesa nebyla stisknuta, vrať 0 } */ unsigned char GetKey() { TRISD=0; // PORTD jako výstupní TRISA=0xC3; // PORTA má výstup RA2-RA5 TRISE0=0; // RE0 je výstupní RBPU=0; // RB pull-up KBO=0b00011100; // Řádek 0 (123) dej do nuly Delay(); // Chvilku počkej if(!RB5) return 1; //klavesa 1 KBO=0b00101100; Delay(); if(!RB5) return 2; //klavesa 4 KBO=0b00110100; Delay(); if(!RB5) return 4; //klavesa 7 KBO=0b00111000; Delay(); if(!RB5) return 5; //klavesa * if(!RB4) return 6; //klavesa Tlačitko return 0; // Pokud jsem se dostali až sem, žádná klávesa nebyla stisknuta, vrati 0 } //-----------------Obsluha přerušeni---------------------------------// void interrupt Preruseni(void) { unsigned char Vysledek; ADIF=0; TMR1ON = 0; TMR1 -=207-6; TMR1IF=0; // A vynulovat přerušení, které nastavo od tohoto časovače TMR1ON = 1; char vysledek = 0; if(Tla[0] == 1) { frekCit[0]++; if(frekCit[0] == frek[0]) { frekCit[0]=0; if(stalStlac[0] == 1) { vysledek = sinus[sin[0]]; } else { vysledek = ((sinus[sin[0]])/del[0]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[0] >= 4) && (stalStlac[0] != 1)) { del[0] = del[0]+1; snizeni[0] = 0; } snizeni[0] = snizeni[0] + 1; if(del[0] == 128) { Tla[0] = 0; del[0] = 3; } sin[0] = sin[0]+1; if(sin[0] == 256) { sin[0]=0; } stalStlac[0] = 0; } } if(Tla[1] == 1) { frekCit[1]++; if(frekCit[1] == frek[1]) { frekCit[1]=0; if(stalStlac[1] == 1) { vysledek = sinus[sin[1]]; } else { vysledek = ((sinus[sin[1]])/del[1]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[1] >= 4) && (stalStlac[1] != 1) ) { del[1] = del[1] + 1; snizeni[1] = 0; } snizeni[1] = snizeni[1] + 1; if(del[1] == 128) { Tla[1] = 0; del[1] = 3; } sin[1]++; if(sin[1] == 256) { sin[1]=0; } stalStlac[1] = 0; } } if(Tla[2] == 1) { frekCit[2]++; if(frekCit[2] == frek[2]) { frekCit[2]=0; if(stalStlac[2] == 1) { vysledek = sinus[sin[2]]; } else { vysledek = ((sinus[sin[2]])/del[2]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[2] >= 5) && (stalStlac[2] != 1) ) { del[2] = del[2] + 1; snizeni[2] = 0; } snizeni[2] = snizeni[2] +1; if(del[2] == 128) { Tla[2] = 0; del[2] = 3; } sin[2]++; if(sin[2] == 256) { sin[2]=0; } stalStlac[2] = 0; } } if(Tla[3] == 1) { frekCit[3]++; if(frekCit[3] == frek[3]) { frekCit[3]=0; if(stalStlac[3] == 1) { vysledek = sinus[sin[3]]; } else { vysledek = ((sinus[sin[3]])/del[3]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[3] >= 5) && (stalStlac[3] != 1) ) { del[3] = del[3] + 1; snizeni[3] = 0; } snizeni[3] = snizeni[3] +1; if(del[3] == 128) { Tla[3] = 0; del[3] = 3; } sin[3]++; if(sin[3] == 256) { sin[3]=0; } stalStlac[3] = 0; } } if(Tla[4] == 1) { frekCit[4]++; if(frekCit[4] == frek[4]) { frekCit[4]=0; if(stalStlac[4] == 1) { vysledek = sinus[sin[4]]; } else { vysledek = ((sinus[sin[4]])/del[4]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[4] >= 6) && (stalStlac[4] != 1) ) { del[4] = del[4] + 1; snizeni[4] = 0; } snizeni[4] = snizeni[4] +1; if(del[4] == 128) { Tla[2] = 0; del[4] = 3; } sin[4]++; if(sin[4] == 256) { sin[4]=0; } stalStlac[4] = 0; } } if(Tla[5] == 1) { frekCit[5]++; if(frekCit[5] == frek[5]) { frekCit[5]=0; if(stalStlac[5] == 1) { vysledek = sinus[sin[5]]; } else { vysledek = ((sinus[sin[5]])/del[5]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[5] >= 7) && (stalStlac[5] != 1) ) { del[5] = del[5]+1; snizeni[5] = 0; } snizeni[5] = snizeni[5] +1; if(del[5] == 128) { Tla[5] = 0; del[5] = 3; } sin[5]++; if(sin[5] == 256) { sin[5]=0; } stalStlac[5] = 0; } } if(Tla[6] == 1) { frekCit[6]++; if(frekCit[6] == frek[6]) { frekCit[6]=0; if(stalStlac[6] == 1) { vysledek = sinus[sin[6]]; } else { vysledek = ((sinus[sin[6]])/del[6]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[6] >= 8) && (stalStlac[6] != 1) ) { del[6] = del[6]+1; snizeni[6] = 0; } snizeni[6] = snizeni[6] +1; if(del[6] == 128) { Tla[6] = 0; del[6] = 3; } sin[6]++; if(sin[6] == 256) { sin[6]=0; } stalStlac[6] = 0; } } if(Tla[7] == 1) { frekCit[7]++; if(frekCit[7] == frek[7]) { frekCit[7]=0; if(stalStlac[7] == 1) { vysledek = sinus[sin[7]]; } else { vysledek = ((sinus[sin[7]])/del[7]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[7] >= 8) && (stalStlac[7] != 1) ) { del[7] = del[7]+1; snizeni[7] = 0; } snizeni[7] = snizeni[7] +1; if(del[7] == 128) { Tla[7] = 0; del[7] = 3; } sin[7]++; if(sin[7] == 256) { sin[7]=0; } stalStlac[7] = 0; } } if(Tla[8] == 1) { frekCit[8]++; if(frekCit[8] == frek[8]) { frekCit[8]=0; if(stalStlac[8] == 1) { vysledek = sinus[sin[8]]; } else { vysledek = ((sinus[sin[8]])/del[8]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[8] >= 9) && (stalStlac[8] != 1) ) { del[8] = del[8]+1; snizeni[8] = 0; } snizeni[8] = snizeni[8] +1; if(del[8] == 128) { Tla[8] = 0; del[8] = 3; } sin[8]++; if(sin[8] >256) { sin[8]=0; } stalStlac[8] = 0; } } if(Tla[9] == 1) { frekCit[9]++; if(frekCit[9] == frek[9]) { frekCit[9]=0; if(stalStlac[9] == 1) { vysledek = sinus[sin[9]]; } else { vysledek = ((sinus[sin[9]])/del[9]); } CCP2Y=(vysledek&1); // LSB CCP2X=(vysledek&2); // další bit vysledek>>=2; // Tyto bity se už neberou do úvahy, odstranit CCPR2L=vysledek; // Zbytek do PWM if((snizeni[9] >= 10) && (stalStlac[9] != 1) ) { del[9] = del[9]+1; snizeni[9] = 0; } snizeni[9] = snizeni[9] +1; if(del[9] == 128) { Tla[9] = 0; del[9] = 3; } sin[9]++; if(sin[9] == 256) { sin[9]=0; } stalStlac[9] = 0; } } } //--------------------samotný program------------------------// void main(void) { ADCON1=0b01001110; // AN0 = Analog, ostatní digital TRISC1=0; // RC1 je výstupní TRISC2=0; RC2=1; TRISE0=0; TRISD=0; PORTD=0; TRISB=0b11111000; PORTB=0b00000111; RBPU=0; // RB pull-up //TRISA=0xC3; // PORTA má výstup RA2-RA5 PR2=0x3F; // Bude pouze 8 bitový PWM (FF by byl 10 bitový) CCPR2L=0x80; // Počáteční hodnota, nepodstatné, stejně se hned změní v přerušení // T2CON=0b00000100; // Zapnout časovač 2 CCP2CON=0b00001111; // CCP2 bude jako PWM // T1CON=0b00000001; // Spustit časovac 1 INTCON=0b11000000; // Povolit přerušení globalni PIE1=0b00000001; // Povolit přerušení od časovače 1 T2CON=0b00000100; // Zapnout časovač 2 T1CON=0b00000001; // Spustit časovac 1, preddelicka 1:1 while(1) { Stlaceno = GetKey(); //zavola funkci na zjisteni tlacitka a pak cislo tlacitka prepise do promene Tlacitko //while(GetKey()); //opatreni proti stalemu stisku tlacitka //Stlaceno = 1; if(Stlaceno == 0) { Tla[0] = 1; stalStlac[0] = 1; } if(Stlaceno == 1) { Tla[1] = 1; stalStlac[1] = 1; } if(Stlaceno == 2) { Tla[2] = 1; stalStlac[2] = 1; } if(Stlaceno == 3) { Tla[3] = 1; stalStlac[3] = 1; } if(Stlaceno == 4) { Tla[4] = 1; stalStlac[4] = 1; } if(Stlaceno == 5) { Tla[5] = 1; stalStlac[5] = 1; } if(Stlaceno == 6) { Tla[6] = 1; stalStlac[6] = 1; } if(Stlaceno == 7) { Tla[7] = 1; stalStlac[7] = 1; } if(Stlaceno == 8) { Tla[8] = 1; stalStlac[8] = 1; } if(Stlaceno == 9) { Tla[9] = 1; stalStlac[9] = 1; } } }