DAC

12 Anni 8 Mesi fa #6 da Guido
Risposta da Guido al topic Re: DAC
molto bene mauro funziona cambiando il Pin. E' normale non ottenere un onda sinusoidale ma un onda quadra smussata?

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Guido
  • Platinum Member
  • Platinum Member
Di più
12 Anni 8 Mesi fa #7 da Guido
Risposta da Guido al topic Re: DAC
Ciao purtroppo sono de coccio, mi serve aiuto ho cercato di usare i tuoi consigli ma celo fatta in parte, ora se premo RB0 esce la frequenza fissata, la nota negativa è che se rilascio il pulsante vi è una frequenza indesiderata sotto fondo, mi dai ancora una mano?
SE puo servire uso un quaezo da 4 MHz.
Ecco il codice, lo ripulito dei DEFINE e il modulo USB, vi ho aggiunto il pulsante.


#include <p18f4550.h>
#include <portb.h>

#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF

//OSC = HS Set to work for high speed
//WDT = OFF watchdog timer is off
//LVP = OFF LVP programming is off
//PBADEN = OFF Analog input on PORTB are off

//************************************************************
// Functions Prototypes
//************************************************************
void set_duty_cycle (int duty_cycle);
void turn_on_PWM1 (void);
void High_Int_Event (void);


//************************************************************
// Global variables
//************************************************************

//Samples
int sine[] = {250,299,346,389,427,458,481,495,500,495,481,458,427,389,346,299,250,201,154,111,73,42,19,5,0,5,19,42,73,111,154,201};

// Repeat the sample for x time
// sampling frequency must be changed to keep analog signal frequency costnat
const unsigned char REPEATING_FACTOR = 3;


//************************************************************
// Interrupt Handler
//************************************************************

#pragma code high_vector = 0x08
void high_interrupt (void) {
// go to the interrupt handler
_asm GOTO High_Int_Event _endasm
}

#pragma code
#pragma interrupt High_Int_Event

void High_Int_Event (void) {

static unsigned char sample = 0;
static unsigned char repeat = 0;

if (PIR1bits.TMR2IF == 1) {
if (PORTBbits.RB0 == 0) {

// I create a pulse on RC0 to be measured with the scope.
// Used just for debugging the sampling frequency
LATCbits.LATC2 = 1;
LATCbits.LATC2 = 0;
if (PORTBbits.RB0 == 0) {

set_duty_cycle (sine[sample]);
}
else {
set_duty_cycle (0);
}
repeat++;
}



if (repeat == REPEATING_FACTOR) {
repeat = 0;
sample++;

if (sample > 31) {
sample = 0;
}
}

}


//Clear Timer 2 Interrupt Flag
PIR1bits.TMR2IF = 0;
}


//************************************************************
// Main program
//************************************************************

void main (void){

// PORTA settings
LATA = 0x00;
TRISA = 0xFF;

// PORTB settings
LATB = 0x00;
TRISB = 0xFF;

// PORTC settings
LATC = 0x00;
TRISC = 0b11111010;

// PORTD settings
LATD = 0x00;
TRISD = 0x00;

// PORTE settings
LATE = 0x00;
TRISE = 0xFF;



//*************************************
// Modules Initializaion
//*************************************

// Set the PWM frequency to
PR2 = 198;

set_duty_cycle (250);

// Turn ON TMR2 and set Prescaler to 0
T2CON = 0x04;

turn_on_PWM1 ();

// Enable Timer 2 Interrupt
PIE1bits.TMR2IE = 1;

// Standrd interrupt (by default is already 0)
RCONbits.IPEN = 0;

// Enable global interrupt
INTCONbits.GIE = 1;

// Enable Peripheral Interrupt
INTCONbits.PEIE = 1 ;

// just loop for nothing...
while (1){

}
}


//************************************
// Set the Diuty Cicle
//************************************

void set_duty_cycle (int duty_cycle) {

CCPR1L = (unsigned char) (duty_cycle >> 2);

if (duty_cycle & 0x0001)
CCP1CONbits.DC1B0 = 0x0001;
else
CCP1CONbits.DC1B0 = 0x0000;

if (duty_cycle & 0x0002)
CCP1CONbits.DC1B1 = 0x0001;
else
CCP1CONbits.DC1B1 = 0x0000;
}


//************************************
// Turn ON the PWM module
//************************************
void turn_on_PWM1 (void) {

CCP1CON = CCP1CON | 0b00001100;

}

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Guido
  • Platinum Member
  • Platinum Member
Di più
12 Anni 8 Mesi fa #8 da Guido
Risposta da Guido al topic Re: DAC
Ciao, ho letto l'articolo che mi hai passato come link, ma preferisco il tuo sistema se riesco a risolvere i problemi perchè il DAC del link mi richiede troppi pin.
Ho cercato di tradurlo se a qualcuno interessa le passo la traduzione.
Grazie

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Guido
  • Platinum Member
  • Platinum Member
