// lab5c_la.c // May 2010 Leo Altmann // C implementation of Lab 5 for PIC32 // Oct 2014 Modified by Josef Spjut // Include #include #include "notes.h" #include "prototypes.h" void main(void) { int note = 0; unsigned short period, duration; TRISF = 0; // Use PORTF for output initTimers(); // Set up Timer0 and Timer1 while (1) { period = notes[note*2]; duration = notes[(note*2)+1]; if (duration == 0) break; playNote(period, duration); note++; } } void initTimers(void) { // Assumes peripheral clock at 5MHz // Use Timer1 for note duration // T1CON // bit 15: ON=1: enable timer // bit 14: FRZ=0: keep running in exception mode // bit 13: SIDL = 0: keep running in idle mode // bit 12: TWDIS=1: ignore writes until current write completes // bit 11: TWIP=0: don't care in synchronous mode // bit 10-8: unused // bit 7: TGATE=0: disable gated accumulation // bit 6: unused // bit 5-4: TCKPS=11: 1:256 prescaler // bit 3: unused // bit 2: don't care in internal clock mode // bit 1: TCS=0: use internal peripheral clock // bit 0: unused T1CON = 0b1001000000110000; // Use Timer2 for frequency generation // T2CON // bit 15: ON=1: enable timer // bit 14: FRZ=0: keep running in exception mode // bit 13: SIDL = 0: keep running in idle mode // bit 12-8: unused // bit 7: TGATE=0: disable gated accumulation // bit 6-4: TCKPS=010: 1:4 prescaler // bit 3: T32=0: 16-bit timer // bit 2: unused // bit 1: TCS=0: use internal peripheral clock // bit 0: unused T2CON = 0b1000000000100000; } void playNote(unsigned short period, unsigned short duration) { TMR1 = 0; // Reset timers TMR2 = 0; while (TMR1 < duration) { // Play until note ends if (period != 0) { // Not a rest, so oscillate PORTFbits.RF0 = 0; // Output low TMR2 = 0; while (TMR2 < period) {} // wait PORTFbits.RF0 = 1; // Output high TMR2 = 0; while (TMR2 < period) {} // wait } } }