Picproje Elektronik Sitesi

DERLEYİCİLER => Hi-Tech => Konuyu başlatan: akrepefe007 - 30 Eylül 2015, 14:17:39

Başlık: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 30 Eylül 2015, 14:17:39
(http://s13.postimg.cc/te7w7gehf/image.jpg) (http://postimg.cc/image/te7w7gehf/)

arkadaşlar bu devreyi yaptım . akım verince 0.08 A akım çekiyor. devreye akım verdiğimizde uyku moduna almak için kod yazdım fakat uyku moduna girmiyor. nerde yanlış yapıyorum acaba? derleyici Hi-tech C ya da mplab xc8 . bunlarn uyku modu kodu SLEEP(); değil mi? AŞağıda yazılımı paylaştım. SLEEP();kodunu main içerisinde While(1){} içerisine yazdım. kısacası butonlara basılmadıgı zaman uyku modunda kalması için ne yapmalıyım. kod mu yanlış kodun yeri mi bilmiyorum.

#include <htc.h>
#include <pic16f690.h>

#if defined(__XC8)
  #pragma config FOSC=HS, CP=OFF, CPD=OFF, WDTE=ON, 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
int a,b;

//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 ReadSD();
void Sayac(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(!Play)ReadSD();
if(!Rec) WriteSD();
        if(!Stop) {
Sayac();
                     }
SLEEP();                  }
}


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)
{

}

void ReadSD(void)
{
unsigned int i,r;
unsigned char data;
aq:
        Command(12,0x00,0xFF); //stop transmit
SPI(0xFF);
SPI(0xFF);
CS = 0;
        SPI(0xFF);
SPI(0xFF);
        Command(12,0x00,0xFF); //stop transmit
SPI(0xFF);
SPI(0xFF);
        if(sdhc){loc = 10;}else{loc = 5120;}
        r = Command(18,loc,0xFF); //read multi-sector
if(r != 0)errorLED = 1; //if command failed


while(Stop && Pause)
{
while(SPI(0xFF) != 0xFE)continue; // 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;
                        if(!Play)goto aq;
                       
                }
               
                SPI(0xFF); //discard of CRC
SPI(0xFF);
                Sayac();
        }

Command(12,0x00,0xFF); //stop transmit
SPI(0xFF);
SPI(0xFF);
CS = 1;

}


