Jump to content
PLC Forum


Sign in to follow this  
dott.cicala

PIC 12F1572

Recommended Posts

gabri-z

Questo PICcino e' capace di pilotare direttamente il trasformatore ?

Share this post


Link to post
Share on other sites

dott.cicala

certo che sì....è un trasformatorino - ino - ino   :superlol:.....audio 300+300 ohm/600ohm da 20mW....in pratica 7x9mm 

fc105f2e105d3d13d2eef9b5a165653b.jpg

Buon Anno!

Share this post


Link to post
Share on other sites
dott.cicala

Come funziona

....ultimo intervento fino all'anno prossimo...credo....:superlol:

L'alimentazione è prelevata dalla linea telefonica e la corrente assorbita non supera mai 1mA...ho infatti eliminato l'unico led previsto...perché assorbiva più di tutto il resto.

D1 limita a 3,3V l'alimentazione e grazie a C2 il circuito rimane alimentato anche durante la generazione degli impulsi da parte del telefono.

Il pic al suo interno ha il Fixed Voltage Reference.....che alimenta, guarda caso, anche l'oscillatore interno e quindi per l'alimentazione basta una tensione compresa fra 2,8V e 5,2V.

D4 limita a 15V la tensione prelevata dalla linea che, in caso di cornetta agganciata è di circa 48Vcc e in presenza dello squillo raggiunge i 150Vca 25Hz.

Il partitore formato da R6-R5-R4 esplica una duplice funzione:

1) fornisce gli impulsi della composizione al pic attraverso RA4 i quali sono limitati a 3,3V dallo zener D2

2) fornisce il segnale di ON HOOK , cioè cornetta alzata, al PIC via RA2. Infatti quando la cornetta è alzata la tensione di linea scende sotto i 7V e quindi, grazie al partitore, su RA2 sarà presente uno zero logico.

Quando RA2 è basso, il pic si aspetta di ricevere entro un tempo, gli impulsi di composizione, altrimenti se ne torna in sleep. Non appena riconosce una cifra attraverso gli impulsi ricevuti, da RA0-RA1 viene generato il bi-tono corrispondente che, passando dal filtro P.B.  composto da R2-C7-R3, viene applicato all'avvolgimento a 300ohm di T1 e quindi iniettato sulla linea tramite l'avvolgimento a 600ohm.

Quando il pic è in sleep....consuma talmente poco che non sono riuscito ad effettuare una misura precisa.....:superlol:

Buona Fine...

Share this post


Link to post
Share on other sites
gabri-z

Quando il pic è in sleep....consuma talmente poco che non sono riuscito ad effettuare una misura precisa.....:superlol:

Dott' , guarda che qualche settimana fa , in una discussione  (forse quella con i LED..LED ..etc di kim , e spero che non mi spari se sbaglio :superlol:) , era presentato uno strumentino ino ino  , che misurava anche 2 nA ; forse fa il Tuo caso :smile: . :roflmao:

 

Buona Fine !!!

Edited by gabri-z

Share this post


Link to post
Share on other sites
dott.cicala

che misurava anche 2 nA

Sì l'ho visto...ma mi stava antipatico il tizio del video.....:roflmao: ...e poi che mi importa misurare i nA....ho strumenti che arrivano al pA  e anche per misurare i pC.....:P

Edited by dott.cicala

Share this post


Link to post
Share on other sites
gabri-z

Sì l'ho visto...ma mi stava antipatico il tizio del video.....:roflmao: .

 Si ? vuol dire che hai premuto PLAY :superlol: , io no .

Share this post


Link to post
Share on other sites
dott.cicala

Nuovo anno.....nuovo Pulse-DTMF encoder ovviamente con il 12F1572 :smile:

f93c541c97c3d668aa1d260c0ec8172f.jpg

Si è reso necessario modificare il circuito perché, in presenza dello squillo di chiamata, ai capi della linea telefonica, è presente un segnale a 25Hz con ampiezza tale da provocare l'intervento dello zener e ciò sovraccaricava inutilmente  la linea stessa.

