Sari la conținut
ELFORUM - Forumul electronistilor

Timer cu PIC12F675


Postări Recomandate

Scriind direct GPIO ( beneficiind de această conjunctură favorabilă în care nu avem alți pini de ieșire decât cei controlați în această secvență ) este ca și cum am folosi un registru SHADOW ( LAT de la PIC-urile mai avansate ) .

Unele recomandări zic că e suficient să intercalăm niște NOP sau GOTO $ dar eu cred că asta ( cu SHADOW sau pseudo ) este soluția corectă.

Link spre comentariu

Astazi mi-a sosit si coletul cu cei doi 12F675. Puteti sa-mi spuneti cam ce valoare trebuie sa aiba semireglabilul din pinul 3 al uC?

As fi vrut să fac acea variantă, deși și aceasta merge ok. Daca mai aveti timp, puteti sa-mi lamuriti neintelegerile din ultima postare de pe pagina anterioară?

La acel soft ar mai fi problema pe care ați rezolvat-o la 683?

Link spre comentariu

Salut,

 

Cum am promis, aveti atasata o varianta a programului pentru uC PIC12F675 care evita situatia de read-modify-write atat in software cat si in hardware. Permite reglarea pragului de lumina din potentiometrul semireglabil cu valoare 5K legat pe pinul 3 al uC 12F675.

 

Soft:

/*
 * File:   main.c
 * Author: mars01 on http://www.elforum.ro
 *
 * Created on August 30, 2017, 2:44 PM
 * Datasheet PIC12F675: http://ww1.microchip.com/downloads/en/devicedoc/41190c.pdf
 */

// PIC12F675 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTRCIO   // Oscillator Selection bits (INTOSC oscillator: I/O function on GP4/OSC2/CLKOUT pin, I/O function on GP5/OSC1/CLKIN)
#pragma config WDTE = ON        // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF      // Power-Up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = OFF      // GP3/MCLR pin function select (GP3/MCLR pin function is digital I/O, MCLR internally tied to VDD)
#pragma config BOREN = ON       // Brown-out Detect Enable bit (BOD enabled)
#pragma config CP = OFF         // Code Protection bit (Program Memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>

#define _XTAL_FREQ  4000000

#define INPUT   1
#define OUTPUT  0

#define GOARNA          GP1         // pinul 6
#define GOARNA_DIR      TRISIO1     
#define FAR_AUTO        GP2         // pinul 5
#define FAR_AUTO_DIR    TRISIO2

// LDR-ul se conecteaza pe pinul 7 adica AN0
#define LDR_DIR         TRISIO0
// Potentiometrul de reglare a pragului se conecteaza pe pinul 3 adica AN3
#define PRAG_DIR        TRISIO4

enum {
    OFF = 0,
    ON = 1
};

void HW_init(void) {
    
    
    // WDT init
    PSA = 1;    // Prescaler asigned to the watchdog
    PS2 = 1;    // Prescaler set to 1:16 so the WDT timeout period is 18ms * 16 = 288ms
    PS1 = 0;
    PS0 = 0;
    CLRWDT();   // reseteaza timer-ul watchdog
    
    LDR_DIR = INPUT;
    PRAG_DIR = INPUT;
    
    ANS0 = 1;       // GP0 este pin analog/ADC
    ANS1 = 0;       // GP1 este pin digital
    ANS2 = 0;       // GP2 este pin digital
    ANS3 = 1;       // GP3 este pin analog/ADC
    
    CMCON = 7;       // Comparator OFF
    // GOARNA = OFF;   
    // FAR_AUTO = OFF;
    GPIO = 0b00000110;

    GOARNA_DIR = OUTPUT;
    FAR_AUTO_DIR = OUTPUT;
    
    // ADC init     
    ADFM = 1;   // rezultatul ADC este aliniat la dreapta
    VCFG = 0;   // referinta este VDD

    ADCS2 = 1;  // ADCS2 = 1; ADCS1 = 1; ADCS0 = 1; => se foloseste Frc 
    ADCS1 = 1;
    ADCS0 = 1;
    ADON = 1;   // Enable ADC
        
}

