Sari la conținut
ELFORUM - Forumul electronistilor

Timer cu PIC12F675


Postări Recomandate

Deh, eu nu stiu programare deloc asa ca... Nici cei de la miva nu s-au obosit sa trimita coletul cu 12f675 mai repede, abia luni imi vine. Ma gandesc sa nu fie din cauza faptului ca initial proiectul s-a facut cu 675 si apoi a fost mulat pe 683. Zic si eu...

Editat de Marius84
Link spre comentariu

In simulator, cand ajunge la linia:

i = 3000;

(in acest moment atat goarna cat si farul sunt OFF si urmeaza 5 minute de OFF dar dvs spuneti ca goarna este in continuare ON la acest moment),

 

starea registrilor este:

              General Purpose IO                                                                         
9F            ANSEL                                          0x71   113           01110001      'q'      
05            GPIO                                           0x00   0             00000000      '.'      
0B            INTCON                                         0x02   2             00000010      '.'      
96            IOC                                            0x00   0             00000000      '.'      
81            OPTION_REG                                     0xFC   252           11111100      '?'      
95            WPU                                            0x37   55            00110111      '7' 

Dupa cum se vede din ANSEL, pinii GP1 si GP2 sunt LOW adica sunt digitali.

In GPIO toti pinii sunt LOW adica inclusiv pinii GP1 (goarna) si GP2 (farul) sunt OFF.

 

Asa ca la acest moment ar trebui ca totul sa fie OFF.

Ciudar, poate cineva ne lamureste daca este o problema de software. Desi m-as mira sa fie.

Editat de mars01
Link spre comentariu

Prin urmare:

- am facut montajul rapid pe o placuta, in locul celor doua, goarna si far, am montat doua LED-uri;

- prima varianta de soft pentru 12F683, la care este postat codul complet, este perfect functionala.

 

Concluzie: verificati hardware-ul dvs. Ceva este defect.

Editat de mars01
Link spre comentariu

Zic și eu , n-am citit foarte atent .

Nu cumva e vechea problemă : ”read-modify-write” ?

Poate că hardware-ul OP are capacități mai mari decât cele cu care ai testat tu ( Marius) .

Un test cu două-trei NOP-uri între scrierea celor doi pini ar putea lămuri problema .

E doar o idee....

Link spre comentariu

Radu, softul asa cum este merge perfect pe un 12F683, doar ca nu am mosfetii plasati pe care ii are Marius84.

Aseara am facut rapid un mic PCB prin toner transfer si am testat softul pe placuta aceasta. Diferenta este ca numai gaseam 12F683 in capsula DIP (era mai usor de testat) asa ca a trebuit sa fac ceva pentru 12F683 in capsula SOIC SMD care o aveam. Deja numai stiam ce se intampla, credeam ca e ceva care imi scapa ... dar nu era cazul.

 

Nu este cazul de problema RMW aici, e prea simplu softul :) mai degraba ma gandeam la ceva configurare gresita la watchdog.

 

a1i874.jpg

Editat de mars01
Link spre comentariu
Vizitator WME

Poate un led serie cu un rezistor de 470R serie legat direct la iesirea GP1 ( rezistorul din grila de FET decuplat) ar lamuri mai rapid ca aveti un FET defect acolo.

Ori mai verificati cablajul in vederea unui scurt la FET.

Din soft, nu este problema. (afirm ca incepator).

Link spre comentariu

Păi tocmai MOSFET-ii ăia ar putea constitui sarcina capacitiva de care e vorba la RMW .

Dar nu insist că asta e cauza . Seamănă însă ca manifestare .

 

EDIT. E drept că fenomenul invocat de mine poate fi vinovat doar în situațiile în care pinii sunt comandați unul după altul

gen :

 

GOARNA = ON;

FAR = ON;

 

Aici fenomenul ar face ca după executarea secvenței să avem GOARNA OFF și FAR -ul ON.

Editat de UDAR
Link spre comentariu

Ce e ciudat insa, este faptul ca problema s-a mutat de pe o iesire pe alta odata cu redefinirea iesirilor picului in soft. Daaar, maine voi alimenta picul in aer, pun la masa pinul 7 si pun doua leduri direct pe cele doua iesiri. Tare sunt curios. Am vazut ca la unele atmega de exemplu sunt diferente mari intre tipuri diferite de capsula, vorbind de functionalitate.

Link spre comentariu

Radu, cred ca ai dreptate cu RMW ... scuze pentru ca in postul anterior am trecut cu vederea atat de usor problema. Am verificat listingul de asamblare si intr-adevar se foloseau instructiunile BSF / BCF care sunt afectate de problema Read-Modify-Write.

 