Quindi l'ho eliminato e con un bel NMOS da 800V in case IPAK  abbinato ad un TL431 ho realizzato un interruttore elettronico che si attiva solo quando la tensione ai capi della linea scende a 14V circa, cioè quando la cornetta è alzata. Già che c'ero, ho aggiunto un altro TL431 per rilevare gli impulsi di composizione.

Viste le modifiche elettriche, è stato necessario rivisitare il firmware...ovviamente.

- Il pic non rimane più in sleep ma si spegne completamente.

- Sfrutto la funzione PWRT (power up timer) e genero un ulteriore ritardo software a seguito dell'alimentazione del pic

- Conto i fronti di discesa degli impulsi per identificare la cifra selezionata

- Genero un ritardo ritorno disco in funzione del numero identificato

- Genero qualche segnalazione tramite led che nello schema non ho riportato

 

 

L'unico limite che non sono riuscito a superare è la generazione dei caratteri alfanumerici ...perché non ho idea di come comporli col disco :superlol:

 

 

Il codice è venuto così:

e276b0f10503878a9459ad857f5cda77.JPG

 

//******************************************************************************
// Project :            Pulse to DTMF Converter - quarzeless
// Author  :            S.T. 4 my old phone
// Date    :            04/01/2016
// MCU     :            PIC12F1572 - INT.OSC. 8MHz
// Compiler:            MikroC PRO for PIC V6.6.2
//******************************************************************************
//****** TAGs ******************************************************************

// Inputs
   sbit Ipulse  at RA3_BIT;
// Outputs
   sbit Led2    at RA2_BIT;
   sbit Led4    at RA4_BIT;
   sbit Led5    at RA5_BIT;

// Stat
   long int dly0=0;
   unsigned int Dc1=0, Dc2=0, dly1=0, dly2=0, dly3=0, dlx=0, dly=50, blink=0;
   unsigned short int  n=0, num=0;
   bit  OnHook, rdy, chk_pulse, tx_pulses;
//******************************************************************************
// FREQUENZE DTMF
//******************************************************************************
/*        +--- +-------------------+          +-------------------------+
          | Hz |1209|1336|1477|1633|          | PITCH | f. richieste Hz |
     +----+----+----+----+----+----+          +-------------------------+
     | Y1 |697 | 1  | 2  | 3  | A  | 716      | 716   |     697   |  Y1 |
     +----+----+----+----+----+----+          +-------------------------+
     | Y2 |770 | 4  | 5  | 6  | B  | 650      | 650   |     770   |  Y2 |
     +----+----+----+----+----+----+          +-------------------------+
     | Y3 |852 | 7  | 8  | 9  | C  | 587      | 587   |     852   |  Y3 |
     +----+----+----+----+----+----+          +-------------------------+
     | Y4 |941 | *  | 0  | #  | D  | 531      | 531   |     941   |  Y4 |
     +----+----+----+----+----+----+          +-------------------------+
          |    | X1 | X2 | X3 | X4 |          | 413   |     1209  |  X1 |
          +----+----+----+----+--- +          +-------------------------+
                413  373  338  305            | 373   |     1336  |  X2 |
                                              +-------------------------+
                                              | 338   |     1477  |  X3 |
                                              +-------------------------+
                                              | 305   |     1633  |  X4 |
                                              +-------------------------+
*/
 unsigned int X0=0, X1=413, X2=373, X3=338, X4=305;
 unsigned int Y0=0, Y1=716, Y2=650, Y3=587, Y4=531;
 
//******************************************************************************
// Blink sub
//******************************************************************************
 void blk()
     {
       if(rdy &!INTCON.TMR0IE)
        {
         if(blink<4000)blink++;
         if(blink>=4000)
          {
           Led4=~Led4;
           blink=0;
          }
        }
       if(rdy &INTCON.TMR0IE)
        {
         Led4=1;
        }
       if(!rdy &!INTCON.TMR0IE)
        {
         Led4=0;
        }
     }
