- Messaggi: 583
- Ringraziamenti ricevuti 1
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
- Autore della discussione
- Platinum Member
Riduci
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;
}
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
- Autore della discussione
- Platinum Member
Riduci
Di più
- Messaggi: 583
- Ringraziamenti ricevuti 1
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
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
- Autore della discussione
- Platinum Member
Riduci
Di più
- Messaggi: 583
- Ringraziamenti ricevuti 1
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
...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.
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;
}
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
- Autore della discussione
- Platinum Member
Riduci
Di più
- Messaggi: 583
- Ringraziamenti ricevuti 1
Moderatori: Mauro Laurenti, Pinna, StefA, Matteo Garia
Registrati al sito
Accedi a tutte le risorse e articoli non visibili pubblicamente, puoi registrarti con pochi passi.