- Messaggi: 583
- Ringraziamenti ricevuti 1
da digitale ad analogico
12 Anni 9 Mesi fa #1
da Guido
da digitale ad analogico è stato creato da Guido
Ciao, sto testando il codice di Mauro solo che all'uscita di RC1 ottengo con un quarzo da 4MHz questi valori di Frequenza 9.89 KHz (circa) col multimetro , quando metto il passa basso per una frequenza di taglio di 500Hz (R 68K e C 4.7nF) ottengo su RC1 5800HZ all' uscita del filtro nulla, dove sbaglio?
Ecco il codice con PIC 18F4550 :
#include <p18f4550.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);
//************************************************************
// EASY USB Related (just constants for the I/O)
//************************************************************
#define LED1 LATDbits.LATD0
#define LED2 LATDbits.LATD1
#define LED3 LATDbits.LATD2
#define LED4 LATDbits.LATD3
#define ENABLE_SELF_PW LATDbits.LATD7
#define PW_IN_EX_ENABLE LATDbits.LATD6
#define VCC_EX_ENABLE LATDbits.LATD5
#define USB_EX_ENABLE LATDbits.LATD4
#define S2 PORTBbits.RB4
#define S3 PORTBbits.RB5
#define USB_PW_SENS PORTAbits.RA1
#define SELF_PW_SENS PORTAbits.RA2
#define LED_ON 1
#define LED_OFF 0
#define ENABLE_SELF_PW_ON 0
#define ENABLE_SELF_PW_OFF 1
#define PW_IN_EX_ENABLE_ON 1
#define PW_IN_EX_ENABLE_OFF 0
#define VCC_EX_ENABLE_ON 0
#define VCC_EX_ENABLE_OFF 1
#define USB_EX_ENABLE_ON 0
#define USB_EX_ENABLE_OFF 1
//************************************************************
// 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) {
// I create a pulse on RC0 to be measured with the scope.
// Used just for debugging the sampling frequency
LATCbits.LATC0 = 1;
LATCbits.LATC0 = 0;
set_duty_cycle (sine[sample]);
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;
//*************************************
// EasyUSB Initialization
//*************************************
ENABLE_SELF_PW = ENABLE_SELF_PW_ON;
PW_IN_EX_ENABLE = PW_IN_EX_ENABLE_OFF;
VCC_EX_ENABLE = VCC_EX_ENABLE_OFF;
USB_EX_ENABLE = USB_EX_ENABLE_OFF;
//*************************************
// Modules Initializaion
//*************************************
// Set the PWM frequency to 25152
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;
}
Ecco il codice con PIC 18F4550 :
#include <p18f4550.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);
//************************************************************
// EASY USB Related (just constants for the I/O)
//************************************************************
#define LED1 LATDbits.LATD0
#define LED2 LATDbits.LATD1
#define LED3 LATDbits.LATD2
#define LED4 LATDbits.LATD3
#define ENABLE_SELF_PW LATDbits.LATD7
#define PW_IN_EX_ENABLE LATDbits.LATD6
#define VCC_EX_ENABLE LATDbits.LATD5
#define USB_EX_ENABLE LATDbits.LATD4
#define S2 PORTBbits.RB4
#define S3 PORTBbits.RB5
#define USB_PW_SENS PORTAbits.RA1
#define SELF_PW_SENS PORTAbits.RA2
#define LED_ON 1
#define LED_OFF 0
#define ENABLE_SELF_PW_ON 0
#define ENABLE_SELF_PW_OFF 1
#define PW_IN_EX_ENABLE_ON 1
#define PW_IN_EX_ENABLE_OFF 0
#define VCC_EX_ENABLE_ON 0
#define VCC_EX_ENABLE_OFF 1
#define USB_EX_ENABLE_ON 0
#define USB_EX_ENABLE_OFF 1
//************************************************************
// 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) {
// I create a pulse on RC0 to be measured with the scope.
// Used just for debugging the sampling frequency
LATCbits.LATC0 = 1;
LATCbits.LATC0 = 0;
set_duty_cycle (sine[sample]);
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;
//*************************************
// EasyUSB Initialization
//*************************************
ENABLE_SELF_PW = ENABLE_SELF_PW_ON;
PW_IN_EX_ENABLE = PW_IN_EX_ENABLE_OFF;
VCC_EX_ENABLE = VCC_EX_ENABLE_OFF;
USB_EX_ENABLE = USB_EX_ENABLE_OFF;
//*************************************
// Modules Initializaion
//*************************************
// Set the PWM frequency to 25152
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ù
12 Anni 8 Mesi fa #2
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: da digitale ad analogico
Ciao,
come hai collegato il filtro?
Invertire R e C potrebbe attenuare molto il segnale e il multimetro non riuscirebbe a leggere nulla perche' il segnale e' basso.
In ogni modo la frequenza in uscita al filtro e' di circa 300Hz (con quarzo a 20MHz). Nel tuo caso, avendo un quarzo a 4MHz dovresti avere 60Hz e il multimetro impostato come frequenzimetro potrebbe non leggere tale frequenza.
Visto le basse tensioni e frequenze in gioco perché non provi a visualizzare il segnale sull'oscilloscopio del PC (con il programma che e' stato segnalato tempo fa)?
Saluti,
Mauro
come hai collegato il filtro?
Invertire R e C potrebbe attenuare molto il segnale e il multimetro non riuscirebbe a leggere nulla perche' il segnale e' basso.
In ogni modo la frequenza in uscita al filtro e' di circa 300Hz (con quarzo a 20MHz). Nel tuo caso, avendo un quarzo a 4MHz dovresti avere 60Hz e il multimetro impostato come frequenzimetro potrebbe non leggere tale frequenza.
Visto le basse tensioni e frequenze in gioco perché non provi a visualizzare il segnale sull'oscilloscopio del PC (con il programma che e' stato segnalato tempo fa)?
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
12 Anni 8 Mesi fa #3
da Guido
Risposta da Guido al topic Re: da digitale ad analogico
Ciao, ho collegato R all'uscita di RC1 poi il condensatore che ho collegato a massa. Tra R e C ho preso il segnale che il multimetro mi da zero.
Hai ragione ho ancora timore di danneggiare il computer ho l'audio integrato alla cpu, ma ci provo.
Grazie
Hai ragione ho ancora timore di danneggiare il computer ho l'audio integrato alla cpu, ma ci provo.
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 #4
da Mauro Laurenti
Risposta da Mauro Laurenti al topic Re: da digitale ad analogico
Fai un'altra misura.
Dal momento che dovresti avere un segnale con frequenza di 60Hz, imposta il multimetro in AC (ACV) e misura la tensione che hai in uscita.
per l'oscilloscopio crea un piccolo circuito a batteria con operazionale che ti fa da buffer e che ti permette di regolare l'ampiezza massima in uscita.
Saluti,
Mauro
Dal momento che dovresti avere un segnale con frequenza di 60Hz, imposta il multimetro in AC (ACV) e misura la tensione che hai in uscita.
per l'oscilloscopio crea un piccolo circuito a batteria con operazionale che ti fa da buffer e che ti permette di regolare l'ampiezza massima in uscita.
Saluti,
Mauro
Si prega Accedi o Crea un account a partecipare alla conversazione.
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.