//******************************************************************************
// On Hook Off Hook CTRL
//******************************************************************************
void Hook()
     {
     if(OnHook &! rdy)
       {
        dly0++;
        if(dly0>=35000)
         {
          dly1=0;
          dly2=0;
          dly3=0;
          tx_pulses=0;
          TMR0=1;
          INTCON.TMR0IF=0;
          IOCAP.IOCAP3=0;
          IOCAP.IOCAN3=1;
          IOCAF.IOCAF3=0;
          INTCON.GIE  =1;
          rdy=1;
         }
       }
      if(!OnHook & rdy)
       {
        dly0--;
        if(dly0<1)
         {
          n=0;
          num=0;
          dly1=0;
          dly2=0;
          dly3=0;
          tx_pulses=0;
          TMR0=1;
          INTCON.TMR0IF=0;
          INTCON.TMR0IE=0;
          IOCAP.IOCAP3=0;
          IOCAP.IOCAN3=0;
          INTCON.GIE  =0;
          rdy=0;
          }
       }
     }
//******************************************************************************
// Pulses Counter
//******************************************************************************
void P_counter()
     {
      if(IOCAF.IOCAF3 &!Ipulse)
       {
          n++;
          TMR0=1;
          dly1=0;
          dly2=0;
          dly3=0;
          dly=(50*n)+50;
          INTCON.TMR0IE=1;
          IOCAF.IOCAF3=0;
       }
      if(n>10)n=0;
      if(tx_pulses &n<=10)
       {
        num=n;
       }
      Led5=tx_pulses;
     }