unsigned int ADC_read(unsigned int channel){
    
    unsigned int result;
    CLRWDT();
    
    switch (channel) {
        case 0:
            CHS1 = 0;   // selectam canalul 0 al ADC adica AN0 adica pinul 7
            CHS0 = 0;
            break;
        case 1:
            CHS1 = 0;   // selectam canalul 1 al ADC adica AN1 adica pinul 6
            CHS0 = 1;
            break;
        case 2:
            CHS1 = 1;   // selectam canalul 2 al ADC adica AN2 adica pinul 5
            CHS0 = 0;
            break;
        case 3:
            CHS1 = 1;   // selectam canalul 3 al ADC adica AN3 adica pinul 3
            CHS0 = 1;
            break;
            
    }
    
    // cat timp ADC-ul este ocupat, asteapta sa devina disponibil
    while (GO_DONE) {
        __nop();    // stai degeaba; este introdus pt ca sa nu optimizeze compilatorul  
    }
    
    // fa un delay de 50us (>> 20us - minimum acquisition time)
    __delay_us(50);
    
    GO_DONE = 1;    // start conversion
    
    // wait for the end of the conversion
    while (GO_DONE) {
        __nop();
    }
    result = ADRESH;
    result = ((result << 8) | ADRESL) & 0x3FF;
    return result;    
}

void main() {
    unsigned int i,j,k;    // counters
    unsigned int LDR_threshold;
      
    HW_init();
    
    
    while (1) {
        
        LDR_threshold = ADC_read(3);

        if (ADC_read(0) >= LDR_threshold) {
        
            /* delay de 3secunde care sa actioneze ca protectie impotriva 
             * iluminarilor accidentale in timpul noptii cum ar fi lumina unei 
             * lanterne sau un fulger etc
            */
            for (i = 30; i > 0; i--){
                CLRWDT();
                __delay_ms(100);
            }
            
            // daca dupa 3 secunde senzorul tot indica ca este iluminat atunci
            if (ADC_read(0) >= LDR_threshold){
                while (ADC_read(0) >= LDR_threshold){
                    __nop();    // stai degeaba cat timp este lumina afara
                }
                
            }
        }
        
        
        CLRWDT();
        // GOARNA = ON;
        // FAR_AUTO = ON;
        GPIO = 0;

        i = 600;
        j = 0;
        while (i--){
            __delay_ms(100);
            CLRWDT();
            if (j > 50) {
                j = 0;
                FAR_AUTO = !FAR_AUTO;
            }
            else {
                j++;
            }
        }

        // opreste alarma audio-vizuala
        // GOARNA = OFF;
        // FAR_AUTO = OFF;
        GPIO = 0b00000110;;

        // delay 3000 * 100ms = 300000ms = 300s = 5minute
        i = 3000;
        while (i--){
            CLRWDT();
            __delay_ms(100);
        }
    }
    
    
}

Schema:

 

2iswndd.jpg

Alarma_animale.X.zip

Editat de mars01
Link spre comentariu

Desi programul de mai sus functioneaza, uitandu-ma pe el am remarcat ca am uitat sa introduc un CLRWDT() in bucla in care se asteapta sa se faca noapte). In plus, in schema am lasat un 12F683 si pentru a evita intrebarile adaug acest post in care sunt corectate problemele mentionate.

 

Schema:

 

28t8a6a.jpg

 

Proiectul este atasat. Singura modificare este adaugarea acelui CLRWDT().

 

Alarma_animale.X.zip

Link spre comentariu
Multumesc pentru tot efortul depus! Ceea ce vroiam sa va intreb, sunt urmatoarele: R6 si R7 sunt de 100 de ohmi, iar R3 de 33 de ohmi? Nu prea am inteles ce fac cu POT2. Din ceea ce am citit, cu pot 1 reglez pragul, dar pot2? La fel de putin imi explic cum sunt comandati mosii prin acei tranzistori. In mintea mea, cnd apare semnalul de 5v in baza tranzistorului, mosul primeste gnd in grila si se deschide...


