S
saroch
Guest
Her er CCS C kode som jeg mottok skjemaet noen og jeg ønsker å endre denne koden fra 18f452 til 16f877.
men når jeg prøver å endre, så mange problemer har oppstått.
pls gi meg noen forslag om å konvertere for 16f877.
thx alle i forveien
Code:/************************************************* ****************************/
/ * * /
/ * RTTTL ringetone Player for Microchip Microcontrollers * /
/ * * /
/ * Dette programmet ble utviklet for å kjøres på PICDEM2 Plus demo bord fra * /
/ * Microchip. * /
/ * * /
/ * Usage: * /
/ * S3 - Velger Melody * /
/ * S2 - Starter / Stopper Melody * /
/ * * /
/ * Denne koden ble laget for en klokke hastighet 20MHz * /
/ * Målenheten var PIC18F452. * /
/ * Du kan bruke PIC16F877 ved å endre oppsettet av CCP1 til * /
/ * CCP_COMPARE_INT. Du må også veksle utdataene pin i * /
/ * CCP1 avbruddsordrelinje rutine. * /
/ * * /
/ * Mange av musikken ble lastet ned fra "www.mrtones.com" * /
/************************************************* ****************************/
# saken
# liste
# include "18F452.h"
# enheten *= 16# define CLOCKSPEED 20000000
# define CCP_COMPARE_TOGGLE_MATCH 2# bruke forsinkelse (klokke = CLOCKSPEED)
# sikringer HS, NOWDT, NOLVP, PUT/ / Ta denne filen etter vår # bruke forsinkelse
# include "lcd.c"# define TMR1_PRESCALE 8
# define NOTE_C_SHARP (((CLOCKSPEED / 4) / 277,18) / TMR1_PRESCALE) / / 277.18Hz
# define NOTE_D_SHARP (((CLOCKSPEED / 4) / 311,13) / TMR1_PRESCALE) / / 311,13 Hz
# define NOTE_F_SHARP (((CLOCKSPEED / 4) / 369,99) / TMR1_PRESCALE) / / 369,99 Hz
# define NOTE_G_SHARP (((CLOCKSPEED / 4) / 415,30) / TMR1_PRESCALE) / / 415,30 Hz
# define NOTE_A_SHARP (((CLOCKSPEED / 4) / 466,16) / TMR1_PRESCALE) / / 466,16 Hz# define NOTE_C (((CLOCKSPEED / 4) / 261,63) / TMR1_PRESCALE) / / 261,63 Hz
# define NOTE_D (((CLOCKSPEED / 4) / 293,66) / TMR1_PRESCALE) / / 293,66 Hz
# define NOTE_E (((CLOCKSPEED / 4) / 329,63) / TMR1_PRESCALE) / / 329,63 Hz
# define NOTE_F (((CLOCKSPEED / 4) / 349,23) / TMR1_PRESCALE) / / 349,23 Hz
# define NOTE_G (((CLOCKSPEED / 4) / 392,00) / TMR1_PRESCALE) / / 392,00 Hz
# define NOTE_A (((CLOCKSPEED / 4) / 440,00) / TMR1_PRESCALE) / / 440,00 Hz
# define NOTE_B (((CLOCKSPEED / 4) / 493,88) / TMR1_PRESCALE) / / 493,88 Hz
# define NOTE_SILENCE 0# define DURATION_32 5 / / Varighet = 2 ^ x
# define DURATION_16 4 / / Varighet = 2 ^ x
# define DURATION_8 3 / / Varighet = 2 ^ x
# define DURATION_4 2 / / Varighet = 2 ^ x
# define DURATION_2 1 / / Varighet = 2 ^ x
# define DURATION_1 0 / / Varighet = 2 ^ xtypedef enum
(
SILENTNIGHT,
JINGLEBELLS,
LAST_MELODY
) Melodier;typedef struct
(
int Head;
int Tail;
int Count;
) NOTESTAT;typedef struct
(
lange notat;
langvarig;
) NOTE_DEF;struct
(
int TRISC0: 1;
int TRISC1: 1;
int TRISC2: 1;
int TRISC3: 1;
int TRISC4: 1;
int TRISC5: 1;
int TRISC6: 1;
int TRISC7: 1;
) TRISCbits;
# finne TRISCbits = 0xF94lang TMR1;
# finne TMR1 = 0xFCEint TMR1L;
# finne TMR1L = 0xFCEint TMR1H;
# finne TMR1H = 0xFCFint TMR0;
# finne TMR0 = 0xFD6# define MAX_NOTE_BUFFER_SIZE 4
# define NOTE_ROLLOVER_MASK 0b00000011
NOTE_DEF NoteBuffer [MAX_NOTE_BUFFER_SIZE];
NOTESTAT Notestat = (0,0,0);lang DurationCount = 0;
int Tempo = 0;
lang Note_Ticks = 0;
Melodier Melody_Pointer;
lang Note_Index = 0xFFFF;
Boolsk PlayMelodyFlag = TRUE;
int Read_Button_Count = 0;const struct
(
char tune [192];
int defaultoctave;
int defaultduration;
int tempo;
) SilentNight = (
( "F #., 8g #, F #, d #. side, f #., 8g #, F #, d #. side, 2c # 6, C # 6, en #. side, 2b, b, f #. , P., 2g #, G #, b., 8a #, G #, F #., 8g #, F #, d #. side, 2g #, G #, b., 8a #, G #, F #., 8g # f # d #. side, 2c # 6, C # 6, e.6, 8c # 6, A #, 2b., 2d # 6, p., b, f #, D #, F #., 8e, C #, b .4,1 p "),
5,
DURATION_4,
140
);const struct
(
char tune [202];
int defaultoctave;
int defaultduration;
int tempo;
) JingleBells = (
( "8e., 8e., E., 8e., 8e., E., 8e., 8g., C, 16d., 2e, p, 8f., 8f., F, 16f., 8f., 8e ., 8e., 16e., 16e., 8e., 8d., 8d., 8e., d., G., 8e., 8e., E., 8e., 8e., E., 8e., 8g., c, 16d., 2e, p, 8f., 8f., f, 16f., 8f., 8e., 8e., 16e., 16e., 8g., 8g., 8f., 8d., c., 1p "),
5,
DURATION_4,
180
);/ * Funksjon prototyper * /
void InitTimer (void);
int PlayMelody ();
void PlayNote (lang oppmerksom int oktav, int varighet);
char get_char_from_tune (lang index);
int get_tempo (void);
int get_defaultoctave (void);
int get_defaultduration (void);
void display_melody_name (void);
void Melody_Task (void);
void Button_Task (void);
void Check_Button_Press (void);//------------------------------------------------ -----------------------------
/ / Start of Code
//------------------------------------------------ -----------------------------/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void main (void)
(
TRISCbits.TRISC2 = 0;
InitTimer ();
enable_interrupts (GLOBAL);
lcd_init ();
Melody_Pointer = JINGLEBELLS;
display_melody_name ();
mens (1)
(
Button_Task ();
Melody_Task ();
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer spille av en melodi
RETURN: Ekte hvis melodi er fortsatt aktiv eller usann hvis komplett
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int PlayMelody (void)
(int oktav = 0;
int lengde = 0;
lange notat = 0;/ / Sjekk for en gyldig Melody
if (Melody_Pointer> = LAST_MELODY)
(
/ / Reset melodien til starten
Melody_Pointer = 0;
Note_Index = 0xFFFF;
)/ / Load notater mens vi har nok plass
while (Notestat.Count <MAX_NOTE_BUFFER_SIZE)
(/ / Er dette første notatet?
if (Note_Index == 0xFFFF)
(
display_melody_name ();
Tempo = get_tempo ();
Note_Index = 0;
)/ / Set Default varighet
varighet = get_defaultduration ();
/ / Set Default oktav
oktav = get_defaultoctave ();/ / Spill litt slience mellom notater
if (get_char_from_tune (Note_Index) == ',')
(
PlayNote (0, 4, DURATION_32);
Note_Index ;
return (true);
)/ / Vi sjekker varigheten
else if ((get_char_from_tune (Note_Index) =='3 ') & & (get_char_from_tune (Note_Index 1) =='2'))
(
varighet = DURATION_32;
Note_Index = 2;
)
else if ((get_char_from_tune (Note_Index) =='1 ') & & (get_char_from_tune (Note_Index 1) =='6'))
(
varighet = DURATION_16;
Note_Index = 2;
)
else if (get_char_from_tune (Note_Index) =='8 ')
(
varighet = DURATION_8;
Note_Index ;
)
else if (get_char_from_tune (Note_Index) =='4 ')
(
varighet = DURATION_4;
Note_Index ;
)
else if (get_char_from_tune (Note_Index) =='2 ')
(
varighet = DURATION_2;
Note_Index ;
)
else if (get_char_from_tune (Note_Index) =='1 ')
(
varighet = DURATION_1;
Note_Index ;
)/ / Nå får vi notatet
bryteren (get_char_from_tune (Note_Index ))
(
case 'c':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_C_SHARP;
Note_Index ;
)
ellers
note = NOTE_C;
break;
case 'd':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_D_SHARP;
Note_Index ;
)
ellers
note = NOTE_D;
break;
case 'e':
note = NOTE_E;
break;
case 'f':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_F_SHARP;
Note_Index ;
)
ellers
note = NOTE_F;
break;
case "g":
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_G_SHARP;
Note_Index ;
)
ellers
note = NOTE_G;
break;
case 'en':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_A_SHARP;
Note_Index ;
)
ellers
note = NOTE_A;
break;
case 'b':
note = NOTE_B;
break;
case 'P': / / slience
note = NOTE_SILENCE;
break;
)/ / Se om dette notatet er 1,5 X varigheten
if (get_char_from_tune (Note_Index) == '.)
(
/ / Bruk MSB å betegne 1,5 X
Varighet | = 0x80;
Note_Index ;
)/ / Get oktav
bryteren (get_char_from_tune (Note_Index))
(
tilfelle'4 ':
oktav = 4;
Note_Index ;
break;
case "5. ':
oktav = 5;
Note_Index ;
break;
tilfelle'6 ':
oktav = 6;
Note_Index ;
break;
tilfelle'7 ':
oktav = 7;
Note_Index ;
break;
standard:
break;
)/ / Iblant varigheten multiplier kommer etter oktav
if (get_char_from_tune (Note_Index) == '.)
(
/ * Varighet 1,5 X * /
Varighet | = 0x80;
Note_Index ;
)/ / Play notatet (vi faktisk bare legger det i en buffer
PlayNote (notat, oktav, varighet);/ / Er dette slutten?
if (get_char_from_tune (Note_Index) == 0)
(
Note_Index = 0xFFFF;
return (FALSE);
)
return (true);
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void PlayNote (lang oppmerksom int oktav, int varighet)
(
lang duration_count;/ / Process oktav
bryteren (oktav)
(
sak 4:
break;
case 5:
note = oppmerksom>> 1;
break;
sak 6:
note = oppmerksom>> 2;
break;
case 7:
note = oppmerksom>> 4;
break;
)/ / Process Merk Varighet
duration_count = 256;
duration_count>> = (varighet & 0x7F);/ / Hvis Varigheten er 1,5 X legge ,5 til varighet
if (varighet og 0x80)
duration_count = (duration_count>> 1);/ / Legg merke til vår buffer
NoteBuffer [Notestat.Tail]. Oppmerksom = notat;
NoteBuffer [Notestat.Tail]. Varighet = duration_count;
Notestat.Tail ;
Notestat.Tail & = NOTE_ROLLOVER_MASK;
Notestat.Count ;
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void InitTimer (void)
(
setup_timer_0 (RTCC_DIV_256 | RTCC_8_BIT);
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);
setup_timer_2 (T2_DIV_BY_4, 250, 5);enable_interrupts (INT_CCP1);
enable_interrupts (INT_TIMER0);
enable_interrupts (INT_TIMER2);
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
char get_char_from_tune (lang indeksen)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.tune [index]);
break;
tilfelle JINGLEBELLS:
return (JingleBells.tune [index]);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int get_tempo (void)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.tempo);
break;
tilfelle JINGLEBELLS:
return (JingleBells.tempo);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int get_defaultoctave (void)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.defaultoctave);
break;
tilfelle JINGLEBELLS:
return (JingleBells.defaultoctave);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int get_defaultduration (void)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.defaultduration);
break;
tilfelle JINGLEBELLS:
return (JingleBells.defaultduration);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void Melody_Task (void)
(
if (PlayMelodyFlag)
(
if (! PlayMelody ())
Melody_Pointer ;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen viser tittelen på melodien på LCD
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void display_melody_name (void)
(
/ / Clear skjermen og kontrollere at vi er på toppen
lcd_putc ( "\ f");
lcd_gotoxy (0,1);/ / Bruk vår globale Melody_Pointer å bestemme tittelen på nåværende tune
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
lcd_putc ( "Silent Night");
break;
tilfelle JINGLEBELLS:
lcd_putc ( "JingleBells");
break;
standard:
break;
)
)/ * ************************************************ *************************
DESCRIPTION: Button Oppgaver
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void Button_Task (void)
(
if (! Read_Button_Count)
(
Read_Button_Count = 30;
Check_Button_Press ();
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void Check_Button_Press (void)
(
static int debounce_count = 4;
static int stabilt = 0xFF;
static int siste = 0xFF;
int trans_low;
int gjeldende = 0xFF;
Boolsk endre = FALSE;/ / Les gjeldende tilstand knappene
if (! inngang (PIN_A4))
bit_clear (strøm, 2);if (! inngang (PIN_B0))
bit_clear (aktuell, 3);/ / Se om de har endret
if (gjeldende! = sist)
(
siste = gjeldende;
endre = TRUE;
)/ / Hvis de har endret deretter tilbakestille våre counter
if (endre)
(
debounce_count = 4;
)
/ / Hver gang de er stabile, så decrement våre teller
else if (debounce_count)
(
debounce_count -;
)
/ / De har vært stabile lenge nok så handle på dem
else if (gjeldende! = stabile)
(
/ / Få høy overganger
trans_low = ((stabil ^ nåværende) og stabile);if (bit_test (trans_low, 2))
PlayMelodyFlag =!
PlayMelodyFlag;
if (bit_test (trans_low, 3))
(
Melody_Pointer ;
if (Melody_Pointer> = LAST_MELODY)
Melody_Pointer = 0;
Note_Index = 0xFFFF;
display_melody_name ();
)
stabil = gjeldende;
)
)//------------------------------------------------ ----------------------------
/ / ISR rutiner
//------------------------------------------------ ----------------------------
# int_ccp1
/ * ************************************************ *************************
Beskrivelse: Denne funksjonen kontrollerer PWM av Piezo høyttaler
RETURN: ingen
Algoritme: ingen
Merknader: Hvis du ikke ønsker å bruke C2 som utgang, så du må
for å veksle din utgang her. Kontroller at du endrer CCP
oppsett ikke å slå C2 utgang hvis dette er tilfelle
************************************************** ************************* * /
void ccp1_isr (void)
(
CCP_1 = Note_Ticks;
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen brukes for å kontrollere varigheten av notatet
RETURN: ingen
Algoritme: ingen
MERKNADER: jeg lagre notatene i en buffer slik at de viktigste loop har andre
tid til å gjøre ting uten å sitte på vent til et notat til
fullført.
************************************************** ************************* * /
# int_timer0
void timer0_isr (void)
(
/ / Forhåndslasting en verdi for TMR0 slik at vi kan styre hvor lang tid det tar å
/ / Utløse en avbruddsordrelinje
TMR0 = Tempo;/ / Er et notat spille?
if (DurationCount)
(
DurationCount -;
if (! DurationCount)
setup_ccp1 (CCP_OFF);
)
/ / Note er ferdig med å spille, har vi mer i vår buffer?
else if (Notestat.Count)
(
DurationCount = NoteBuffer [Notestat.Head]. Varighet;
Note_Ticks = NoteBuffer [Notestat.Head]. Notat;
Notestat.Count--;
Notestat.Head ;
Notestat.Head & = NOTE_ROLLOVER_MASK;
CCP_1 = TMR1 Note_Ticks;
if (Note_Ticks)
(
/ * Oppsett av CCP modulen å veksle utdataene pin c2 * /
setup_ccp1 (CCP_COMPARE_TOGGLE_MATCH);
)
/ / Nei, vi er alle gjennom så deaktivere PWM
ellers
(
setup_ccp1 (CCP_OFF);
)
)
)# int_timer2
/ * ************************************************ *************************
Beskrivelse: Denne funksjonen er vårt system tick satt til 1ms
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void timer2_isr (void)
(
if (Read_Button_Count)
(
Read_Button_Count -;
)
)
men når jeg prøver å endre, så mange problemer har oppstått.
pls gi meg noen forslag om å konvertere for 16f877.
thx alle i forveien
Code:/************************************************* ****************************/
/ * * /
/ * RTTTL ringetone Player for Microchip Microcontrollers * /
/ * * /
/ * Dette programmet ble utviklet for å kjøres på PICDEM2 Plus demo bord fra * /
/ * Microchip. * /
/ * * /
/ * Usage: * /
/ * S3 - Velger Melody * /
/ * S2 - Starter / Stopper Melody * /
/ * * /
/ * Denne koden ble laget for en klokke hastighet 20MHz * /
/ * Målenheten var PIC18F452. * /
/ * Du kan bruke PIC16F877 ved å endre oppsettet av CCP1 til * /
/ * CCP_COMPARE_INT. Du må også veksle utdataene pin i * /
/ * CCP1 avbruddsordrelinje rutine. * /
/ * * /
/ * Mange av musikken ble lastet ned fra "www.mrtones.com" * /
/************************************************* ****************************/
# saken
# liste
# include "18F452.h"
# enheten *= 16# define CLOCKSPEED 20000000
# define CCP_COMPARE_TOGGLE_MATCH 2# bruke forsinkelse (klokke = CLOCKSPEED)
# sikringer HS, NOWDT, NOLVP, PUT/ / Ta denne filen etter vår # bruke forsinkelse
# include "lcd.c"# define TMR1_PRESCALE 8
# define NOTE_C_SHARP (((CLOCKSPEED / 4) / 277,18) / TMR1_PRESCALE) / / 277.18Hz
# define NOTE_D_SHARP (((CLOCKSPEED / 4) / 311,13) / TMR1_PRESCALE) / / 311,13 Hz
# define NOTE_F_SHARP (((CLOCKSPEED / 4) / 369,99) / TMR1_PRESCALE) / / 369,99 Hz
# define NOTE_G_SHARP (((CLOCKSPEED / 4) / 415,30) / TMR1_PRESCALE) / / 415,30 Hz
# define NOTE_A_SHARP (((CLOCKSPEED / 4) / 466,16) / TMR1_PRESCALE) / / 466,16 Hz# define NOTE_C (((CLOCKSPEED / 4) / 261,63) / TMR1_PRESCALE) / / 261,63 Hz
# define NOTE_D (((CLOCKSPEED / 4) / 293,66) / TMR1_PRESCALE) / / 293,66 Hz
# define NOTE_E (((CLOCKSPEED / 4) / 329,63) / TMR1_PRESCALE) / / 329,63 Hz
# define NOTE_F (((CLOCKSPEED / 4) / 349,23) / TMR1_PRESCALE) / / 349,23 Hz
# define NOTE_G (((CLOCKSPEED / 4) / 392,00) / TMR1_PRESCALE) / / 392,00 Hz
# define NOTE_A (((CLOCKSPEED / 4) / 440,00) / TMR1_PRESCALE) / / 440,00 Hz
# define NOTE_B (((CLOCKSPEED / 4) / 493,88) / TMR1_PRESCALE) / / 493,88 Hz
# define NOTE_SILENCE 0# define DURATION_32 5 / / Varighet = 2 ^ x
# define DURATION_16 4 / / Varighet = 2 ^ x
# define DURATION_8 3 / / Varighet = 2 ^ x
# define DURATION_4 2 / / Varighet = 2 ^ x
# define DURATION_2 1 / / Varighet = 2 ^ x
# define DURATION_1 0 / / Varighet = 2 ^ xtypedef enum
(
SILENTNIGHT,
JINGLEBELLS,
LAST_MELODY
) Melodier;typedef struct
(
int Head;
int Tail;
int Count;
) NOTESTAT;typedef struct
(
lange notat;
langvarig;
) NOTE_DEF;struct
(
int TRISC0: 1;
int TRISC1: 1;
int TRISC2: 1;
int TRISC3: 1;
int TRISC4: 1;
int TRISC5: 1;
int TRISC6: 1;
int TRISC7: 1;
) TRISCbits;
# finne TRISCbits = 0xF94lang TMR1;
# finne TMR1 = 0xFCEint TMR1L;
# finne TMR1L = 0xFCEint TMR1H;
# finne TMR1H = 0xFCFint TMR0;
# finne TMR0 = 0xFD6# define MAX_NOTE_BUFFER_SIZE 4
# define NOTE_ROLLOVER_MASK 0b00000011
NOTE_DEF NoteBuffer [MAX_NOTE_BUFFER_SIZE];
NOTESTAT Notestat = (0,0,0);lang DurationCount = 0;
int Tempo = 0;
lang Note_Ticks = 0;
Melodier Melody_Pointer;
lang Note_Index = 0xFFFF;
Boolsk PlayMelodyFlag = TRUE;
int Read_Button_Count = 0;const struct
(
char tune [192];
int defaultoctave;
int defaultduration;
int tempo;
) SilentNight = (
( "F #., 8g #, F #, d #. side, f #., 8g #, F #, d #. side, 2c # 6, C # 6, en #. side, 2b, b, f #. , P., 2g #, G #, b., 8a #, G #, F #., 8g #, F #, d #. side, 2g #, G #, b., 8a #, G #, F #., 8g # f # d #. side, 2c # 6, C # 6, e.6, 8c # 6, A #, 2b., 2d # 6, p., b, f #, D #, F #., 8e, C #, b .4,1 p "),
5,
DURATION_4,
140
);const struct
(
char tune [202];
int defaultoctave;
int defaultduration;
int tempo;
) JingleBells = (
( "8e., 8e., E., 8e., 8e., E., 8e., 8g., C, 16d., 2e, p, 8f., 8f., F, 16f., 8f., 8e ., 8e., 16e., 16e., 8e., 8d., 8d., 8e., d., G., 8e., 8e., E., 8e., 8e., E., 8e., 8g., c, 16d., 2e, p, 8f., 8f., f, 16f., 8f., 8e., 8e., 16e., 16e., 8g., 8g., 8f., 8d., c., 1p "),
5,
DURATION_4,
180
);/ * Funksjon prototyper * /
void InitTimer (void);
int PlayMelody ();
void PlayNote (lang oppmerksom int oktav, int varighet);
char get_char_from_tune (lang index);
int get_tempo (void);
int get_defaultoctave (void);
int get_defaultduration (void);
void display_melody_name (void);
void Melody_Task (void);
void Button_Task (void);
void Check_Button_Press (void);//------------------------------------------------ -----------------------------
/ / Start of Code
//------------------------------------------------ -----------------------------/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void main (void)
(
TRISCbits.TRISC2 = 0;
InitTimer ();
enable_interrupts (GLOBAL);
lcd_init ();
Melody_Pointer = JINGLEBELLS;
display_melody_name ();
mens (1)
(
Button_Task ();
Melody_Task ();
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer spille av en melodi
RETURN: Ekte hvis melodi er fortsatt aktiv eller usann hvis komplett
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int PlayMelody (void)
(int oktav = 0;
int lengde = 0;
lange notat = 0;/ / Sjekk for en gyldig Melody
if (Melody_Pointer> = LAST_MELODY)
(
/ / Reset melodien til starten
Melody_Pointer = 0;
Note_Index = 0xFFFF;
)/ / Load notater mens vi har nok plass
while (Notestat.Count <MAX_NOTE_BUFFER_SIZE)
(/ / Er dette første notatet?
if (Note_Index == 0xFFFF)
(
display_melody_name ();
Tempo = get_tempo ();
Note_Index = 0;
)/ / Set Default varighet
varighet = get_defaultduration ();
/ / Set Default oktav
oktav = get_defaultoctave ();/ / Spill litt slience mellom notater
if (get_char_from_tune (Note_Index) == ',')
(
PlayNote (0, 4, DURATION_32);
Note_Index ;
return (true);
)/ / Vi sjekker varigheten
else if ((get_char_from_tune (Note_Index) =='3 ') & & (get_char_from_tune (Note_Index 1) =='2'))
(
varighet = DURATION_32;
Note_Index = 2;
)
else if ((get_char_from_tune (Note_Index) =='1 ') & & (get_char_from_tune (Note_Index 1) =='6'))
(
varighet = DURATION_16;
Note_Index = 2;
)
else if (get_char_from_tune (Note_Index) =='8 ')
(
varighet = DURATION_8;
Note_Index ;
)
else if (get_char_from_tune (Note_Index) =='4 ')
(
varighet = DURATION_4;
Note_Index ;
)
else if (get_char_from_tune (Note_Index) =='2 ')
(
varighet = DURATION_2;
Note_Index ;
)
else if (get_char_from_tune (Note_Index) =='1 ')
(
varighet = DURATION_1;
Note_Index ;
)/ / Nå får vi notatet
bryteren (get_char_from_tune (Note_Index ))
(
case 'c':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_C_SHARP;
Note_Index ;
)
ellers
note = NOTE_C;
break;
case 'd':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_D_SHARP;
Note_Index ;
)
ellers
note = NOTE_D;
break;
case 'e':
note = NOTE_E;
break;
case 'f':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_F_SHARP;
Note_Index ;
)
ellers
note = NOTE_F;
break;
case "g":
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_G_SHARP;
Note_Index ;
)
ellers
note = NOTE_G;
break;
case 'en':
if (get_char_from_tune (Note_Index) == '#')
(
note = NOTE_A_SHARP;
Note_Index ;
)
ellers
note = NOTE_A;
break;
case 'b':
note = NOTE_B;
break;
case 'P': / / slience
note = NOTE_SILENCE;
break;
)/ / Se om dette notatet er 1,5 X varigheten
if (get_char_from_tune (Note_Index) == '.)
(
/ / Bruk MSB å betegne 1,5 X
Varighet | = 0x80;
Note_Index ;
)/ / Get oktav
bryteren (get_char_from_tune (Note_Index))
(
tilfelle'4 ':
oktav = 4;
Note_Index ;
break;
case "5. ':
oktav = 5;
Note_Index ;
break;
tilfelle'6 ':
oktav = 6;
Note_Index ;
break;
tilfelle'7 ':
oktav = 7;
Note_Index ;
break;
standard:
break;
)/ / Iblant varigheten multiplier kommer etter oktav
if (get_char_from_tune (Note_Index) == '.)
(
/ * Varighet 1,5 X * /
Varighet | = 0x80;
Note_Index ;
)/ / Play notatet (vi faktisk bare legger det i en buffer
PlayNote (notat, oktav, varighet);/ / Er dette slutten?
if (get_char_from_tune (Note_Index) == 0)
(
Note_Index = 0xFFFF;
return (FALSE);
)
return (true);
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void PlayNote (lang oppmerksom int oktav, int varighet)
(
lang duration_count;/ / Process oktav
bryteren (oktav)
(
sak 4:
break;
case 5:
note = oppmerksom>> 1;
break;
sak 6:
note = oppmerksom>> 2;
break;
case 7:
note = oppmerksom>> 4;
break;
)/ / Process Merk Varighet
duration_count = 256;
duration_count>> = (varighet & 0x7F);/ / Hvis Varigheten er 1,5 X legge ,5 til varighet
if (varighet og 0x80)
duration_count = (duration_count>> 1);/ / Legg merke til vår buffer
NoteBuffer [Notestat.Tail]. Oppmerksom = notat;
NoteBuffer [Notestat.Tail]. Varighet = duration_count;
Notestat.Tail ;
Notestat.Tail & = NOTE_ROLLOVER_MASK;
Notestat.Count ;
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void InitTimer (void)
(
setup_timer_0 (RTCC_DIV_256 | RTCC_8_BIT);
setup_timer_1 (T1_INTERNAL | T1_DIV_BY_8);
setup_timer_2 (T2_DIV_BY_4, 250, 5);enable_interrupts (INT_CCP1);
enable_interrupts (INT_TIMER0);
enable_interrupts (INT_TIMER2);
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
char get_char_from_tune (lang indeksen)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.tune [index]);
break;
tilfelle JINGLEBELLS:
return (JingleBells.tune [index]);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int get_tempo (void)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.tempo);
break;
tilfelle JINGLEBELLS:
return (JingleBells.tempo);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int get_defaultoctave (void)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.defaultoctave);
break;
tilfelle JINGLEBELLS:
return (JingleBells.defaultoctave);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
int get_defaultduration (void)
(
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
return (SilentNight.defaultduration);
break;
tilfelle JINGLEBELLS:
return (JingleBells.defaultduration);
break;
standard:
break;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void Melody_Task (void)
(
if (PlayMelodyFlag)
(
if (! PlayMelody ())
Melody_Pointer ;
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen viser tittelen på melodien på LCD
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void display_melody_name (void)
(
/ / Clear skjermen og kontrollere at vi er på toppen
lcd_putc ( "\ f");
lcd_gotoxy (0,1);/ / Bruk vår globale Melody_Pointer å bestemme tittelen på nåværende tune
bryteren (Melody_Pointer)
(
tilfelle SILENTNIGHT:
lcd_putc ( "Silent Night");
break;
tilfelle JINGLEBELLS:
lcd_putc ( "JingleBells");
break;
standard:
break;
)
)/ * ************************************************ *************************
DESCRIPTION: Button Oppgaver
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void Button_Task (void)
(
if (! Read_Button_Count)
(
Read_Button_Count = 30;
Check_Button_Press ();
)
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen håndterer sjekke knappen trykkes
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void Check_Button_Press (void)
(
static int debounce_count = 4;
static int stabilt = 0xFF;
static int siste = 0xFF;
int trans_low;
int gjeldende = 0xFF;
Boolsk endre = FALSE;/ / Les gjeldende tilstand knappene
if (! inngang (PIN_A4))
bit_clear (strøm, 2);if (! inngang (PIN_B0))
bit_clear (aktuell, 3);/ / Se om de har endret
if (gjeldende! = sist)
(
siste = gjeldende;
endre = TRUE;
)/ / Hvis de har endret deretter tilbakestille våre counter
if (endre)
(
debounce_count = 4;
)
/ / Hver gang de er stabile, så decrement våre teller
else if (debounce_count)
(
debounce_count -;
)
/ / De har vært stabile lenge nok så handle på dem
else if (gjeldende! = stabile)
(
/ / Få høy overganger
trans_low = ((stabil ^ nåværende) og stabile);if (bit_test (trans_low, 2))
PlayMelodyFlag =!
PlayMelodyFlag;
if (bit_test (trans_low, 3))
(
Melody_Pointer ;
if (Melody_Pointer> = LAST_MELODY)
Melody_Pointer = 0;
Note_Index = 0xFFFF;
display_melody_name ();
)
stabil = gjeldende;
)
)//------------------------------------------------ ----------------------------
/ / ISR rutiner
//------------------------------------------------ ----------------------------
# int_ccp1
/ * ************************************************ *************************
Beskrivelse: Denne funksjonen kontrollerer PWM av Piezo høyttaler
RETURN: ingen
Algoritme: ingen
Merknader: Hvis du ikke ønsker å bruke C2 som utgang, så du må
for å veksle din utgang her. Kontroller at du endrer CCP
oppsett ikke å slå C2 utgang hvis dette er tilfelle
************************************************** ************************* * /
void ccp1_isr (void)
(
CCP_1 = Note_Ticks;
)/ * ************************************************ *************************
Beskrivelse: Denne funksjonen brukes for å kontrollere varigheten av notatet
RETURN: ingen
Algoritme: ingen
MERKNADER: jeg lagre notatene i en buffer slik at de viktigste loop har andre
tid til å gjøre ting uten å sitte på vent til et notat til
fullført.
************************************************** ************************* * /
# int_timer0
void timer0_isr (void)
(
/ / Forhåndslasting en verdi for TMR0 slik at vi kan styre hvor lang tid det tar å
/ / Utløse en avbruddsordrelinje
TMR0 = Tempo;/ / Er et notat spille?
if (DurationCount)
(
DurationCount -;
if (! DurationCount)
setup_ccp1 (CCP_OFF);
)
/ / Note er ferdig med å spille, har vi mer i vår buffer?
else if (Notestat.Count)
(
DurationCount = NoteBuffer [Notestat.Head]. Varighet;
Note_Ticks = NoteBuffer [Notestat.Head]. Notat;
Notestat.Count--;
Notestat.Head ;
Notestat.Head & = NOTE_ROLLOVER_MASK;
CCP_1 = TMR1 Note_Ticks;
if (Note_Ticks)
(
/ * Oppsett av CCP modulen å veksle utdataene pin c2 * /
setup_ccp1 (CCP_COMPARE_TOGGLE_MATCH);
)
/ / Nei, vi er alle gjennom så deaktivere PWM
ellers
(
setup_ccp1 (CCP_OFF);
)
)
)# int_timer2
/ * ************************************************ *************************
Beskrivelse: Denne funksjonen er vårt system tick satt til 1ms
RETURN: ingen
Algoritme: ingen
MERKNADER: ingen
************************************************** ************************* * /
void timer2_isr (void)
(
if (Read_Button_Count)
(
Read_Button_Count -;
)
)