//******************************************************************************
// Main program
//******************************************************************************
void main()
 {
//******************************************************************************
// Registro configurazione Oscillatore
//******************************************************************************
       OSCCON  = 0b01110010;     // Int Osc 8MHz 4xPLL OFF
/*                              bit 6543
                                    1111 = 16 MHz HF
                                    1110 = 8 MHz or 32 MHz HF
                                    1101 = 4MHz HF
                                    1100 = 2MHz HF
                                    1011 = 1MHz HF
                                    1010 = 500 kHz HF
                                    1001 = 250 kHz HF
                                    1000 = 125 kHz HF
                                    0111 = 500 kHz MF (default upon Reset)
                                    0110 = 250 kHz MF
                                    0101 = 125 kHz MF
                                    0100 = 62.5 kHz MF
                                    0011 = 31.25 kHz HF
                                    0010 = 31.25 kHz MF
                                    000x = 31kHz LF
*/
       OSCTUNE = 0b00000000;    // 0b00000000 - factory-calibrated frequency
                                // 0b00011111 - max frequency
                                // 0b00100000 - min frequency
//******************************************************************************
// Registri configurazione PORT[A]
//******************************************************************************
       WPUA    = 0b00000000;    // Resistenze Pull Up disattivate
       SLRCONA = 0b00000000;    // Slew Rate non limitato
       INLVLA  = 0b00001000;    // Ctrl.Ingressi 0=TTL-1=Scmitt Triggered
       ODCONA  = 0b00000000;    // Ctrl. Outputs 0=Totem Pole-1=Open Drain
       APFCON  = 0b00000000;    // Alternate Pin Function
       TRISA   = 0b11001000;    // RA0-RA1-RA2-RA4-RA5=OUT - RA3=INPUT
       LATA    = 0b00000000;    // PORT[A] Latch register
       ANSELA  = 0b00000000;    // Ingressi Anaogici
//******************************************************************************
//                            OPTION REGISTER
//******************************************************************************
   OPTION_REG.B0      =1; // Prescaler Rate Sel bit    000| 1:2
   OPTION_REG.B1      =0; // Prescaler Rate Sel bit    001| 1:4
   OPTION_REG.B2      =1; // Prescaler Rate Sel bit    010| 1:8
                          //                           011| 1:16
                          //                           100| 1:32
                          //                           101| 1:64
                          //                           110| 1:128
                          //                           111| 1:256

   OPTION_REG.PSA     =0; // Prescaler Assign. bit:    0= TMR0 assigned
                          //                           1= TMR0 not assigned

   OPTION_REG.TMR0SE  =0; // TMR0 Source Edge Sel bit: 1 = Inc. H to L T0CKI pin
                          //                           0 = Inc. L to H T0CKI pin

   OPTION_REG.TMR0CS  =0; // TMR0 Clk Source Sel bit:  1= on T0CKI pin
                          //                           0= cycle clk (FOSC/4)

   OPTION_REG.INTEDG  =0; // Interrupt Edge Sel bit:   1= rising edge  INT pin
                          //                           0= falling edge INT pin

   OPTION_REG.B7      =0; // WPUEN: Weak Pull-Up Enable bit
                          // 1 = All weak pull-ups disabled (except MCLR)
                          // 0 = Weak pull-ups enabled by individual WPUx
//******************************************************************************
//                            INTCON REGISTER
//******************************************************************************
       INTCON.IOCIF   =0; // Read Only Interrupt-on-Change Flag bit
                          // 1 = The interrupt-on-change pins has changed state
                          // 0 = interrupt-on-change pins - state not changed

       INTCON.INTF    =0; // External Interrupt Flag bit
                          // 1 = The INT external interrupt occurred
                          // 0 = The INT external interrupt did not occur

       INTCON.TMR0IF  =0; // TMR= Overflow Interrupt Flag bit
                          // 1 = TMR0 register has overflowed
                          // 0 = TMR0 register did not overflow

       INTCON.IOCIE   =0; // Interrupt-on-Change Enable bit
                          // 1 = Enables the interrupt-on-change
                          // 0 = Disables the interrupt-on-change

       INTCON.INTE    =0; // External Interrupt Enable bit
                          // 1 = Enables the INT external interrupt
                          // 0 = Disables the INT external interrupt

       INTCON.TMR0IE  =0; // TMR0 Overflow Interrupt Enable bit
                          // 1 = Enables the Timer0 interrupt
                          // 0 = Disables the Timer0 interrupt

       INTCON.PEIE    =0; // Peripheral Interrupt Enable bit(2)
                          // must be set to enable any peripheral interrupt
                          // 1 = Enables all active peripheral interrupts
                          // 0 = Disables all peripheral interrupts

       INTCON.GIE     =1; // Global Interrupt Enable bit
                          // 1 = Enables all active interrupts
                          // 0 = Disables all interrupts
//******************************************************************************
// Registri configurazione INTERRUPTS
//******************************************************************************
       PIE1    = 0b00000000;    // PERIPHERAL INTERRUPT ENABLE REGISTER 1
       PIE2    = 0b00000000;    // PERIPHERAL INTERRUPT ENABLE REGISTER 2
       PIE3    = 0b00000000;    // PERIPHERAL INTERRUPT ENABLE REGISTER 3
       PIR1    = 0b00000000;    // PERIPHERAL INTERRUPT REQUEST REGISTER 1
       PIR2    = 0b00000000;    // PERIPHERAL INTERRUPT REQUEST REGISTER 2
       PIR3    = 0b00000000;    // PERIPHERAL INTERRUPT REQUEST REGISTER 3
       IOCAP   = 0b00000000;    // INTERRUPT-ON-CHANGE PORT[A] POS.EDGE REGISTER
       IOCAN   = 0b00000000;    // INTERRUPT-ON-CHANGE PORT[A] NEG.EDGE REGISTER
       IOCAF   = 0b00000000;    // INTERRUPT-ON-CHANGE PORT[A] FLAG REGISTER
//******************************************************************************
// Registri configurazione 16-BIT PWM MODULE
//******************************************************************************
//----RA1 - PWM1 ---------------------------------------------------------------
       PWM1CON   = 0b11000000;    // module en, output en, norm pol, standard m.
       PWM1CLKCON= 0b01010001;    // HFINTOSC clock, Prescaler /32
       PWM1PR    = 0x3FF;         // PWM PERIOD COUNT REGISTER
       PWM1PH    = 0x3FF;         // PWM PHASE  COUNT REGISTER
//----RA0 - PWM2 ---------------------------------------------------------------
       PWM2CON   = 0b11000000;    // module en, output en, norm pol, standard m.
       PWM2CLKCON= 0b01010001;    // HFINTOSC clock, Prescaler /32
       PWM2PR    = 0x3FF;         // PWM PERIOD COUNT REGISTER
       PWM2PH    = 0x3FF;         // PWM PHASE  COUNT REGISTER
//----PWM MIRROR REGISTERS -----------------------------------------------------
       PWMLD     = 0x000;         // PWM LOAD SIMULTANEOUSLY REGISTER
//******************************************************************************
    OnHook=1;
    INTCON.TMR0IE=1;
//##############################################################################
//                               Main Loop
//##############################################################################
    while(1)
     {
//**** On Hook
     Hook();
//**** Segnalazioni led
     blk();
//**** Conteggio Impulsi
     P_counter();
//******************************************************************************
// Selezione cifra
//******************************************************************************
      switch (num){
       case 0:  Dc1=Y0;
                Dc2=X0;
                break;

       case 1:  Dc1=Y1;
                Dc2=X1;
                break;

       case 2:  Dc1=Y1;
                Dc2=X2;
                break;

       case 3:  Dc1=Y1;
                Dc2=X3;
                break;

       case 4:  Dc1=Y2;
                Dc2=X1;
                break;

       case 5:  Dc1=Y2;
                Dc2=X2;
                break;

       case 6:  Dc1=Y2;
                Dc2=X3;
                break;

       case 7:  Dc1=Y3;
                Dc2=X1;
                break;

       case 8:  Dc1=Y3;
                Dc2=X2;
                break;

       case 9:  Dc1=Y3;
                Dc2=X3;
                break;

       case 10: Dc1=Y4;
                Dc2=X2;
                break;
      }
//******************************************************************************
// Buffer PWM1-PWM2
//******************************************************************************
      if(tx_pulses)PWMLD=0x3;
      if(!tx_pulses & PWM1CON.B5)
       {
        n=0;
        num=0;
        Dc1=0;
        Dc2=0;
        PWMLD=0x3;
        INTCON.TMR0IE=0;
       }
//******************************************************************************
// Comando PWM1-PWM2
//******************************************************************************
         PWM1PR = Dc1;         // PWM PERIOD COUNT REGISTER
         PWM1PH = Dc1;         // PWM PHASE  COUNT REGISTER
         PWM1DC = Dc1/2;       // RA0 OUT PWM[2]

         PWM2PR = Dc2;         // PWM PERIOD COUNT REGISTER
         PWM2PH = Dc2;         // PWM PHASE  COUNT REGISTER
         PWM2DC = Dc2/2;       // RA1 OUT PWM[1]
     }
  }