Di più
12 Anni 8 Mesi fa #9 da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: DAC
bene,
...ora funziona.
Qualche altro accorgimento e ci siamo.

relativamente al pin RC0 non vedi nulla perche' il pin viene cambiato da 1 a 0 troppo rapidamente (un solo ciclo istruzioni).
Per visualizzare questo impulso ho fatto uso di un oscilloscopio con campionamento a 1GS/s e banda da 40MHz mentre nel tuo caso campioni a 44KHz e banda 20KHz. Quindi l'impulso e' troppo rapido per essere letto.

Per togliere il rumore prova a spegnere il modulo PWM piuttosto che porre il Duty Cycle a 0.
In alternativa metti il Duty cycle a 1023 (ovvero sempre a 1).

Saluti,

Mauro

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Mauro Laurenti
  • Avatar di Mauro Laurenti
  • Moderator
  • Moderator
Di più
12 Anni 8 Mesi fa #10 da Guido
Risposta da Guido al topic Re: DAC
Ciao, ho provato ma non va, ho scritto prima e seconda prova nel codice per vedere se ho fatto bene.
codice:

#include <p18f4550.h>
#include <portb.h>

#pragma config FOSC = HS
#pragma config WDT = OFF
#pragma config LVP = OFF
#pragma config PBADEN = OFF

//OSC = HS Set to work for high speed
//WDT = OFF watchdog timer is off
//LVP = OFF LVP programming is off
//PBADEN = OFF Analog input on PORTB are off

//************************************************************
// Functions Prototypes
//************************************************************
void set_duty_cycle (int duty_cycle);
void turn_on_PWM1 (void);
void High_Int_Event (void);


//************************************************************
// Global variables
//************************************************************

//Samples
int sine[] = {250,299,346,389,427,458,481,495,500,495,481,458,427,389,346,299,250,201,154,111,73,42,19,5,0,5,19,42,73,111,154,201};

// Repeat the sample for x time
// sampling frequency must be changed to keep analog signal frequency costnat
const unsigned char REPEATING_FACTOR = 3;


//************************************************************
// Interrupt Handler
//************************************************************

#pragma code high_vector = 0x08
void high_interrupt (void) {
// go to the interrupt handler
_asm GOTO High_Int_Event _endasm
}

#pragma code
#pragma interrupt High_Int_Event

void High_Int_Event (void) {


static unsigned char sample = 0;
static unsigned char repeat = 0;




if (PIR1bits.TMR2IF == 1) {



if (PORTBbits.RB0 == 0) {

set_duty_cycle (sine[sample]);

repeat++;
}

else {
//ClosePWM1 (); prima prova fatta (non funziona, non esce la frequenza)

//set_duty_cycle (1023); seconda prova fatta (il rumore rimane, cambia la Freq.)


set_duty_cycle (0);
}

if (repeat == REPEATING_FACTOR) {
repeat = 0;
sample++;
}
if (sample > 31) {
sample = 0;
}
}

//Clear Timer 2 Interrupt Flag
PIR1bits.TMR2IF = 0;

}


//************************************************************
// Main program
//************************************************************

void main (void){

// PORTA settings
LATA = 0x00;
TRISA = 0xFF;

// PORTB settings
LATB = 0x00;
TRISB = 0xFF;

// PORTC settings
LATC = 0x00;
TRISC = 0b11111010;

// PORTD settings
LATD = 0x00;
TRISD = 0x00;

// PORTE settings
LATE = 0x00;
TRISE = 0xFF;



//*************************************
// Modules Initializaion
//*************************************

// Set the PWM frequency to
PR2 = 198;

set_duty_cycle (250);

// Turn ON TMR2 and set Prescaler to 0
T2CON = 0x04;

turn_on_PWM1 ();

// Enable Timer 2 Interrupt
PIE1bits.TMR2IE = 1;

// Standrd interrupt (by default is already 0)
RCONbits.IPEN = 0;

// Enable global interrupt
INTCONbits.GIE = 1;

// Enable Peripheral Interrupt
INTCONbits.PEIE = 1 ;

// just loop for nothing...
while (1){
}
}


//************************************
// Set the Diuty Cicle
//************************************

void set_duty_cycle (int duty_cycle) {

CCPR1L = (unsigned char) (duty_cycle >> 2);

if (duty_cycle & 0x0001)
CCP1CONbits.DC1B0 = 0x0001;
else
CCP1CONbits.DC1B0 = 0x0000;

if (duty_cycle & 0x0002)
CCP1CONbits.DC1B1 = 0x0001;
else
CCP1CONbits.DC1B1 = 0x0000;
}


//************************************
// Turn ON the PWM module
//************************************
void turn_on_PWM1 (void) {


CCP1CON = CCP1CON | 0b00001100;

}

Si prega Accedi o Crea un account a partecipare alla conversazione.

  • Guido
  • Platinum Member
  • Platinum Member
Di più
Moderatori: Mauro LaurentiPinnaStefAMatteo Garia

Registrati al sito

Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.

Registrati al sito LaurTec.

Login