void Sayac(void){
       CS=1;
        if(sdhc){loc = 10;} else{loc = 5120;}
       SLEEP();
       CS=0;
        SPI(0xFF);
        SPI(0xFF);
        Command(12,0x00,0xFF); //stop transmit
SPI(0xFF);
SPI(0xFF);
       

Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 01 Ekim 2015, 16:44:38
arkadaşlar sıkıntı nerde bilen varmı?  :( :-[ :-\ :'(
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: Gökhan BEKEN - 01 Ekim 2015, 16:54:32
16f887 için bir low power fonksiyonum vardı , olduğu gibi ekliyorum, dikkat edilmesi gereken şey, low moda sokmadan önce pinlerin modularını ayarlamak, çalışan timer adc gibi kısımları iptal etmek.


void DusukMod(void) {
    INTCONbits.GIE = 0;
    OPTION_REGbits.nRBPU = 1; //PORTB pull-ups are disabled
    INTCONbits.T0IE = 0; //timer kesmesi kapali
    //T0CONbits.TMR0ON = 0;

    ADCON0bits.ADON = 0; //ADC is disabled
    ADCON0bits.CHS = 3; //Selects channel 0 ( AN3 )

    VRCONbits.VREN = 0; //datasheet sayfa 99 CVREF=0

    //TRISEbits.TRISE3=1; //MCLR
    //PORTEbits.RE3=0;


    //pinler:
    //led sat?r:
    TRISBbits.TRISB0 = 0;
    PORTBbits.RB0 = 1;

    TRISBbits.TRISB1 = 0;
    PORTBbits.RB1 = 1;

    TRISBbits.TRISB2 = 0;
    PORTBbits.RB2 = 1;

    TRISBbits.TRISB3 = 0;
    PORTBbits.RB3 = 1;

    TRISBbits.TRISB4 = 0;
    PORTBbits.RB4 = 1;

    //led sutun:
    TRISCbits.TRISC5 = 1;
    PORTCbits.RC5 = 0;

    TRISCbits.TRISC6 = 1;
    PORTCbits.RC6 = 0;

    TRISCbits.TRISC7 = 1;
    PORTCbits.RC7 = 0;

    //butonlar:
    TRISCbits.TRISC0 = 1; //denedik, bunlar cikis olursa cok akim cekiyor
    PORTCbits.RC0 = 0; //buton

    TRISCbits.TRISC1 = 1; //denedik
    PORTCbits.RC1 = 0; //motor

    //ADC'Ler:
    TRISAbits.TRISA3 = 0; //denedik farketmedi
    PORTAbits.RA3 = 0; //LDR

    TRISBbits.TRISB5 = 1; //denedik
    PORTBbits.RB5 = 0; //GSM

    TRISAbits.TRISA5 = 1; //denedik
    PORTAbits.RA5 = 0; //3G

    TRISAbits.TRISA0 = 1; //denedik
    PORTAbits.RA0 = 0; //UHF

    //kontroller:
    TRISCbits.TRISC4 = 1; //denedik
    PORTCbits.RC4 = 0; //GSM

    TRISAbits.TRISA7 = 1; //denedik
    PORTAbits.RA7 = 0; //3G

    TRISAbits.TRISA1 = 1; //denedik
    PORTAbits.RA1 = 0; //UHF

    TRISCbits.TRISC3 = 1; //denedik
    PORTCbits.RC3 = 0; //RF

    TRISCbits.TRISC2 = 0; //denedik
    PORTCbits.RC2 = 0; //MOTOR

    TRISAbits.TRISA4 = 1; //LDR
    PORTAbits.RA4 = 0; //denedik


    //kullanilmayanlar:
    TRISBbits.TRISB6 = 1; //denedik
    PORTBbits.RB6 = 0;

    TRISBbits.TRISB7 = 0; //denedik
    PORTBbits.RB7 = 1;

    TRISAbits.TRISA2 = 1; //denedik
    PORTAbits.RA2 = 0; //test point 1

    TRISAbits.TRISA6 = 1; //denedik
    PORTAbits.RA6 = 0; //test point 2


    __delay_ms(3000);

    WDTPS0 = 0x1011;

    while (1) {
        SWDTEN = 1; //wdt aktif
        SLEEP();
        SWDTEN = 0; //wdt pasif, calisma modu
        if (!INPUT_PIN_BUTON) {
            SWDTEN = 1; //software reset icin //wdt aktif
            while (1);
        }

    }


    //SLEEP();

}
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 01 Ekim 2015, 17:37:30
peki Gökhan bey onu deniyeceğim. sizin kodda uyku moduna girdikten sonra tekrar çalışma kodu geliyor. uyku modundan çıkma işlemini ne yapıyor? butonlara basmak mı? ben bir fonksiyon yazayım uyku modu için . dediğiniz gibi timer adc leri iptal edeyim. sonra da uyku moduna alayım. şöyle ki

uyku(void)
{
...//adc iptal
...//timer iptal
...// vs.
SLEEP();
}

burda mesala benim devre uyku moduna girerse geri çıkması için devrede bir butona basmam yeterli mi?uyku modundan çıkınca tekrar adc ,timer vs. aktif etmem gerekmiyor mu=? bu konularda pek çalışmadığım için sorularım basit y a da saçma olabilir. kusuruma bakmayın...
teşekkür ederim bu arada yardımınız için.
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: Gökhan BEKEN - 01 Ekim 2015, 17:59:21
Koddaki
if (!INPUT_PIN_BUTON) {
            SWDTEN = 1; //software reset icin //wdt aktif
            while (1);
}

kısmına dikkat edin, siz istediğiniz kadar sleep moduna sokun, program çalışmaya devam edecek, bu yüzden sonsuz döngüde bekletmek gerekiyor.
Sonsuz döngüden arada bir çıkıp, butonu kontrol etmesi lazım. Sonsuz döngüden çıkmasını sağlamak için watch dog timer kullanmanız lazım. Belli bir sürede çıkıp butonu kontrol edecek, basıldıysa bu moddan çıkacak.
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 02 Ekim 2015, 11:02:44
tamam işte bakın ben de main içerisindewhile(1) {
SLEEP();
        if(!Play)ReadSD();
if(!Rec) WriteSD();
        if(!Stop) {
Sayac();

        }

içerisinde butonlar kontrol ettiriyorum zaten. sanırım benim sıkıntım wdt olayı. ya da dediğiniz gibi timer ve adc kısımları fakat bunu nasıl yapacagımı henüz bilmiyorum. kod SLEEP(); değil mi bunda hemfikiriz?
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: Gökhan BEKEN - 02 Ekim 2015, 11:35:58
ReadSD ve WriteSD fonksiyonları sd kart ile ilgiliyse sıkıntı var. Uyku sırasında sd kartla konuşursanız o uykudan hayır gelmez, yine akım çekersiniz.
WDT'ı kullanın zor değil zaten, yukarıda eklediğim kodlar dışında sigorta ayarlarından da WDT ON yapın.
TIMER ve ADC'nin nasıl açılıp kapatılacağı chip'e göre değişir, datasheet'ten ilgili register'ları bulun.
SLEEP uyku için yeterli ama sağlıklı uyku için takım elbisenizi çıkartıp pijamalarınızı giymeniz gerekiyor. Bu yüzden kullandığınız her çevre birimini kapatmanız gerekiyor, uykudan çıktıktan sonra tekrar aktif etmeniz de şart.
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 02 Ekim 2015, 14:33:12
Alıntı YapReadSD ve WriteSD fonksiyonları sd kart ile ilgiliyse sıkıntı var
elbette . writeSD sd karta ses kaydıı için . butona basınca bu fonksiyon çalışıyor. ReadSd de aynı şekilde kaydı dinlemek için.
Alıntı YapBu yüzden kullandığınız her çevre birimini kapatmanız gerekiyor, uykudan çıktıktan sonra tekrar aktif etmeniz de şart.
Wdt ı on yaptım zaten ben . timer ve adc sıfırlama yerini bulamadım henüz. o konuları ddediğiniz gibi datasheetten bir araştırayım. inşallah yapabilirim.
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 10 Ekim 2015, 11:43:05
uyku moduna girip çıkıyor sürekli anlamadım gitti. giriyor 2 3 saniye bekliyor sonra çıkıyor.aynı şekilde 2 3 saniye bekleyip tekrar giriyor uyku moduna. Devreyi Deneme imkanı olan var mı acaba?
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 12 Ekim 2015, 11:24:00
WDT aktif  ettiğim içn program 2 3 saniyede bir yeniden başlıyor. WDT aktif edince neden böyle oluyor. yardımcı olabilecek var mı? yazılımda neresi etkileniyor olabilir? WDT'ı aktif yapmadan uyku moduna girilmiyor mu?
Başlık: Ynt: 16F690 ses kayıt devresi uyku modu...
Gönderen: akrepefe007 - 13 Ekim 2015, 14:24:14
şöyle bir kod yazdım ama... wdt'ı döngü içinde aktif yaptım. devre play işlemi yapmıyor artık:) öyle bekliyor.
while(1) {
           while(1) {
            if(Stop && Play && Rec ){
                          WDTCON=1;
                          SLEEP();
           }
if(!Rec) WriteSD();
if(!Play) ReadSD();
if(!Stop) {
if(sdhc){loc = 10;}else{loc = 5120;}
}

SPI haberleşmeden dolayı mı uyku moduna girmiyor.? SPI haberleşme üzerinde çalışan var mı? ??? ??? :-\ :-\ ???