//******************************************************************************
//##############################################################################
//                        Interrupt Routine
//##############################################################################
void interrupt(){
           if(dly1<2000)
            {
            dly1++;
            TMR0=1;
            INTCON.TMR0IF=0;
            }
//******************************************************************************
// Tempo massimo riconoscimento singolo numero
//******************************************************************************
           if(n>0)
            {
             dly2++;
            }
           if((dly2>=dly)&!tx_pulses)
            {
             tx_pulses=n>0;
             dly2=0;
             dly3=0;
            }
//******************************************************************************
// Tempo massimo emissione toni
//******************************************************************************
           if(tx_pulses & dly3<150)dly3++;
           if(dly3>=150)
            {
             dly1=0;
             dly2=0;
             dly3=0;
             tx_pulses=0;
             TMR0=1;
             INTCON.TMR0IF=0;
            }
//******************************************************************************
// Timeout
//******************************************************************************
           if(dly1>=2000)
            {
             dly1=0;
             dly2=0;
             dly3=0;
             tx_pulses=0;
             TMR0=1;
             INTCON.TMR0IF=0;
             INTCON.TMR0IE=0;
             OnHook=0;
            }
          }

 

1d2ffb29e34c256ffa71c3143e03aeb9.jpg

Rimane ancora un bel po' di spazio :smile:

 

E con questo......ho concluso!

 

Edited by dott.cicala

Share this post


Link to post
Share on other sites
sorecaro

Dopo aver seguito questa discussione con molta attenzione non mi resta che dire una cosa, ottimo lavoro. :clap:

Share this post


Link to post
Share on other sites
dott.cicala

....grazie :thumb_yello:

....stavo penzando.....ci sono ancora un sacco di periferiche e funzioni in questo piccolo integratino che si potrebbero esplorare.....ma le vacanze son finite! :(:wallbash:

Edited by dott.cicala

Share this post


Link to post
Share on other sites
sorecaro

Dott.cicala visto che mi hai messo la pulce nell'orecchio, le altre periferiche cerco di esplorare io :smile:

Share this post


Link to post
Share on other sites
Livio Orsini

poi magari screvete un tutorial a 4 mani, sarebbe una bella iniziativa.

Share this post


Link to post
Share on other sites
dott.cicala

Riassunto delle puntate precedenti :smile:

Fino ad ora, di questo pic-cino sono state usate le periferiche evidenziate in figura

6f7275e9d2f63e49cd46365d7d1b85d7.JPG

Si potrebbe sfruttare un pin libero....ed entrare nel mondo della EEPROM  con i suoi registri....e aggiungere la funzione di

richiamata ultimo numero selezionato.

A tale scopo, sarà necessario predisporre di una variabile adeguata

unsigned short int  mem[10]={0,0,0,0,0,0,0,0,0,0};

che sarà composta da un ARRAY di 10 elementi, ognuno di essi inizializzato a zero, di tipo unsigned short int  cioè un intero corto senza segno. 

Servirà un indice per indicizzare l'array

unsigned short int  m=0

e quindi scrivere tutto ciò che serve per riempire l'array con le cifre dell'ultimo numero chiamato

//******************************************************************************
// Ultimo numero memorizzato
//******************************************************************************
void LstNum()
     {
        ...
        ...
        ...
        mem[m]=num;
     }

Chi si offre volontario?

PS.

nell'ultimo schema R3 vale 27K e non 10K 

Share this post


Link to post
Share on other sites
dott.cicala

....nell'attesa che si palesi il volontario, mi è stato chiesto di chiarire come si fa a controllare un fronte di salita o di discesa.

Ci sono almeno 2 modi.

Ammettiamo che il fronte da controllare sia quello di salita e che si presenti su RA3.

Si potrebbe agire alla vecchia maniera, tramite un bit di appoggio:

rising_edge = PORTA.B3 &! dummy;   //rising edge è il fronte di salita e dura 1 instruction cycle
dummy       = PORTA.B3;

Oppure scegliere la via più comoda, sfruttando i registri IOCAPIOCAN - IOCAF

       IOCAP   = 0b00000100;    // INTERRUPT-ON-CHANGE PORT[A] POS.EDGE REGISTER
       IOCAN   = 0b00000100;    // INTERRUPT-ON-CHANGE PORT[A] NEG.EDGE REGISTER

mettendo a 1 il bit 3 di IOCAP viene abilitato il controllo del fronte di salita di RA3

mettendo a 1 il bit 3 di IOCAN viene abilitato il controllo del fronte di discesa di RA3

Ovviamente è possibile controllare tutti e due i fronti....con le dovute cautele.

 Non appena il fronte si verifica, in IOCAF il bit 3 verrà settato e rimarrà in tale stato in attesa che il programma utente lo resetti.

Ammettiamo di voler controllare il fronte di discesa su RA3

IOCAP.IOCAP3=0;
IOCAP.IOCAN3=1;

e quindi

      if(IOCAF.IOCAF3)
       {
          n++;                    // incremento n            
          IOCAF.IOCAF3=0;         // resetto il flag generato dal fronte su RA3
       }

Se poi nel registo INTCON ci fosse questa situazione

       INTCON.GIE     =1; // Global Interrupt Enable bit
                          // 1 = Enables all active interrupts
                          // 0 = Disables all interrupts
                          
       INTCON.IOCIE   =1; // Interrupt-on-Change Enable bit
                          // 1 = Enables the interrupt-on-change
                          // 0 = Disables the interrupt-on-change

allora, al riconoscimento del fronte, si genererebbe una richiesta di INTERRUPT  ed il flag INTCON.IOCIF verrebbe posto a 1.

Non è comunque necessario ricorrere ad un interrupt per controllare un fronte in quanto  IOCAF viene scritto anche se I0CIE=0 al primo fronte rilevato.

Se ne deduce che se è necessario reagire ad entrambi i fronti, dopo aver acquisito il fronte di salita (ad esempio) è necessario azzerare IOCAF prima che si verifichi il fronte di discesa....altrimenti lo si perde.

Edited by dott.cicala

Share this post


Link to post
Share on other sites
dott.cicala

Circuito che genera due differenti segnalazioni acustiche con frequenza e durata diverse, sul fronte di salita e di discesa di RA1...... per auto...:whistling:

6ee0250a12241748f46c4c2b27898e7a.jpg

//******************************************************************************
// Project :            2 tone buzzer
// Author  :            S.T.
// Date    :            05/01/2016
// MCU     :            PIC12F1572 - INT.OSC. 8MHz
// Compiler:            MikroC PRO for PIC V6.6.2
//******************************************************************************
//****** TAGs ******************************************************************
// Inputs
   sbit In1     at RA1_BIT;
// Stat
   bit  RisingEdge, FallingEdge, app, latch;
//******************************************************************************
// Main program
//******************************************************************************
void main()
 {
//******************************************************************************
// Registro configurazione Oscillatore
//******************************************************************************
       OSCCON  = 0b01110010;     // Int Osc 8MHz 4xPLL OFF
//******************************************************************************
// Registri configurazione PORT[A]
//******************************************************************************
       INLVLA  = 0b11111110;    // Ctrl.Ingressi 0=TTL-1=Scmitt Triggered
       ODCONA  = 0b00000000;    // Ctrl. Outputs 0=Totem Pole-1=Open Drain
       TRISA   = 0b11111110;    // RA0=OUT - RA1-RA2-RA3-RA4-RA5=INPUT
       Sound_Init(&PORTA,0);
//##############################################################################
//                               Main Loop
//##############################################################################
    while(1)
     {
// RA1 - Genero fronte di salita
       RisingEdge =In1 &!app;
       app =In1;
       
// RA1 - Genero fronte di discesa
       latch = (In1|latch)&!FallingEdge;
       FallingEdge = !In1 & latch;

// RA0 - Comando buzzer
      if(RisingEdge) Sound_Play(1000,500);  //tono acuto 0.5s
      if(FallingEdge)Sound_Play(440,1000);  //tono grave 1s
     }
  }

 

 

Edited by dott.cicala

Share this post


Link to post
Share on other sites
gabri-z

.. per auto...:whistling:

Patent pending ?:roflmao: 

Edited by gabri-z

Share this post


Link to post
Share on other sites
dott.cicala

Questa volta....parliamo del DAC

6ba2768880e587903f1a69c8ad63ffa0.JPG

 

Che cosa possiamo fare con un misero DAC a 5 Bit ?

 

Un traccia curve!

 

Per realizzare un traccia curve col quale visualizzare le curve caratteristiche di diodi, bjt, fet e mosfet, scr, triac ecc ecc è necessario prima di tutto generare due segnali specifici:

 

Uno a dente di sega e uno a gradini

 

E' necessario inoltre che siano sincronizzati tra loro, Per ogni dente di sega generato deve corrispondere un gradino.

 

Tutto ciò lo si potrebbe realizzare con qualche operazionale e almeno un contatore binario oppure...con un unico 12F1572.

 

Per generare il dente di sega, si sfrutterà uno dei tre PWM disponibili, mentre per il segnale a gradini, il DAC, ma si potrebbe fare anche viceversa.

 

Ed ecco il risultato

 

06a54f1ce3e5df10388a6e584fe57854.jpg

 

Sembra che i due segnali non siano perfettamente sincronizzati, ma ciò dipende solamente dal fotografo..:thumbdown:

 

Ed ecco la struttura interna del DAC disponibile nel 12F1572

 

9948ab3538e835fdd040377191d913b1.jpg

 

 

 

 

 

 

 

 

 

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this  

×
×
  • Create New...