Per campionare a 22kHz dovrebbero durare meno di 45us
Se hai un oscilloscopio o un frequenzimetro, potresti provare a cambiare di stato ad un pin del PIC ogni volta che leggi un byte dalla SD, quindi leggi la frequenza/tempo con cui varia quel pin e vedi quanto tempo impiega la routine di lettura.
Suoni con PWM
Moderatori:
carloc,
g.schgor,
BrunoValente,
IsidoroKZ
36 messaggi
• Pagina 3 di 4 • 1, 2, 3, 4
0
voti
[22] Re: Suoni con PWM
c1b8 ha scritto:Per campionare a 22kHz dovrebbero durare meno di 45us
Se hai un oscilloscopio o un frequenzimetro, potresti provare a cambiare di stato ad un pin del PIC ogni volta che leggi un byte dalla SD, quindi leggi la frequenza/tempo con cui varia quel pin e vedi quanto tempo impiega la routine di lettura.
Ho un oscilloscopio analogico in azienda proverò con quello sperando di riuscire a leggere il segnale.
grazie per l'aiuto vi terrò aggiornato
-

guidoi8311
0 2 - New entry

- Messaggi: 66
- Iscritto il: 3 lug 2013, 11:51
0
voti
[23] Re: Suoni con PWM
Ho provato con oscilloscopio ma purtroppo il segnale e troppo veloce e non riesco a leggerlo comunque ho provato a realizzare una variabile array di 1000 valori in cui precarico il file e successivamente mando in riproduzione ma le cose non cambiano il suono si sente sempre rallentato facendo due conti il buffer si svuoterebbe in 145ms perché genero un interrupt ogni 45us leggo il valore e setto il duty ora io per settare il duty utilizzo una funzione interna al MikroC non vorrei che anche questa influenzi la riproduzione?
se diminuissi ancora di più l'interrupt x compensare i ritardi?
se diminuissi ancora di più l'interrupt x compensare i ritardi?
-

guidoi8311
0 2 - New entry

- Messaggi: 66
- Iscritto il: 3 lug 2013, 11:51
1
voti
[24] Re: Suoni con PWM
Se il suono si sente rallentato probabilmente stai dimenticando una fattore 2 da qualche parte. Di solito si fanno casini con la frequenza di ciclo macchina che è la metà (o un quarto) di quella dell'oscillatore.
-

marioursino
5.687 3 9 13 - G.Master EY

- Messaggi: 1598
- Iscritto il: 5 dic 2009, 4:32
0
voti
[25] Re: Suoni con PWM
ho provato anche con un file a campionamento 16Khz si sente un po meglio ma sempre rallentato solo con 8Khz riesco a leggere e riprodurre senza nessun problema bha
comunque grazie per i suggerimenti che mi state dando
comunque grazie per i suggerimenti che mi state dando
-

guidoi8311
0 2 - New entry

- Messaggi: 66
- Iscritto il: 3 lug 2013, 11:51
0
voti
[26] Re: Suoni con PWM
oggi mi è venuta la brillante idea di leggere il file campionato a 16kHz senza l'utilizzo dell'interrupt quindi leggo il valore e lo mando al PWM Duty ed ho iniziato a vedere miglioramenti poi visto che per settare il duty utilizzo una funzione interna del programma che ho pensato potesse rallentare l'esecuzione ho impostato manualmente i valori del registro CCP2L e i bit 5 e 4 del registro CCP2CON e per magia la musica si sente a ritmo l'unico neo e la voce che si sente distorta come se il file venisse riprodotto più velocemente ma non è cosi qualcuno sa darmi qualche dritta 
-

guidoi8311
0 2 - New entry

- Messaggi: 66
- Iscritto il: 3 lug 2013, 11:51
1
voti
[27] Re: Suoni con PWM
Ciao, scusa il ritardo.
Non credo sia una buona idea non utilizzare gli interrupt. Con l'interrupt sei sicuro di avere un campionamento preciso, senza interrupt non hai questa certezza.
Forse la voce si sente distorta proprio perché il tempo di esecuzione del ciclo senza interrupt, quindi il tempo di scrittura del duty cycle, non è sempre lo stesso.
Non so come fosse la routine di interrupt prima, se nella routine ci fosse la chiamata alla lettura della sd o meno.
Secondo me la routine di interrupt deve solo impostare il duty cycle.
La lettura della sd deve essere nel main, come hai fatto adesso senza interrupt.
Quindi:
1) nel main
2) nella routine di interrupt
Temo comuqnue che non sia possibile superare di tanto i 16kHz di campionamento, visto quanto hai detto delle prove effettuate.
Non credo sia una buona idea non utilizzare gli interrupt. Con l'interrupt sei sicuro di avere un campionamento preciso, senza interrupt non hai questa certezza.
Forse la voce si sente distorta proprio perché il tempo di esecuzione del ciclo senza interrupt, quindi il tempo di scrittura del duty cycle, non è sempre lo stesso.
Non so come fosse la routine di interrupt prima, se nella routine ci fosse la chiamata alla lettura della sd o meno.
Secondo me la routine di interrupt deve solo impostare il duty cycle.
La lettura della sd deve essere nel main, come hai fatto adesso senza interrupt.
Quindi:
1) nel main
- Codice: Seleziona tutto
while (1) {
- attendo che sia scattato un interrupt (controllo di un bit di una locazione di memoria)
- quando si è verificato un interrupt leggo il dato dalla SD e lo salvo, resetto il bit controllato sopra
}
2) nella routine di interrupt
- Codice: Seleziona tutto
- leggo il dato salvato in fase di lettira della SD nel main
- imposto il Duty Cycle con questo dato
- imposto il bit che serve al main per sapere che si è verificato un interrupt
Temo comuqnue che non sia possibile superare di tanto i 16kHz di campionamento, visto quanto hai detto delle prove effettuate.
Fabio
0
voti
[28] Re: Suoni con PWM
Grazie x la risposta, si più o meno la gestione dell'interrupt l'ho pensata come te comunque ho visto un po in giro sulla rete ed tutti sono concordi che MiKroC ha molte funzioni ma compila programmi molto grossi e lenti ed avevo pensato di passare al XC8 ma devo trovare qualche esempio per la gestione della fat16 sulle sd perché non ho idea di come realizzare le funzione che sono implementate nel MikroC.
P.s. Buona domenica delle palme
P.s. Buona domenica delle palme
-

guidoi8311
0 2 - New entry

- Messaggi: 66
- Iscritto il: 3 lug 2013, 11:51
0
voti
[30] Re: Suoni con PWM
Ragazzi ho fatto un po di prove e un po di ricerce ed ho messo tutto insieme ma il risultato non è dei migliori
- Codice: Seleziona tutto
// Lcd pinout settings
sbit LCD_RS at RB7_bit;
sbit LCD_EN at RA4_bit;
sbit LCD_D7 at RA0_bit;
sbit LCD_D6 at RA1_bit;
sbit LCD_D5 at RA2_bit;
sbit LCD_D4 at RA3_bit;
// Pin direction
sbit LCD_RS_Direction at TRISB7_bit;
sbit LCD_EN_Direction at TRISA4_bit;
sbit LCD_D7_Direction at TRISA0_bit;
sbit LCD_D6_Direction at TRISA1_bit;
sbit LCD_D5_Direction at TRISA2_bit;
sbit LCD_D4_Direction at TRISA3_bit;
// MMC module connections
sfr sbit Mmc_Chip_Select at RC2_bit;
sfr sbit Mmc_Chip_Select_Direction at TRISC2_bit;
char error=1;
char TESTO[]="Inizializing SD";
char filename[14] = "provax.wav";
char dato; //che rispetti sempre le caratteristiche descritte sopra
char countsong;
char buffer[1024];
unsigned long size,j;
unsigned int circle,buffstore;
unsigned short bit1,bit2,bit3,bit4;
int latenza,sample,Fcamp;
unsigned short valuetimer=0,valuepretimer=0,songcount=0;
unsigned int valuecircle=0;
unsigned short eof=0;
void LCD_PUTSN (signed int c);
void LCD_PUTUN (unsigned int c);
unsigned int Fcampionamento();
void trovainiziodati();
void main() {
CCP1CON=0b00000000;
UCON.USBEN=0;
ADCON0.ADON=0;
ADCON1=0b00001111;
CMCON=7;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR); // CANCELLA DISPLAY
Lcd_Cmd(_LCD_CURSOR_OFF);
Delay_ms(100); // DISABILITA CURSORE
Lcd_Out(1,1,TESTO);
// Inizializzazione modulo SPI
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV64, _SPI_DATA_SAMPLE_MIDDLE,_SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
Delay_ms(100);
while(error==1)
{
error = Mmc_Fat_Init();
}
// Reinizializzazione modulo SPI ad alta velocità per lettura FAT
SPI1_Init_Advanced(_SPI_MASTER_OSC_DIV16, _SPI_DATA_SAMPLE_MIDDLE, _SPI_CLK_IDLE_LOW, _SPI_LOW_2_HIGH);
Lcd_Cmd(_LCD_CLEAR);
Delay_ms(100);
Mmc_Fat_Assign(&filename, 0);
Mmc_Fat_Reset(&size); // To read file, procedure returns size of file
Lcd_Cmd(_LCD_CLEAR);
INTCON=0x20; //abilito l'interrupt di timer0 e disabilito il GIE
PWM2_Init(65000); //Inizializzo il PWM alla frequenza 65khz
Delay_ms(10);
Fcamp=Fcampionamento(); //TROVO LA FREQUENZA DI CAMPIONAMENTO
switch(Fcamp)
{
case 22050:{valuetimer=25;valuepretimer=0xC0;valuecircle=640;break;} //SE È 22050 SETTO IL TIMER PER ANDARE IN OVERFLOW A 22050 Hz
case 16000:{valuetimer=100; valuepretimer=0xC1;valuecircle=512;break;} //" " 16000
case 11025:{valuetimer=29;valuepretimer=0xC1;valuecircle=256;break;} //ecc
case 8000: {valuetimer=177;valuepretimer=0xC3;valuecircle=128break;}
}
trovainiziodati(); //Salto l'header e vado direttamente all'inizio dei samples
mmc_fat_readN(buffer,1024); //riempio il buffer dei primi 512 byte dei samples
j=0;
circle=512;
T0CON=valuepretimer;
PWM2_Start(); //Abilito il PWM
delay_ms(100);
INTCON.GIE=1; //abilito l'interrupt
while(Mmc_Fat_EOF()==0 ) //finché il file non è finito
{
if(buffstore==1) //Se la latenza è minore riempio il buffer con 8 nuovi bytes
{
mmc_fat_read(&dato); //leggo un byte e mi posiziono al successivo
buffer[circle]=dato; //posiziono il byte letto nel buffer
mmc_fat_read(&dato);
buffer[circle+1]=dato; //lo faccio per 8 volte
mmc_fat_read(&dato);
buffer[circle+2]=dato;
mmc_fat_read(&dato);
buffer[circle+3]=dato;
mmc_fat_read(&dato);
buffer[circle+4]=dato;
mmc_fat_read(&dato);
buffer[circle+5]=dato;
mmc_fat_read(&dato);
buffer[circle+6]=dato;
mmc_fat_read(&dato);
buffer[circle+7]=dato;
circle=circle+8; //faccio avanzare di 8 posizioni l'indice di scrittura
//del buffer
if(circle>=1024) //Se sono arrivato alla fine del buffer
{ //ricomincio da 0
circle=0;
}
}
latenza= (circle-j); //calcolo la latenza
if(latenza<0) //se è negativa
{ //ne calcolo il valore assoluto
latenza=-latenza;
}
if(latenza<valuecircle) //se la latenza è minore di 256
{ //attivo la scrittura sul buffer
buffstore=1;
}
else //se no la disattivo
{
buffstore=0;
}
}
}
void LCD_PUTUN (unsigned int c)
{
unsigned char t1,i,wrote;
unsigned int k;
wrote=0;
for (i=4;i>=1;i--)
{
switch(i)
{
case 4: k=10000;
break;
case 3: k=1000;
break;
case 2: k=100;
break;
case 1: k=10;
}
t1=c/k;
if((wrote)||(t1!=0))
{
Lcd_Chr_CP(t1+'0');
wrote=1;
}
c-=(t1*k);
}
Lcd_Chr_CP(c+'0');
}
/****************************************
Writes signed numbers to the LCD
*****************************************/
void LCD_PUTSN (signed int c)
{
if(c<0)
{
Lcd_Chr_CP('-');
c*=(-1);
}
LCD_PUTUN(c);
}
// Crea file ed inserisce la data
void interrupt() //interrupt
{
bit1=buffer[j]; //Prendo i primi 8 bit del sample
bit2=buffer[j+1]; //prendo i secondi 8 bit del sample
sample=bit1+(bit2<<8); //calcolo il sample a 16 bit
sample=sample+32768; //lo trasformo in unipolare
sample=sample/64; //lo trasformo a 10 bit
CCPR2L = sample >> 2; //Setto il PWM
CCP2CON.F4 = sample; //al valore calcolato a 10 bit
CCP2CON.F5 = sample >> 1;
j=j+2; //mando avanti l'indice di 2
if(j>=1024) //se sono arrivato alla fine dell'indice
{ //lo faccio ripartire da 0
j=0;
}
TMR0L=valuetimer; //presetto il timer0 in modo di avere l'interrupt
//alla frequenza più precisa possibile
INTCON.TMR0IF=0; //abbasso il flag di interrupt del timer
}
unsigned int Fcampionamento()
{
unsigned short kkj=0;
int Fcamp1=0;
Mmc_Fat_Reset(&size);
for(kkj=0;kkj<24;kkj++) //IL BYTE CHE DEFINISCE LA FREQUENZA È IL 24esimo
{
Mmc_Fat_Read(&dato);
}
Mmc_Fat_Read(&dato); //QUINDI VADO A LEGGERLO
bit1=dato;
Mmc_Fat_Read(&dato);
bit2=dato;
Mmc_Fat_Read(&dato);
bit3=dato;
Mmc_Fat_Read(&dato);
bit4=dato;
Fcamp1=(bit1+(bit2<<8)+(bit3<<16)+(bit4<<24)); //CALCOLO LA FREQUENZA DI CAMPIONAMENTO
return Fcamp1;
}
void trovainiziodati()
{
Mmc_Fat_Reset(&size);
while(1)
{
Mmc_Fat_Read(&dato);
Lcd_Cmd(_LCD_CLEAR);
if(100==dato); //Se trovo la lettera "d"(100) cerco per la "a"(97)
{ LCD_PUTSN(dato);
j++;
Mmc_Fat_Read(&dato);
if(97==dato) //se trovo la "a" cerco la "t" (116)
{ LCD_PUTSN(dato);
j++;
Mmc_Fat_Read(&dato); //Se trovo la "t" cerco la a
if(116==dato)
{LCD_PUTSN(dato);
j++;
Mmc_Fat_Read(&dato);
if(97==dato) //Se trovo la "a" significa che ho trovato "data"
{ LCD_PUTSN(dato);
j++;
//Spengo il led e esco dal ciclo
break;
}
}
}
}
j++;
}
}
da un software altrui ho preso l'idea del buffer circolare con due indici ma anche con il file campionato a 8khz a 16bit mono la musica si sente rallentata forse sbaglio ad impostare l'interrupt? ho letto da qualche parte che nei PIC 18 ci sono interrupt a priorita hight e low bho! comunque io sto usando un PIC 18f2550 con quarzo a 40,685mhz e credo siano sufficienti anche perché se leggo la sd ed invio direttamente i valori al duty la musica si sente accellerata quindi significa che il tempo della lettura e minore del tempo per generare la frequenza esatta del file campionato ! :cry:
Qualche consiglio ? idee? non so più quante volte ho riprogrammato sto PIC
-

guidoi8311
0 2 - New entry

- Messaggi: 66
- Iscritto il: 3 lug 2013, 11:51
36 messaggi
• Pagina 3 di 4 • 1, 2, 3, 4
Chi c’è in linea
Visitano il forum: Nessuno e 48 ospiti

Elettrotecnica e non solo (admin)
Un gatto tra gli elettroni (IsidoroKZ)
Esperienza e simulazioni (g.schgor)
Moleskine di un idraulico (RenzoDF)
Il Blog di ElectroYou (webmaster)
Idee microcontrollate (TardoFreak)
PICcoli grandi PICMicro (Paolino)
Il blog elettrico di carloc (carloc)
DirtEYblooog (dirtydeeds)
Di tutto... un po' (jordan20)
AK47 (lillo)
Esperienze elettroniche (marco438)
Telecomunicazioni musicali (clavicordo)
Automazione ed Elettronica (gustavo)
Direttive per la sicurezza (ErnestoCappelletti)
EYnfo dall'Alaska (mir)
Apriamo il quadro! (attilio)
H7-25 (asdf)
Passione Elettrica (massimob)
Elettroni a spasso (guidob)
Bloguerra (guerra)