Ahoj vsem. Naprogramoval jsem si tuhle aplikaci (elektronické vyrhany) na PIC16F877A v MPLAB (kompilátor Hitech - C). Potřeboval bych pomoct, nejlépe dodělat problematiku sčítání sinusovek (viz zadání). Zbytek by měl být funkční. Potřebuji to mít do zítra hotové. Děkuji za pomoc.
[code]/*
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 <pic.h>
__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;
}
}
}[/code]
administrator: přejmenováno z “Sčítání jednotlivých sinusovek”
administrator: příspěvek byl upraven
Příště prosím použij náhled, pro ujištění, že vložený text nenaruší strukturu webu.
jirka.c (14 KB)