O solutie ar fi ca fiecare MOSFET sa fie controlat printr-un BJT dar atunci ar trebui sa inversez in software starile (acolo unde iesirile sunt ON ele vor fi OFF si cand sunt OFF ele trebuie sa fie ON).

Aceasta ar fi cea mai OK solutie pentru a nu forta pinii controller-ului cu un curent de 25mA (cat este maxim-ul per pin) iar MOSFET-ul are mai mult de 50pF pe gate (cat este maxim-ul ce poate fi prezent pe oricare pin uC). Mai exact, 2.5nF.

 

 

 

 

Dar cred ca se poate rezolva si scriind direct registrul GPIO avand in vedere ca pinii analogici nu vor fi influentati deoarece driverul de output este deconectat pentru acestia (TRIS este setat ca input pentru acestia) iar intre schimbarile de stare avem un interval de timp suficient.

 

Softul devine asa (pentru HW-ul curent, cu tz mosfeti controlati direct din pinii uC):

/*
 * File:   main.c
 * Author: mars01 on http://www.elforum.ro
 *
 * Created on August 27, 2017, 2:08 AM
 * Datasheet PIC12F683: http://ww1.microchip.com/downloads/en/DeviceDoc/41211D_.pdf
 */


// PIC12F683 Configuration Bit Settings

// 'C' source line config statements

// CONFIG
#pragma config FOSC = INTOSCIO  // Oscillator Selection bits (INTOSCIO oscillator: I/O function on RA4/OSC2/CLKOUT pin, I/O function on RA5/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      // MCLR Pin Function Select bit (MCLR pin function is digital input, MCLR internally tied to VDD)
#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 BOREN = OFF       // Brown Out Detect (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal External Switchover mode is disabled)
#pragma config FCMEN = OFF       // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor 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_THRESHOLD   512     // jumatate din valoarea maxima a ADC

enum a {
    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
    
    TRISIO0 = 1;
    // GP0 este pin analog/ADC, restul sunt digitali
    ANS0 = 1;
    ANS1 = 0;
    ANS2 = 0;
    ANS3 = 0;
    
    CMCON0 = 0x07;      // Comparator OFF

    GOARNA_DIR = 0;
    FAR_AUTO_DIR = OUTPUT;
    
    // GOARNA = OFF;   
    // FAR_AUTO = OFF;
    GPIO = 0;
    
    // ADC init
    CHS1 = 0;   // selectam canalul 0 al ADC adica AN0 adica pinul 7
    CHS0 = 0;
    
    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(void){
    
    unsigned int result;
    CLRWDT();
    
    // 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;    // counters
    
    HW_init();
    
    while (1) {
        if (ADC_read() >= 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() >= LDR_THRESHOLD){
                while (ADC_read() >= LDR_THRESHOLD){
                    __nop();    // stai degeaba cat timp este lumina afara
                }
                
            }
        }
        
        
        CLRWDT();
        // GOARNA = ON;
        // FAR_AUTO = ON;
        GPIO = 0b00000110;

        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 = 0;

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

    }
    
    
}

Iar fisierul .HEX este atasat.

Alarma_animale_12F683.X.production.hex.txt

Editat de mars01
Link spre comentariu

Intr-adevar, cu acest hex modulul functioneaza corect, cel putin din punct de vedere al celor doua iesiri.

Timp de un minut, una a fost tot timpul on, alta 5sec on si 5 sec off. Dupa un minut, ambele s-au oprit pentru 5 minute, dupa care s-a repetat minutul de secventa on. Ceea ce nu inteleg inca, este urmatorul fapt: afara este lumina, pe pinul 7 sunt mai mult de 2,5v. Tensiunea pe acest pin trebuie sa scada mai mult de 3 secunde consecutiv sub 2,5v ca sa activeze iesirile, sau imediat ce scade sub 2,5v, chiar si o fractiune de secunda? La mine se activeaza daca aceasta tensiune scade o fractiune de secunda sub 2,5v.

Daca veti mai avea timp, poate imi dati o idee cam cum ar trebui sa arate partea hardware definitiva, chiar de mai trebuiesc adaugate componente, oricum fac alt cablaj. Ma refer aici mai mult la implementarea potentiomentrului(semireglabilului) pentru a alege din acesta valoarea dorita pentru declansare.

Multumesc!

L.E. Cred ca am privit eu gresit lucrurile. Acum inteleg ca acele 3 secunde se refera doar la momentul cand e noapte si apar lumini accidentale, nu si pentru momentul de repaus din timpul zilei impotriva perioadelor scurte cand lumina zilei scade.

Editat de Marius84
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