» Click to show Spoiler - click again to hide... «
#include<htc.h>
__CONFIG(FOSC_HS&WDTE_OFF&PWRTE_OFF&BOREN_OFF&LVP_OFF);
#define _XTAL_FREQ 20000000
#define Buzzer RC1
#define A4 78 //440
#define B4b 74 //466
#define C4 132 //261
#define C4_1 130
#define C5 65 //523
#define D4 117 //293
#define D4b 124 //277
#define E4 105 //329
#define F4 98 //349
#define G4 0 //392
void tone_out(unsigned char tone , unsigned int delay);
void pwm_initialize(void)
{
// Setting PWM frequency = 3.846khz, using PIC16F887 with 20MHz Crystal
// PR2 = 0x50; // In this progeam, we have already set the PR2 in main.
T2CKPS1 = 1;
T2CKPS0 = 1; // Timer 2 prescale = 16.
CCPR2L = 0; // Duty cycle = 0;
TMR2ON = 1; // Turn on Timer 2.
CCP2M3 = 1;
CCP2M2 = 1; // Configure CCP1 module to operate in PWM mode.
CCP2M1 = 0;
CCP2M0 = 0;
CCPR2L = 0x00;
}
/*******************************************************************************
* PUBLIC FUNCTION: pwm_set_duty_cycle
*
* PARAMETERS:
* ~ ui_duty_cycle - The duty cycle of the PWM, 10 bits.
*
* RETURN:
* ~ void
*
* DESCRIPTIONS:
* Set the duty cycle of the PWM.
*
*******************************************************************************/
void pwm_set_duty_cycle(unsigned int ui_duty_cycle)
{
CCP2CON = (CCP2CON & 0b00001111) | (0b00110000 & ((unsigned char)(ui_duty_cycle << 4)));
CCPR2L = ui_duty_cycle >> 2;
}
void main(void)
{
PORTA = 0; // Clear Port
PORTB = 0;
PORTC = 0;
PORTD = 0;
TRISA = 0b00000000; // set PORTA as OUTPUT
TRISB = 0b00000011; // set PORTB<7:2> as OUTPUT , PORTB<1:0> as INPUT
TRISC = 0b00000000; // set PORTC as OUTPUT
TRISD = 0b00000000; // set PORTD as OUTPUT
RC1=0;
pwm_initialize();
unsigned char wait = 0;
unsigned int birthday[] = {C4_1,C4,D4,C4,F4,E4,C4_1,C4,D4,C4,G4,F4,C4_1,C4,C5,A4,F4,E4,D4,B4b,B4b,A4,F4,G4,F4};
unsigned int delay_period[] = {1,1,2,2,2,3,1,1,2,2,2,3,1,1,2,2,2,2,3,1,1,2,2,2,3};
while (1)
{
for (wait=0 ; wait<25 ; wait++) // loop for 25 times while increase "wait"
{
PR2 = (birthday[wait]/2); // generate PWM period (refer data sheet for detail)
tone_out(birthday[wait],delay_period[wait]*20000);
}
}
}
/*******************************************************************************
* PRIVATE FUNCTION: tone_out
*
* PARAMETERS:
* ~ void
*
* RETURN:
* ~ unsigned char tone - pwm duty cycle
* ~ unsigned int delay - the delay of the tone
*
* DESCRIPTIONS:
* generate the pwm duty cycle and delay the tone for period of time
*
*******************************************************************************/
void tone_out(unsigned char tone , unsigned int delay)
{
while(delay-- > 0)
{
pwm_set_duty_cycle(tone); // generate PWM pulse width
}
}
I got this example of source code from cytron project tutorial, when i run this program, the piezo buzzer will repeat after the first 25 tone is played, i have try to cancel the while(1) command but the buzzer is still looping the song non stop.