(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);
arkadaşlar sıkıntı nerde bilen varmı? :( :-[ :-\ :'(
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();
}
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.
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.
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?
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.
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.
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?
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?
şö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ı? ??? ??? :-\ :-\ ???