Animale_2.png


Animale_2.jpg

Editat de Marius84
Link spre comentariu

Da, intr-adevar R3 este de 33 ohm si R6/R7 au valoarea de aprox 100 ohm. Valorile nu sunt stricte. R3 este pus mai mult pentru separare la programare.

R6/R7 seteza curentul prin Tz bipolare la aprox 44mA.

Rezistorii R4/R5 se ajusteaza daca este cazul in functie de factorul beta al Tz bipolare.

POT2 este cam inutil, corect. Folositi un rezistor cu valoarea discutata anterior.

 

Mosfetii dvs sunt cu canal N deci se deschid cu tensiune pe grila mai mare decat tensiunea de threshold. Tz bipolare sunt inversoare in configuratia aleasa.

Cu alte cuvinte, cu un LOW pe iesirea uC se deschide un MOSFET. LOW pe iesirea uC inseamna ca tz bipolar este inchis si grila MOSFET este legata prin R6/R7 la VCC (5V) prin urmare MOSFET-ul este deschis.

Editat de mars01
Link spre comentariu

Acum am terminat de facut montajul, dar cred ca voi ramane la prima varianta, cea cu 683.

Acest montaj consuma mult mai multa energie, compartiv cu cealalta varianta. Ia vreo 120mA, fata de vreo 10 cat consuma celalalt.

In acest moment, iesirile functioneaza pe dos decat ar trebui, sau cel putin asa am eu impresia.

De ce spun asta? Iesirile microcontrolerului sunt tinute high pentru ca bipolarul sa negativeze cat mai mult grila si mosfetul sa ramana off. Cand bipolarul nu primeste nimic in baza de la uC, mosfetul ar trebui sa porneasca, deci in grila lui sa apara circa 5v prin R6si R7, ceea ce la mine nu se intampla. Am respectat schema, doar in locul mosfetilor am pus 86t02gh de pe o placa de baza, iar in locul bipolarilor am pus 2222A. Ambii au fost testati pe super multi tester si sunt ok.

Editat de Marius84
Link spre comentariu

Ce bine ca se mai gaseste cate un om de bine sa corecteze pe cei ce nu-s in stare sa faca un cablaj pentr 20 de componente. Am remediat problema cu colectorii (rezistentele marcate cu 100k la pusesem totusi de 100R, dupa ultima discutie cu mars01), acum sunt vii si mosfetii. Din pacate, consumul este prea mare pentru nevoile mele, cca 130mA, fata de doar 4mA cat are celalalt in starea de veghe. Si nu cred ca ar scadea prea mult nici daca as elimina ledurile.

Editat de Marius84
Link spre comentariu

Nu , circa 90-100mA din consum sunt datorați rezistențelor de 100Ω ”trase” la masă de tranzistori.

Ca să muți consumul din starea de veghe în cea activă schema ar trebui modificată cu PNP în loc de NPN .

Cam așa ceva :

post-176515-0-95579500-1504445328_thumb.jpg

 

Am mărit valorile la R2 și R3 , cred că merg și mai mari . Viteza de comutare a MOSFET-ului nu e esențială în acest caz.

Link spre comentariu

Nu ati mentionat nimic legat de portabilitate/consum.

In acest caz, evident varianta in care se face drive la mosfeti direct din pinul controller-ului este mai economica deoarece singurul consum mai semnificativ al circuitului apare pentru un timp foarte scurt, la pornirea mosfetilor (max 2 x 25mA adica max 50mA).

 

O varianta buna dpdv consum este si cea propusa de Radu in postul #56.

 

Probabil ca cea mai buna varianta are fi sa se foloseasca in schema lui Radu in loc de tranzistor driver PNP un mosfet cu canal P cu capacitate mica de intrare cum ar fi BS250F (cca 2lei bucata in varianta SMD), are Ciss ~25pF < 50pF; in acest caz sursa acestuia se poate lega direct la Vin (12V).

Editat de mars01
Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum
×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări