Hi..
Below is the code to generate 4kHz sine wave using PWM for PIC18F4620. I am going to test it soon but at the mean time, i don't have the equipment such as oscilloscope so am not able to test it jst yet.. However, by simulating it in Proteus, I am able to see the pulsewidth (or duty cycle changes accordingly). The PWM output will connect to sallen key's 2nd order low pass filter with a cut off frequency of 4kHz or slightly higher so that the higher frequency will be filtered off leaving behind a sine wave (hopefully).
I am in the middle of building a low pass filter similar to the low pass filter of this preamp.
Anybody done this before..? Please advice..
Thanks..
Below is the code to generate 4kHz sine wave using PWM for PIC18F4620. I am going to test it soon but at the mean time, i don't have the equipment such as oscilloscope so am not able to test it jst yet.. However, by simulating it in Proteus, I am able to see the pulsewidth (or duty cycle changes accordingly). The PWM output will connect to sallen key's 2nd order low pass filter with a cut off frequency of 4kHz or slightly higher so that the higher frequency will be filtered off leaving behind a sine wave (hopefully).
I am in the middle of building a low pass filter similar to the low pass filter of this preamp.
Anybody done this before..? Please advice..
Thanks..
Code:
#include <p18f4620.h>
#include <delays.h>
#include <usart.h>
#include <stdio.h>
#include <timers.h>
#include <pwm.h>
#pragma config OSC=HSPLL
#pragma config PWRT=ON
#pragma config BOREN=OFF
#pragma config WDT=OFF
#pragma config MCLRE=ON
#pragma config PBADEN=OFF
#pragma config LVP=OFF
#pragma config XINST=OFF
#define CLOCK_FREQ (40000000) // Hz
/////////////////////////////////////
// FUNCTION PROTOTYPE
/////////////////////////////////////
void low_isr();
void InitInterrupt();
void InitTimer2();
void InitPWM();
void UpdateDutyCycle();
/////////////////////////////////////
// GLOBAL VARIABLE
/////////////////////////////////////
unsigned int cnt8000 = 0;
char cntDty = 0;
char boolUpdateDty = 0;
const unsigned char Dty [24] = {128, 160, 191, 218, 238, 251, 255, 251, 238, 218, 191, 160, 128, 95, 64, 37, 17, 4, 0, 4, 17, 37, 64, 95}; // Testing
unsigned long int tempDty1 = 0, tempDty2 = 0;
/////////////////////////////////////
// SETUP ISR VECTOR
/////////////////////////////////////
#pragma code low_vector=0x18 //setup the ISR vector
void low_interrupt (){
_asm GOTO low_isr _endasm //jump to interrupt handler
}
#pragma code
/////////////////////////////////////
// ISR
/////////////////////////////////////
#pragma interruptlow low_isr //the ISR
void low_isr()
{
if (PIR1bits.TMR2IF == 1)
{
PIR1bits.TMR2IF=0;
boolUpdateDty = 1;
if (cnt8000 < 8000)
cnt8000++;
else
cnt8000 = 0;
}
}
#pragma code
void main()
{
InitInterrupt();
InitTimer2();
InitPWM();
T2CONbits.TMR2ON = 1;
while (1)
{
if (boolUpdateDty==1)
{
boolUpdateDty = 0;
UpdateDutyCycle();
}
}
}
void InitInterrupt()
{
PIE1bits.TMR2IE = 1; //enable Timer2 interrupt
INTCONbits.PEIE = 1; //enable peripheral interrupts
INTCONbits.GIE = 1; //enable glogal interrupts
IPR1bits.TMR2IP = 0; // low priority
}
void InitTimer2()
{
T2CON = 0b01001000;
PR2 = 124; // 125 counts including 0
}
void InitPWM()
{
SetDCPWM1(250);
CCP1CON=0b00001100; //ccpxm3:ccpxm0 11xx=pwm mode
T2CONbits.TMR2ON = 0; // STOP TIMER2 registers to POR state
PR2 = 124;
}
void UpdateDutyCycle()
{
if ((cnt8000%334)==0)
{
tempDty1 = 50000/255;
tempDty2 = Dty[cntDty]*tempDty1/100;
SetDCPWM1(tempDty2);
if (cntDty < 22)
cntDty++;
else
cntDty = 0;
}
}
Last edited: