pic16F690 ses kayıt ve dinleme devresi. STOP sorunu

Başlatan akrepefe007, 16 Eylül 2015, 15:34:10

akrepefe007

            Arkadaşlar bir ricam olacak. 16F690 ile bir proje var burda: http://moty22.co.uk/sd.php

           Ben bu proje de ses  kayıt devresini yaptım 16F690 ile... devreye uzaktan kumanda ekledim. bunu da Play butonuna bağladım. tetikleme yapınca kaydettiğim ses çalıyor fakat STOP butonuna basmadan durmuyor. kayıt bitince öylece bekliyor ve tekrar tetikleme almıyor. tekrar tetikleme alması için STOP butonuna elle basmam gerekiyor. sd karttan okuma sistemi byte byte oldugu için sd kartın tamamını tarıyor. En azından ben öyle anladım:) Şimdi ben istiyorum ki Play butonuna basılınca kayıt çalsın ve çalma işlemi bitince otomatik dursun. bunun için baya bir kod yazmaya çalıştım. ama henüz yapamadım. nasıl bir yol izlemeliyim? Yardımcı olursanız Çook Sevinirim. Saygılarımla.... EFe

http://moty22.co.uk/sd.php?dl=1  Yazlım dosyası SDHC 16F690 klasörü içierisnde 16F690.C dosyasıdır.


Gökhan BEKEN

Dosyayı çalmaya başlamadan önce boyutunu öğrenin bir değişkene atın,
döngüyü bu değişkenin değerine göre dönderin, böylece stop sorunu ortadan kalkar.
Özel mesaj okumuyorum, lütfen göndermeyin.

akrepefe007

gökhan bey teşekkür ederim öncelikle. fakat ses kaydını kendimiz yaptıgımız için dosya boyutu sürekli değişiyor. ayrıca sdkartı pc ye taktıgımızda biçimlendirme yapmadan sd kartı açmıyor. Sanırım ReadSD() fnksiyonu içerisindeki for döngüsünü diyorsunuz. bunu azalttım ben önceden. aynı ses kaydını daha hızlı okudu.ses kaydını çalıyor fakat çok çok hızlı okuyor.

Gökhan BEKEN

Alıntı yapılan: akrepefe007 - 17 Eylül 2015, 09:34:32
ses kaydını kendimiz yaptıgımız için dosya boyutu sürekli değişiyor.
Onu diyorum işte, dosyanın boyutu sabit değil bu yüzden dosyanın boyutunu fat32 kütüphanesi yardımıyla öğrenmeniz lazım.
Eğer kayıt yaparken wav dosyasının headerini güncelliyorsanız, <ki bunu yapmazsanız bilgisayarda player'da oynatamazsınız>
güncellediğiniz adresi okuyarak da boyutunu öğrenebilirsiniz.

Not: Kodlarınızı incelemedim. Önemli olan kısmını buraya yazarsanız dosya indirmek zorunda kalmayız.
Özel mesaj okumuyorum, lütfen göndermeyin.

akrepefe007

#4
işte o boyutu writeSD() içersiinde yazmam gerekiyor sanırım. sesi kaydediyor devre ama sdkartı çıkarıp pc ye taktıgım zaman direk biçimlendir uyarısı geliyor. yani .wav formatlı bir dosya kaydetmiyor. fat32 ile olan sistemi yaptım ben. onda ses kaydı yok. direk sd kartda 0000, 0001 ... şeklinde adlandırma ile .wav uzantılı dosyaları yükeyip çalıyoruz. ben kayıt yaparken ilk byte geldiğinde bir zamanlayıcı oluşturmayyı düşündüm. ilk byte gelince zamanlayıcı başlayacak. son bit geldiğinde de zamanlayıcı bitecek . ya da son bit yerine stop butonuna basınca zamanlayıcı bitecek ve bu süre bir değişkende tutulacak. çalma işleminde de bu değişken değerine kadar döngü oluşturmam gerekiyor ki oluşturdum da fakat aynı kaydı daha kısa sürede hızl bir şekilde okudu bu sınırlama ile. şöyle ki;

---------------------------------------
writeSD()
{
int a=0;//zamanlayıcı oluşturmak için
int b=0; //zamanlayıcı oluşturmak için
if(!Rec) 
{
do
{
a++;//stop butonuna basılmadıgı sürece a'yı artırıyor.
if(!stop) break;
}while(Stop)
b=a; // b'yi ReadSD() fonksiyonu içerisinde döngüde kullanacağız
}
}
------------------------------------------------

// Sound Recorder using SD/SDHC card and PIC16F690, by [url=http://www.moty22.co.uk]www.moty22.co.uk[/url]
//
// File will compile with the MPLAB free Hi-Tech C compiler or MPLABX with XC8.
// Recording is done by the ADC using only the LSB. Bytes are written to the SD
// at the rate of 20KHz. 
// For playback CCP is used as a DAC (Digital to Analogue Converter).
   
#include <htc.h>

#if defined(__XC8)
  #pragma config FOSC=HS, CP=OFF, CPD=OFF, WDTE=OFF, BOREN=OFF, MCLRE=OFF
#else defined(COMPILER_MPLAB_PICC)
  __CONFIG(WDTDIS & UNPROTECT & HS & MCLRDIS & UNPROTECT & BORDIS & PWRTDIS);
#endif
  
#define CS RC2		//chip select input
#define Stop RA2	//stop pushbutton
#define Play RB5	//play PB
#define Rec RB7		//record PB
#define Pause RA1	//pause PB
#define RecLED RC0
#define errorLED RC1
#define sdLED RC4	//SD or SDHC optional LED

//prototypes
unsigned char SPI(unsigned char data);
char Command(unsigned char frame1, unsigned long adrs, unsigned char frame2 );
void InitSD(void);
void main(void);
void WriteSD(void);
void ReadSD(void);


unsigned long loc;	//pause location
unsigned char sdhc=0;	//standard sd

void main(void)
{
	OSCCON = 0B1110001;	//8MHz,
	// PIC I/O init
	ANSEL = 0;
	ANSELH = 0;
	TRISC = 0b1000000;		//  rc5=CPP1.
	TRISA = 0b110;   	// switches
	TRISB = 0b10111111;
	//pullup on
	#if defined(__XC8)
    	nRABPU = 0;
    #else defined(COMPILER_MPLAB_PICC)
    	RABPU = 0;
    #endif
	WPUA1 = 1;
	WPUA2 = 1;
	WPUB5 = 1;
	WPUB7 = 1;
	
	ANS8 = 1;	//analogue chan 8
	RecLED = 0;
	errorLED = 0;
	sdLED = 0;
		
	//analogue init
	CCP1CON = 0B1100;	//PWM mode
	PR2 = 100;	//20KHz
	T2CON = 0B100;	//prescale 1, post scale 1, timer2 on
	ADCON1 = 0B1010000;		// Fosc/16.
	ADCON0 = 0B10100000;	// ref=Vdd, right just, AN8, AD off 
	
	//SPI init
	SSPCON = 0B110010;	//low speed osc/64(125kHz),enabled,clock idle=H
	CS = 1; 		// disable SD	

	InitSD();
	if(sdhc){loc = 10;}else{loc = 5120;}	//SD or SDHC
	while(1) {
	if(!Rec) WriteSD();	
	if(!Play) ReadSD();
	if(!Stop) {
		if(sdhc){loc = 10;}else{loc = 5120;}
	}	

	}		
}

unsigned char SPI(unsigned char data)		// send character over SPI
{
	SSPBUF = data;			// load character
	while (!BF);		// sent
	return SSPBUF;		// received character
}

char Command(unsigned char frame1, unsigned long adrs, unsigned char frame2 )
{	
	unsigned char i, res;
	SPI(0xFF);
	SPI((frame1 | 0x40) & 0x7F);	//first 2 bits are 01
	SPI((adrs & 0xFF000000) >> 24);		//first of the 4 bytes address
	SPI((adrs & 0x00FF0000) >> 16);
	SPI((adrs & 0x0000FF00) >> 8);
	SPI(adrs & 0x000000FF);	
	SPI(frame2 | 1);				//CRC and last bit 1

	for(i=0;i<10;i++)	// wait for received character
	{
		res = SPI(0xFF);
		if(res != 0xFF)break;
	}
	return res;	  
}

void InitSD(void)
{
	unsigned char i,r[4];
	
	CS=1;
	for(i=0; i < 10; i++)SPI(0xFF);		// min 74 clocks
	CS=0;			// Enabled for SPI mode
	
	i=100;	//try enter idle state for up to 100 times
	while(Command(0x00,0,0x95) !=1 && i!=0)
	{ 
		CS=1;
		SPI(0xFF);
		CS=0;
		i--;
	}
	if(i==0)	errorLED = 1;	//idle failed
	
	if (Command(8,0x01AA,0x87)==1){					//check card is 3.3V
		r[0]=SPI(0xFF); r[1]=SPI(0xFF); r[2]=SPI(0xFF); r[3]=SPI(0xFF);		//rest of R7
		if ( r[2] == 0x01 && r[3] == 0xAA ){ 		//Vdd OK (3.3V)
			
			//Command(59,0,0xFF);		//CRC off
			Command(55,0,0xFF);
			while(Command(41,0x40000000,0xFF)){Command(55,0,0xFF);} 	//ACMD41 with HCS bit
			}
	}else{errorLED = 1;} 
	
	if (Command(58,0,0xFF)==0){		//read CCS in the OCR - SD or SDHC
		r[0]=SPI(0xFF); r[1]=SPI(0xFF); r[2]=SPI(0xFF); r[3]=SPI(0xFF);		//rest of R3
		sdhc=r[0] & 0x40;
		if(r[0] & 0x40)sdLED=1;  
	}
	
	SSPM1 = 0;	// full speed 2MHz
	CS = 1;
}

void WriteSD(void)	
{
	unsigned int r,i;
	CS = 0;	
	ADON = 1;
	RecLED = 1;
	
	r = Command(25,loc,0xFF);	//multi sector write
	if(r != 0)
	{
		errorLED = 1;
		ADON = 0;
		RecLED = 0;
	}
	SPI(0xFF);
	SPI(0xFF);
	SPI(0xFF);
	
	while(Stop && Pause)
	{
		SPI(0xFC);	//multi sector token byte
		for(i=0;i<512;i++)
		{
			//ADC input sample
                        #if defined(__XC8)
                        GO_DONE = 1;
                        #else defined(COMPILER_MPLAB_PICC)
                        GODONE=1;
                        #endif
			while(!TMR2IF){}	//20KHz clock
			SPI(ADRESL);		//send analogue byte
			TMR2IF = 0;
				//comment next 2 lines to disable play while recording
			DC1B1 = ADRESL & 1;	//shift byte to get the required PWM duty cycle CCP1X
			CCPR1L = (ADRESL >> 1);
		}
 		SPI(0xFF);	// CRC
		SPI(0xFF);	// CRC
	
	if((r=SPI(0xFF) & 0x0F) == 0x05){	//data accepted	= 0101		
		for(i=10000;i>0;i--){				
			if(r=SPI(0xFF))	break;
		}	
	}
	else{
		errorLED = 1;
	}
	while(SPI(0xFF) != 0xFF);	// while busy
	
	if(sdhc){loc += 1;}else{loc += 512;}	//SD or SDHC 		
	}
	SPI(0xFD);	//stop transfer	token byte
			
	SPI(0xFF);
	SPI(0xFF);
	while(SPI(0xFF) != 0xFF);	// while busy
	
	CS = 1;
	ADON = 0;
	RecLED = 0;
}

void ReadSD(void)
{
	unsigned int i,r;
	unsigned char data;
	CS = 0;
	r = Command(18,loc,0xFF);	//read multi-sector
	if(r != 0)errorLED = 1;			//if command failed

	while(Stop && Pause)
	{
		while(SPI(0xFF) != 0xFE);	// wait for first byte
		for(i=0;i<512;i++){
			while(!TMR2IF){}
			data = SPI(0xFF);
			DC1B1 = data & 1;	//shift byte to get the required PWM duty cycle 
			CCPR1L = (data >> 1);
			TMR2IF = 0;
		}
		SPI(0xFF);	//discard of CRC
		SPI(0xFF);
		
		if(sdhc){loc += 1;}else{loc += 512;}	//SD or SDHC	
	}
	
	Command(12,0x00,0xFF);	//stop transmit
	SPI(0xFF);
	SPI(0xFF);
	CS = 1;
}

RaMu

https://www.picproje.org/index.php/topic,60876.msg470908.html#msg470908
Konuda bahsedilen tipte uart kontrollü mp3 modüller var,
bunlardan alıp denemeni tavsiye ederim,
vaktin varsa ebay dan çok ucuza alabilirsin.

Bahsedilen modül:
http://www.robotizmo.net/asp/product/1005/DF-Player-Mini


Ayrıca yine direk pic ile yapma çalışmalarınada devam et tabiki,
yalnız konu detaylı, iyi araştırman, çok incelemen, sabırla denemen lazım.
Çok uğraşırsın ve bu sayede birçok şey öğrenebilirsin.
Sorularınıza hızlı cevap alın: http://www.picproje.org/index.php/topic,57135.0.html

Gökhan BEKEN

Dosya sistemi kullanmadan mı yapmaya çalışıyorsunuz. Böyle yaparsanız işletim sistemi dosyayı göremez.
FatFs kütüphanesi ile yapmanız lazım.
Fseek fonksiyonu ile ilgili byte'lara geçip , dosyanın header kısmını sürekli olmasa bile saniyede bir kere güncellemeniz gerek. Güncelledikten sonra tekrar fseek ile kaldığınız sektöre geçmeniz lazım.
Stop komutundan sonra dosyayı close fonksiyonu ile kapatmanız yani kaydetmeniz gerek.
Özel mesaj okumuyorum, lütfen göndermeyin.

akrepefe007

Alıntı YapKonuda bahsedilen tipte uart kontrollü mp3 modüller var,
Ramu Teşekkür ederim öncelikle. elimde aliexpress ten aldıgım bir modul var .ad4 formatlı dosyaları çalıyor. fakat bu bir proje olacagı için yazılım kısmını da sunmam gerekiyor. bu yüzden modul işimi görmüyor. teşekkürlerimi sunuyorum tekrar ....
Alıntı YapAyrıca yine direk pic ile yapma çalışmalarınada devam et tabiki,
yalnız konu detaylı, iyi araştırman, çok incelemen, sabırla denemen lazım.
Çok uğraşırsın ve bu sayede birçok şey öğrenebilirsin.
elbette bu işin peşini bırakmam fakat şu an biraz zaman kısıtlı oldugu için burada konuyu paylaşıp bir çözüm yolu ve yöntem bulmak istedim...
Alıntı YapDosya sistemi kullanmadan mı yapmaya çalışıyorsunuz.
Gökhan bey sorun şu ki henüz nasıl bir yol izleyeceğimi bilmiyorum. sizin aydınlatmalarınız ile biraz birşeyler şekillenmeye başladı kafamda. fatFs ve Fseek fonksiyonları nasıl kullanılır bilmediğim için şu an verdiğiniz çözüm bana korkutucu geldi diyebilirim:)...
Yazılımda ilk bit ve son bitin alındıgı fonksiyon var.
char Command(unsigned char frame1, unsigned long adrs, unsigned char frame2 )
{	
	unsigned char i, res;
	SPI(0xFF);
	SPI((frame1 | 0x40) & 0x7F);	//first 2 bits are 01
	SPI((adrs & 0xFF000000) >> 24);		//first of the 4 bytes address
	SPI((adrs & 0x00FF0000) >> 16);
	SPI((adrs & 0x0000FF00) >> 8);
	SPI(adrs & 0x000000FF);	
	SPI(frame2 | 1);				//CRC and last bit 1

	for(i=0;i<10;i++)	// wait for received character
	{
		res = SPI(0xFF);
		if(res != 0xFF)break;
	}
	return res;	  
}


mesela burdan anladıgım ilk 2 bit 01 son bit ise 1 şeklinde. yani veri 01...........1 şeklinde saklanıyor. benim yakalamam gereken noktalar
1) ya son bit olan 1'i bulup if komutu ile 1 i görünce dur diyebilmek ki böyle br yazılımda arada kalan 1 ler ne olacak?
2)ya da önceden söylediğim gibi kayıt işlemi sırasında başka bir yerde kayıt süresini başka bir değişkende tutup, okuma işlemi başladıgı anda bu süre kadar pic'e akım verip sonra pic'in akımını kesmek, pic'i uyku moduna almak ya da stop butonunu tetiklemek gibi bir çözüm bulmalıyım.

akrepefe007


akrepefe007

tamam arkadaşlar gerek kalmadı. yaptım ben devreyi. yardım almak isteyen olursa her türlü yardımı yaparım. direk kod bile yazar gönderrim.