Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PWM DAC problems?

Status
Not open for further replies.
Hey there,

I'm planning to make a simple tone-generator, but first I need to get this PWM and the 440Hz sinewave tone out, before adding other waveforms like square and sawtooth.

However, I have a problem here - I can't get the 8ohm speaker to sound anything despite running through the wavetable.

By the way here is the code, and the passive LPF is a 470ohm resistor with a 100nF capacitor. Also, the sine wave is in 256 steps and each step is read at 31.25µsecs. The PWM frequency is in 64kHz. In the code, a square wave is used instead. Microcontroller is PIC 18F45K20.

Crystal is internal onboard and it is 16MHz.

Code:
#include <p18f45k20.h>

#pragma config FOSC = INTIO67, WDTEN = OFF, MCLRE = OFF

void T0_ISR(void);
void T2_ISR(void);

#pragma interrupt chk_isr
void chk_isr(void)
{
    if (PIR1bits.TMR2IF == 1)
        T2_ISR();
    if (INTCONbits.TMR0IF == 1)
        T0_ISR();
}

#pragma code HiPrio_Int = 0x0008
void HiPrio_Int(void)
{
_asm goto chk_isr _endasm
}
#pragma code

rom near sqWaveForm[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
                        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
                        };

char counter = 0;
                            
void main()
{
    OSCCON = 0b01110011;
    ADCON0 = 0x00;
    TRISD = 0x00;
    TRISC = 0x00;

    PIR1bits.TMR2IF = 0;
    PIE1bits.TMR2IE = 0;
    T2CON = 0x00;
    TMR2 = 0xC1;
    T2CONbits.TMR2ON = 1;

    INTCONbits.TMR0IF = 0;
    INTCONbits.TMR0IE = 0;
    T0CON = 0b00001000;
    TMR0H = 0xFD;
    TMR0L = 0x8F;
    T0CONbits.TMR0ON = 0;
    
    CCP1CON = 0x00;
    PR2 = 255;
    //CCPR1L = 63;
    //CCP1CON = 0b00111100; // --00---- for 0.00
                          // --01---- for 0.25
                          // --11---- for 0.75

    INTCONbits.PEIE = 1;
    INTCONbits.GIE = 1;
    
    while(1);
}

void T0_ISR(void)
{
    CCPR1L = sqWaveForm[counter];        // values from waveform / PR2
    CCP1CON = 0b00001100;
   
    TMR0H = 0xFD;
    TMR0L = 0x8F;
    INTCONbits.TMR0IF = 0;
}

void T2_ISR(void)
{
    TMR2 = 0x00;
    PIR1bits.TMR2IF = 0;
}
 
Last edited:
G'Day LT

I haven't checked your code yet - but a few points I noticed about your numbers...

- To produce 440Hz, the table index should increment every 8.88 uSec for a 256 entry table... unless I'm missing something.
- At 440Hz, the waveform will be formed with 145 PWM periods (at 64KHz) - less than the resolution of the table. This may still suit your purposes. BUT - I'm not familiar with PIC's but many micro's have a few gotcha's when it comes to the PWM engine. Many will ignore update commands during parts of their cycle, others may cancel the PWM output altogether.

So my first step would be to slow everything down until you can see the output on an LED/Multimeter/Cro etc - whatever you have at hand. Then speed it back up again.

EVA Robotics | The latest in Stepper Motor Control
 
Status
Not open for further replies.

Latest threads

Back
Top