walterword Inserita: 21 dicembre 2015 Segnala Inserita: 21 dicembre 2015 io non ho scritto che tu dicevi che arduino fosse un bidone...dove lo vedi ....io ho scritto "passa ad arduino che fai prima 2...non e' la stessa cosa ti pare?
dott.cicala Inserita: 21 dicembre 2015 Autore Segnala Inserita: 21 dicembre 2015 (modificato) io non ho scrittosono un po' paranoico e soffro di manie di persecuzione .....e l'ho letto tra le righe nel messaggio precedente.Li sto avendo or ora i dispiaceri con MPLAB X Prima di tutto perché il corso appena scaricato e stampato (a colori!!) ...è PIC32 based oltre ad essere orientato a piazzare...la loro demoboard.....Il 12F1572, pur essendo un 8pin, fa parte dei mid range, è sul mercato dal 2013 e c'è pochissimo in rete...e quel poco che c'è è incompleto.Questo invece è un esempio - sia pur migliorabile - funzionante.Basta scaricare MikroC, che non avrà niente di professionale ma per scopi dilettantistici è più che sufficiente, copiare-incollare il codice qui sopra, avendo cura di settare i fuses come da immagine, programmare il pic con il pickit3, realizzare il circuito su mille fori....e si ha già qualcosa di funzionante...senza impazzire con l'assembly.E in un colpo solo, viene usato un ingresso analogico, i tre pwm e un piccolo esempio su come traslare da un paio di pins ad altri due le funzioni pwm, agendo sul registoAPFCON = 0b00000011; // Alternate Pin Function: PW1->RA5 - PWM2->RA4Si ha che RA0, RA1 che di default fanno capo a PWM2 - PWM1, vengono usati come ingressiTRISA = 0b11001011; // RA2-RA4-RA5=OUT - RA0-RA1-RA3=INPUTi quali sono configurati come Schmitt Triggered insieme ad RA3 che a sua volta è configurato come ingresso e non come MCLRINLVLA = 0b00001011; // Ctrl.Ingressi 0=TTL-1=Schmitt Triggered RA0 è usato come ingresso analogicoANSELA = 0b00000001; // Ingressi Anaogici RA0=AN0I PWM non sono triggerati dai loro bit LDA, cioè il bit 7 dei rispettivi registri PWMxLDCON sbit Load1 at PWM1LDCON.B7; sbit Load2 at PWM2LDCON.B7; sbit Load3 at PWM3LDCON.B7;ma vengono triggerati simultaneamente per mezzo del registro mirror PWMLD scrivendo 111 nei bit da 0 a 2PWMLD=0x7;II bit del registo mirror PWMLD o dei rispettivi registri PWMxLDCON vedranno resettati dall'hardware non appena il nuovo valore viene assunto dai moduli PWM evitando così fenomeni di glitch. Peccato che il DAC interno abbia solo 5 bit....ma l'idea di farci un DDS a bassa frequenza mi solletica molto. Un generatore di onde quadre a duty cycle programabile....è già nell'esempio qui sopra...con un po' di fantasia....e pure a 3 canali indipendenti....e volendo...si può sincronizzarli, modificare fase , offset, perido....senza dover passare per MPLAB X Modificato: 21 dicembre 2015 da dott.cicala
Livio Orsini Inserita: 21 dicembre 2015 Segnala Inserita: 21 dicembre 2015 Peccato che il DAC interno abbia solo 5 bit....ma l'idea di farci un DDS a bassa frequenza mi solletica molto.Dai sintetizzare una sinusoide su solo 31 livelli discreti è.......come usare un vecchio inverter 3 steps.Livio non perdere tempo a studiare i ragnetti .....cerca il circuito DDSSe vuoi farti un DDS con Arduino non c'è problema ne possiamo parlare, anche se non vedo l'utilità.
dott.cicala Inserita: 21 dicembre 2015 Autore Segnala Inserita: 21 dicembre 2015 Un DDS fatto direttamente con Arduino....avrà prestazioni limitate ....meglio comandare con Arduino in seriale o parallelo un AD9851 o un AD9858,allora sì che si può fare un DDS decente......c'è già tutto pronto....basta attaccare i fili
dott.cicala Inserita: 21 dicembre 2015 Autore Segnala Inserita: 21 dicembre 2015 (modificato) Tornando al PIC12F1572.....e lasciando per un attimo i PWM, un'altra periferica semplice ma interessante è.....ll range parte da -40°C per arrivare a +85°C.urge preparare uno schemino per metterla alla prova Modificato: 21 dicembre 2015 da dott.cicala
walterword Inserita: 21 dicembre 2015 Segnala Inserita: 21 dicembre 2015 be non proprio un DDs , per quello ci sono gia dei moduli ben fatti e potenti Diciamo un modulo per pilotare gli stepper motor
Livio Orsini Inserita: 22 dicembre 2015 Segnala Inserita: 22 dicembre 2015 Pilotare gli stepper direttamente da Arduino, va bene se si realizzano giochini. Se vuoi fare un qualche cosa per alte prestazioni, con microstepping e rampe di accelerazione e decelerazione, allora è da rivedere un po' tutto.
walterword Inserita: 22 dicembre 2015 Segnala Inserita: 22 dicembre 2015 io ho due stepper nema 23 e due drive TBxxx Sto cercando di creare un semplice motion control con Arduino. Il treno di impulsi esce dal motion ossia da Arduino.Per fare questo sto facendo dei test usando l'interrupt di un timer .Rammpe , accelerazioni, selezione velocità, calcolo delle traiettorie etc le implemento nel software , che gira su Aduino.E' un po più chiaro quello che vorrei fare ? ......
dott.cicala Inserita: 22 dicembre 2015 Autore Segnala Inserita: 22 dicembre 2015 (modificato) ....E meno male che avevo definito semplice il Temperature Sensor Indicator ! MikroC...ovviamente non è capace di gestirlo e quindi, se si hanno più ingressi analogici come ho voluto fare io....non si può più utilizzare la comoda funzione di libreria ADC_Read().La comodità di questa funzione consiste nel fatto che, una volta definiti gli ingressi con il registro TRIS e definiti gli analogici con il registro ANSEL,è sufficiente richiamarla per leggere direttamente il canale analogico, così, ad esempio per leggere RA0 configurato ingresso analogico, basta scrivereVar1=ADC_Read(0) per leggere AN0Var1=ADC_Read(1) per leggere AN1ecc.Per leggere invece il sensore di temperatura....non è possibile usare la funzione, nemmeno per leggere altri canali analogici...perchè.....il convertitore AD è uno solo e viene multiplexato....e la funzione di libreria si occupa anche di questa gestione.E' quindi necessario capire come funziona il convertitoreAD a 10 bit....e tutti i suoi registri ...lasciando perdere per un momento quelli dedicati agli Interrupts...lo schema logico del convertitore non lascia spazio a dubbi ...per utilizzare il sensore di temperatura è necessario agire anche sul registro FVRCON cioè il registo che controlla il Fixed Voltage Reference, ed agire almeno sul bit di abilitazione del sensore di temperatura, che si chiamaTSEN e quindi FVRCON.TSEN=1; e il sensore è abilitato. E' inoltre necessario scegliere il range, agendo su TSRNG sempre di FVRCON.FVRCON.TSRNG=1 cortocircuita 2 diodi e si ha il range basso, che va bene con una tensione di alimentazione bassa (1.8 a 3,6V)FVRCON.TSRNG=0 vengono usati tutti e 4 i diodi...e va bene con tensioni di alimentazioni >=3,6VOra, siccome nel mio prototipo ho usato anche altri due ingressi analogici.....il codice diventa così://****************************************************************************** // Project : Standard Mode PWM Test // Author : S.T. 4 Plc Forum // Ingressi Analogici - Temp.Sens. Indicator // Date : 22/12/2015 // MCU : PIC12F1572 - INT.OSC. 32MHz // Compiler: MikroC PRO for PIC V6.6.2 //****************************************************************************** //****** TAGs ****************************************************************** sbit Load1 at PWM1LDCON.B7; sbit Load2 at PWM2LDCON.B7; sbit Load3 at PWM3LDCON.B7; sbit man at RA3_BIT; float act_temp; unsigned int Dc1, Dc2, Dc3, DutyCycle; unsigned int AnVal1, AnVal2, AnVal3, CalVal; char Catt[8]; bit dn, up, start; //****************************************************************************** //****************************************************************************** void main() { //****************************************************************************** // Registro configurazione Oscillatore //****************************************************************************** OSCCON = 0b11110000; // Int Osc 32MHz 4xPLL ON OSCTUNE = 0b00111111; // Max Frequency //****************************************************************************** // Registri configurazione PORT[A] //****************************************************************************** WPUA = 0b00000000; // Resistenze Pull Up disattivate SLRCONA = 0b00000000; // Slew Rate non limitato INLVLA = 0b00001011; // Ctrl.Ingressi 0=TTL-1=Scmitt Triggered ODCONA = 0b00000000; // Ctrl. Outputs 0=Totem Pole-1=Open Drain APFCON = 0b00000011; // Alternate Pin Function: PW1->RA5 - PWM2->RA4 TRISA = 0b11001011; // RA2-RA4-RA5=OUT - RA0-RA1-RA3=INPUT LATA = 0b00000000; // PORT[A] Latch register ANSELA = 0b00000011; // Ingressi Anaogici RA4=AN3 //****************************************************************************** // Registri configurazione INTERRUPTS //****************************************************************************** INTCON = 0b00000000; // INTERRUPTS CTRL REGISTER 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= 0b00100001; // HFINTOSC clock, Prescaler /4 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= 0b00100001; // HFINTOSC clock, Prescaler /4 PWM2PR = 0x3FF; // PWM PERIOD COUNT REGISTER PWM2PH = 0x3FF; // PWM PHASE COUNT REGISTER //----RA2 - PWM3 --------------------------------------------------------------- PWM3CON = 0b11000000; // module en, output en, norm pol, standard m. PWM3CLKCON= 0b00100001; // HFINTOSC clock, no prescaler PWM3PR = 0x3FF; // PWM PERIOD COUNT REGISTER PWM3PH = 0x3FF; // PWM PHASE COUNT REGISTER //----PWM MIRROR REGISTERS ----------------------------------------------------- PWMLD = 0x000; // PWM LOAD SIMULTANEOUSLY REGISTER //****************************************************************************** // REGISRTI AD //****************************************************************************** ADCON1 = 0b10010000; // Right Justfied - AD Clk = Fosc/32 = 1uS ADCON2 = 0b00000000; // No Autoconversion Trigger //****************************************************************************** // Temperature Indicator Module - Valore di Calibrazione //****************************************************************************** CalVal=517; //****************************************************************************** // Lettura AN0 - RA0 //****************************************************************************** while(1) { ADCON0.CHS0 =0; // BIT0 - AN SELECTOR | ADCON0.CHS1 =0; // BIT1 - AN SELECTOR | ADCON0.CHS2 =0; // BIT2 - AN SELECTOR |- RA0 SELEZIONATO ADCON0.CHS3 =0; // BIT3 - AN SELECTOR | ADCON0.CHS4 =0; // BIT4 - AN SELECTOR | ADCON0.ADON =1; // ATTIVO CONVERTITORE AD delay_us(5); // ATTENDO 5us ADCON0.GO =1; // ATTIVO LA CONVERSIONE delay_us(11); // ATTENDO 11us AnVal1=ADRES; // TRASFERISCO VALORE AD SU VARIABILE1 ADCON0.GO =0; // DISATTIVO LA CONVERSIONE ADCON0.ADON =0; // DISATTIVO CONVERTITORE AD //****************************************************************************** // Lettura AN1 - RA1 //****************************************************************************** ADCON0.CHS0 =1; // BIT0 - AN SELECTOR | ADCON0.CHS1 =0; // BIT1 - AN SELECTOR | ADCON0.CHS2 =0; // BIT2 - AN SELECTOR |- RA1 SELEZIONATO ADCON0.CHS3 =0; // BIT3 - AN SELECTOR | ADCON0.CHS4 =0; // BIT4 - AN SELECTOR | ADCON0.ADON =1; // ATTIVO CONVERTITORE AD delay_us(5); // ATTENDO 5us ADCON0.GO =1; // ATTIVO LA CONVERSIONE delay_us(11); // ATTENDO 11us AnVal2=ADRES; // TRASFERISCO VALORE AD SU VARIABILE2 ADCON0.GO =0; // DISATTIVO LA CONVERSIONE ADCON0.ADON =0; // DISATTIVO CONVERTITORE AD //****************************************************************************** // Lettura Temperature Indicator Module //****************************************************************************** FVRCON.TSRNG=0; // RANGE SENSORE TEMPERATURA FVRCON.TSEN =1; // ABILITAZIONE SENSORE TEMPERATURA ADCON0.CHS0 =1; // BIT0 - AN SELECTOR | ADCON0.CHS1 =0; // BIT1 - AN SELECTOR | ADCON0.CHS2 =1; // BIT2 - AN SELECTOR |- TEMP.Sens.Indicator ADCON0.CHS3 =1; // BIT3 - AN SELECTOR | ADCON0.CHS4 =1; // BIT4 - AN SELECTOR | ADCON0.ADON =1; // ATTIVO CONVERTITORE AD delay_us(5); // ATTENDO 5us ADCON0.GO =1; // ATTIVO LA CONVERSIONE delay_us(11); // ATTENDO 11us AnVal3=ADRES; // TRASFERISCO VALORE AD SU VARIABILE2 ADCON0.GO =0; // DISATTIVO LA CONVERSIONE ADCON0.ADON =0; // DISATTIVO CONVERTITORE AD FVRCON.TSEN =0; // DISATTIVO SENSORE TEMPERATURA //****************************************************************************** // Temperatura attuale [°C] //****************************************************************************** act_temp=((0.659-(1.25)*(1.0-((AnVal3-CalVal)/1022.0)))/0.00132))-40.0; FloatToStr(act_temp,Catt); // Temperatura da trasferire via UART //****************************************************************************** // Comando PWM1-PWM2-PWM3 //****************************************************************************** Dc1=AnVal1; Dc2=AnVal2; Dc3=AnVal3; PWMLD=0x7; PWM1DC = Dc1; //RA5 PWM2DC = Dc2; //RA4 PWM3DC = Dc3; //RA2 } } Modificato: 22 dicembre 2015 da dott.cicala
dott.cicala Inserita: 22 dicembre 2015 Autore Segnala Inserita: 22 dicembre 2015 (modificato) ...in pratica, per leggere i canali analogici abilitati è necessario rispettare questo diagramma temporale...TAD è funzone del clock e del fattore di divisione. In questo caso il clock è 32MHz e il fattore di divisione è 32 --> TAD=1usDall'abilitazione del convertitore ADCON0.ADON =1è necessario attendere almeno 4*TAD prima di attivare la conversioneADCON0.GO =1;A questo punto, trascorso il tempo cha va da TACQ a TAD11, in questo caso forzato a 16us, in AnVal3 è contenuto il valore di conversione "Right justified"ADCON1 = 0b10010000; // Right Justfied - AD Clk = Fosc/32 = 1uSrelativo al temperature sensor indictator. (In realtà ADCON0.GO viene resettato dall'AD a conversione avvenuta...)AnVal3=ADRES; // TRASFERISCO VALORE AD SU VARIABILE3 Affinché si abbia una lettura precisa, è necessario effettuare una calibrazione ad almeno un punto e ricavare il valore di calibrazione "CalVal" Quindi, il calcolo della temperatura attuale in float, e la conversione in string[8] per poter essere trasmessa via UART ad un display...eventuale.//****************************************************************************** // Temperatura attuale [°C] //****************************************************************************** act_temp=((0.659-(1.25)*(1.0-((AnVal3-CalVal)/1022.0)))/0.00132))-40.0; FloatToStr(act_temp,Catt); // Temperatura da trasferire via UARTPer la calibrazione, fare riferimento alla AN1333 dove si trova anche questa Si potrebbe riscalare il valore di conversione in modo tale che per un range di temperatura il pwm3 abbia un duty cycle da 0 a 100%per comandare una ventola....e abbiano ancora un ingresso libero che si potrebbe usare per il controllo di rotazione o come feedback di velocità.... Non male per un coso grande quanto un 555 vero? Modificato: 22 dicembre 2015 da dott.cicala
Livio Orsini Inserita: 22 dicembre 2015 Segnala Inserita: 22 dicembre 2015 A questo punto molto più semplice e comodo usare un DS1820 in I2C, che è anche più precisoBattute a parte io credo che questo dispositivo sia stato progettato per poter risolvere molti differenti problemi, però uno alla volta. Certo che per un 8 pins le prestazioni sono veramente eccezionali.Walter saimo completamente OT e rischiamo di fare una grande confusione con la storia degli stepper. Apri, se vuoi un'altra discussione.
dott.cicala Inserita: 22 dicembre 2015 Autore Segnala Inserita: 22 dicembre 2015 (modificato) Effettivamente il sensore di temperatura non ha una grande precisione. Ma per gli copi per i quali è stato progettato, la sua precisione è sufficiente. Immaginiamo che invece di un DIL8 stiamo usando un 12F1572 in case MSOP, quindi smd, e sullo stesso pcb ci siano dei mos power...e che il pcb sia montato a ridosso della loro aletta di raffreddamento...Il sensore di temperatura potrebbe controllare una ventola e mandare in protezione il sistema in caso di temperatura eccessiva...e per fare ciò, non è necessario calcolare la temperatura in °C.Oltretutto, la funzione che ho usato per la conversione...è eccessiva, sia perché calcolata in float (virgola mobile 32bit), sia perchè viene usata una funzione di libreria per convertire da float a string. act_temp=((0.659-(1.25)*(1.0-((AnVal3-CalVal)/1022.0)))/0.00132))-40.0; //Floating point 32bit FloatToStr(act_temp,Catt); // Temperatura da trasferire via UARTMemoria occupata senza la funzione di cui sopraMemoria occupata con funzione e conversione Float to StringUrge fare i conti diversamente, abbandonando la comodità della virgola mobile per passare alla notazione Unsigned Int che impegna 16bit è può rappresentare un valore max di 65535.....Oltre all'inutile spreco di memoria, c'è da considerare quanti cicli di clock sarebbero necessari per svolgere il calcolo.Volendo,si può anche calcolare...sapendo che il clock è a 32MHz..... Modificato: 22 dicembre 2015 da dott.cicala
Livio Orsini Inserita: 23 dicembre 2015 Segnala Inserita: 23 dicembre 2015 Scusa ma hai problemi di velocità e/o di occupazione di memoria?
dott.cicala Inserita: 23 dicembre 2015 Autore Segnala Inserita: 23 dicembre 2015 No...però volendo si può migliorare e risparmiare. Nel frattempo ho fatto alcune misure raffreddando e scaldando il chip e misurando la temperatura con un termometro IR. Ne è venuto fuori questo grafico.La curva arancio (counts vs °C) è prodotta dalla formula microchip senza aggiungere il valore di calibrazione. la curva blu è stata ottenuta ricavando i valori min e max count raffreddando e riscaldando e, considerando che la funzione temperatura corrente nei diodi è lineare, ho riscalato in uint per pilotare il pwm//****************************************************************************** // Temperatura attuale //****************************************************************************** // In_min =743; Out_min =102; // In_max =797; Out_max =1022; act_temp=((AnVal3-In_min)/(In_max-In_min)*(Out_max-Out_min))+Out_min;//****************************************************************************** // Comando PWM1-PWM2-PWM3 //****************************************************************************** Dc1=AnVal1; Dc2=AnVal2; Dc3=act_temp; PWMLD=0x7; PWM1DC = Dc1; //RA5 PWM2DC = Dc2; //RA4 PWM3DC = Dc3; //RA2Ora si può comandare una ventola in funzione della temperatura del chip.....e l'occupazione di memoria diventa cosìRimane spazio per fare qualcos'altro: Il controllo rotazione tramite l'ingresso RA3 rimasto libero.
dott.cicala Inserita: 23 dicembre 2015 Autore Segnala Inserita: 23 dicembre 2015 (modificato) Lo scaling con interi non va bene.(AnVal3-In_min)/(In_max-In_min) Il risultato di questa in intero può assumere solo due valori: - Zero per il valore minimo di ingresso- UNO per il valore massimo di ingresso Di conseguenza il risultato dellaact_temp=((AnVal3-In_min)/(In_max-In_min))*(Out_max-Out_min)+Out_min;ha solo due valori:- Out_min- Out_maxLa soluzione più semplice è usare il float e convertire il risultato in INTact_temp=(int)(Out_min+(((In_Val -In_min)/(In_max-In_min))*(Out_max-Out_min)));Rimane comunque abbastanza memoria per fare qualcos'altroDa tutto ciò è evidente che il Temperature Indicator Module è più adatto ad una regolazione ON-OFF piuttosto che lineare... Modificato: 23 dicembre 2015 da dott.cicala
dott.cicala Inserita: 24 dicembre 2015 Autore Segnala Inserita: 24 dicembre 2015 (modificato) Grazie!Nel frattempo ....dopo una nottata a raffreddare e riscaldare il PIC con mezzi ultra professionali (lattina gelata e stazione dissaldante con getto a 100°C)sono riuscito a calibrare meglio la scala e quindi...mi devo ricredere. Una volta calibrata la scala, è possibile eseguire una regolazione lineare dell'uscita PWM che comanda la ventola.Ecco il risultato finale//****************************************************************************** // Project : Standard Mode PWM Test // Author : S.T. 4 Plc Forum // Ingressi Analogici - Temp.Sens. Indicator // Date : 22/12/2015 // MCU : PIC12F1572 - INT.OSC. 32MHz // Compiler: MikroC PRO for PIC V6.6.2 //****************************************************************************** //****** TAGs ****************************************************************** sbit Load1 at PWM1LDCON.B7; sbit Load2 at PWM2LDCON.B7; sbit Load3 at PWM3LDCON.B7; sbit trip at RA3_BIT; unsigned int Dc1, Dc2, Dc3; unsigned int AnVal1, AnVal2, AnVal3, Temp; float In_min, In_max, Out_min, Out_max; bit mem; //****************************************************************************** //****************************************************************************** void main() { //****************************************************************************** // Registro configurazione Oscillatore //****************************************************************************** OSCCON = 0b11110000; // Int Osc 32MHz 4xPLL ON OSCTUNE = 0b00111111; // Max Frequency //****************************************************************************** // Registri configurazione PORT[A] //****************************************************************************** WPUA = 0b00000000; // Resistenze Pull Up disattivate SLRCONA = 0b00000000; // Slew Rate non limitato INLVLA = 0b00001011; // Ctrl.Ingressi 0=TTL-1=Scmitt Triggered ODCONA = 0b00000000; // Ctrl. Outputs 0=Totem Pole-1=Open Drain APFCON = 0b00000011; // Alternate Pin Function: PW1->RA5 - PWM2->RA4 TRISA = 0b11001011; // RA2-RA4-RA5=OUT - RA0-RA1-RA3=INPUT LATA = 0b00000000; // PORT[A] Latch register ANSELA = 0b00000011; // Ingressi Anaogici RA4=AN3 //****************************************************************************** // Registri configurazione INTERRUPTS //****************************************************************************** INTCON = 0b00000000; // INTERRUPTS CTRL REGISTER 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 //****************************************************************************** //----RA5 - PWM1 --------------------------------------------------------------- PWM1CON = 0b11000000; // module en, output en, norm pol, standard m. PWM1CLKCON= 0b00100001; // HFINTOSC clock, Prescaler /4 PWM1PR = 0x3FF; // PWM PERIOD COUNT REGISTER PWM1PH = 0x3FF; // PWM PHASE COUNT REGISTER //----RA4 - PWM2 --------------------------------------------------------------- PWM2CON = 0b11000000; // module en, output en, norm pol, standard m. PWM2CLKCON= 0b00100001; // HFINTOSC clock, Prescaler /4 PWM2PR = 0x3FF; // PWM PERIOD COUNT REGISTER PWM2PH = 0x3FF; // PWM PHASE COUNT REGISTER //----RA2 - PWM3 --------------------------------------------------------------- PWM3CON = 0b11000000; // module en, output en, norm pol, standard m. PWM3CLKCON= 0b00100001; // HFINTOSC clock, no prescaler PWM3PR = 0x3FF; // PWM PERIOD COUNT REGISTER PWM3PH = 0x3FF; // PWM PHASE COUNT REGISTER //----PWM MIRROR REGISTERS ----------------------------------------------------- PWMLD = 0x000; // PWM LOAD SIMULTANEOUSLY REGISTER //****************************************************************************** // REGISRTI AD //****************************************************************************** ADCON1 = 0b10010000; // Right Justfied - AD Clk = Fosc/32 = 1uS ADCON2 = 0b00000000; // No Autoconversion Trigger //****************************************************************************** // Temperature Indicator Module - Valori Scaling //****************************************************************************** In_min =747.5; Out_min =0.; In_max =815.; Out_max =1022.; mem =0; //****************************************************************************** // Lettura AN0 - RA0 //****************************************************************************** while(1) { ADCON0.CHS0 =0; // BIT0 - AN SELECTOR | ADCON0.CHS1 =0; // BIT1 - AN SELECTOR | ADCON0.CHS2 =0; // BIT2 - AN SELECTOR |- RA0 SELEZIONATO ADCON0.CHS3 =0; // BIT3 - AN SELECTOR | ADCON0.CHS4 =0; // BIT4 - AN SELECTOR | ADCON0.ADON =1; // ATTIVO CONVERTITORE AD delay_us(6); // ATTENDO 6us ADCON0.GO =1; // ATTIVO LA CONVERSIONE delay_us(11); // ATTENDO 11us AnVal1=ADRES; // TRASFERISCO VALORE AD SU VARIABILE1 ADCON0.GO =0; // DISATTIVO LA CONVERSIONE ADCON0.ADON =0; // DISATTIVO CONVERTITORE AD //****************************************************************************** // Lettura AN1 - RA1 //****************************************************************************** ADCON0.CHS0 =1; // BIT0 - AN SELECTOR | ADCON0.CHS1 =0; // BIT1 - AN SELECTOR | ADCON0.CHS2 =0; // BIT2 - AN SELECTOR |- RA1 SELEZIONATO ADCON0.CHS3 =0; // BIT3 - AN SELECTOR | ADCON0.CHS4 =0; // BIT4 - AN SELECTOR | ADCON0.ADON =1; // ATTIVO CONVERTITORE AD delay_us(6); // ATTENDO 6us ADCON0.GO =1; // ATTIVO LA CONVERSIONE delay_us(11); // ATTENDO 11us AnVal2=ADRES; // TRASFERISCO VALORE AD SU VARIABILE1 ADCON0.GO =0; // DISATTIVO LA CONVERSIONE ADCON0.ADON =0; // DISATTIVO CONVERTITORE AD //****************************************************************************** // Lettura Temperature Indicator Module //****************************************************************************** FVRCON.TSRNG=0; // RANGE SENSORE TEMPERATURA FVRCON.TSEN =1; // ABILITAZIONE SENSORE TEMPERATURA ADCON0.CHS0 =1; // BIT0 - AN SELECTOR | ADCON0.CHS1 =0; // BIT1 - AN SELECTOR | ADCON0.CHS2 =1; // BIT2 - AN SELECTOR |- TIM SELEZIONATO ADCON0.CHS3 =1; // BIT3 - AN SELECTOR | ADCON0.CHS4 =1; // BIT4 - AN SELECTOR | ADCON0.ADON =1; // ATTIVO CONVERTITORE AD delay_us(250); // ATTENDO 250us ADCON0.GO =1; // ATTIVO LA CONVERSIONE delay_us(202); // ATTENDO 202us AnVal3=ADRES; // TRASFERISCO VALORE AD SU VARIABILE2 ADCON0.GO =0; // DISATTIVO LA CONVERSIONE ADCON0.ADON =0; // DISATTIVO CONVERTITORE AD FVRCON.TSEN =0; // DISATTIVO SENSORE TEMPERATURA //****************************************************************************** // Scaling Temperature Indicator Module vs PWM - CTRL limiti //****************************************************************************** if(AnVal3<In_min)AnVal3=In_min; if(AnVal3>In_max)AnVal3=In_max; //****************************************************************************** // Scaling Temperature Indicator Module vs PWM //****************************************************************************** Temp=(int)(Out_min+(((AnVal3-In_min)/(In_max-In_min))*(Out_max-Out_min))); //****************************************************************************** // Trip //****************************************************************************** if(trip) { AnVal1=0; AnVal2=0; Temp =0; } //****************************************************************************** // Comando PWM1-PWM2-PWM3 //****************************************************************************** Dc1=AnVal1; // RA0 AI --> RA5 OUT PWM[2] Dc2=AnVal2; // RA1 AI --> RA4 OUT PWM[1] Dc3=Temp; // Temperature Indicator Module PWMLD=0x7; // PWM1-2-3 LOAD TRIGGER SOURCE PWM1DC = Dc1; //RA5 OUT PWM[2] PWM2DC = Dc2; //RA4 OUT PWM[1] PWM3DC = Dc3; //RA2 OUT PWM[TIM] } }E' stato necessario aggiungere il controllo dei limiti//****************************************************************************** // Scaling Temperature Indicator Module vs PWM - CTRL limiti //****************************************************************************** if(AnVal3<In_min)AnVal3=In_min; if(AnVal3>In_max)AnVal3=In_max;BUON NATALE! Modificato: 24 dicembre 2015 da dott.cicala
dott.cicala Inserita: 29 dicembre 2015 Autore Segnala Inserita: 29 dicembre 2015 Dopo la pausa natalizia....un altro progettino interessante: PSTN-DTMF converter...senza quarzo e senza integrati speciali.Il solo 12F1572 riesce a far tutto. Alimentato dalla linea telefonica, il circuito è abbastanza piccolo da trovar posto all'interno di un vecchio telefono dei nonni a composizione decadica che desideravo riportare in servizio //****************************************************************************** // Project : PSTN-DTMF Converter - senza quarzo // Author : S.T. 4 my old phone // Date : 29/12/2015 // MCU : PIC12F1572 - INT.OSC. 8MHz // Compiler: MikroC PRO for PIC V6.6.2 //****************************************************************************** //****** TAGs ****************************************************************** sbit Pulses at RA3_BIT; sbit Led at RA5_BIT; unsigned int Dc1, Dc2, Dc3; int num; bit mem1; mem2; //****************************************************************************** // FREQUENZE DTMF //****************************************************************************** /* +--- +-------------------+ +-------------------------+ | Hz |1209|1336|1477|1633| | PITCH | f. richieste Hz | +----+----+----+----+----+----+ +-------------------------+ | Y1 |697 | 1 | 2 | 3 | A | | 716 | 697 | +----+----+----+----+----+----+ +-------------------------+ | Y2 |770 | 4 | 5 | 6 | B | | 650 | 770 | +----+----+----+----+----+----+ +-------------------------+ | Y3 |852 | 7 | 8 | 9 | C | | 587 | 852 | +----+----+----+----+----+----+ +-------------------------+ | Y4 |941 | * | 0 | # | D | | 531 | 941 | +----+----+----+----+----+----+ +-------------------------+ | | X1 | X2 | X3 | X4 | | 413 | 1209 | +----+----+----+----+--- + +-------------------------+ | 373 | 1336 | +-------------------------+ | 338 | 1477 | +-------------------------+ | 305 | 1633 | +-------------------------+ */ unsigned int X1=1209, X2=1336, X3=1477, X4=1633; unsigned int Y1=697, Y2=770, Y3=852, Y4=941; //****************************************************************************** void main() {...........................coming soon
Livio Orsini Inserita: 30 dicembre 2015 Segnala Inserita: 30 dicembre 2015 Stefano di questo passo dovremmo aprirti una sezione dedicata 12F1572 Comunque son lavoretti interessanti da cui si possono anche trarre spunti per altri lavori.
dott.cicala Inserita: 30 dicembre 2015 Autore Segnala Inserita: 30 dicembre 2015 (modificato) Spunti che rimangono...specialmente a me...essendo disordinato molte volte cose che avevo fatto e poi perso le ho recuperate perché pubblicate sul forum Generare i toni DTMF è stato semplice. Non volendo bruciare la memoria con funzioni complesse, ho usato 2 pwm comandati in periodo, mantenendo il duty cycle al 50% e scegliendo un clock che abbinato al fattore del prescaler dei pwm consenta di ottenere le frequenze richieste.Con un clock a 8MHz e prescaler a /32 si ottiene che, ad esempio, caricando il valore 650 in PWMxPR viene generatala frequenza di 770,5 Hz cioè 0,5Hz in più di quanto necessario ma comunque in tolleranza rispetto la specifica.Perchè funzioni il PWM in standard mode, il valore caricato in PWMxPR deve essere uguale a quanto caricato il PWMxPH e ciò semplifica la formula dalla quale si ottiene che per avere un duty cycle del 50% è sufficiente che PWMxDC= PWMxPR/2//****************************************************************************** // 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] A Questo punto basta un case e prelevare dalla matrice X,Y i valori da assegnare ai due PWM, switch (numSel[i]){ case 1: Dc1=X1; Dc2=Y1; PWMLD=0x7;; break;poi si mixano le due uscite con due condensatori e il tono è fatto.Adesso viene la parte un po' più difficile- Contare gli impulsi- distinguere l' interdigit, cioè il ritorno del disco compositore ed emettere il tono in questo istante Modificato: 30 dicembre 2015 da dott.cicala
sorecaro Inserita: 30 dicembre 2015 Segnala Inserita: 30 dicembre 2015 Dott. Cicala se per lei non é un problema potrebbe postare lo schema per il convertitore pstn-dtmf. Sarei interessato al progetto.Grazie
dott.cicala Inserita: 30 dicembre 2015 Autore Segnala Inserita: 30 dicembre 2015 (modificato) Al momento non c'è ancora uno schema definitivo.Nel frattempo.....come verificare se i toni generati sono corretti e se vengono riconosciuti....senza impegnare la linea telefonica???Tutti i numeri hanno generato i rispettivi toni...e sono stati pure riconosciuti! ...alla faccia di tutti gli integratini e dei loro quarzi con frequenze balorde! Modificato: 30 dicembre 2015 da dott.cicala
dott.cicala Inserita: 31 dicembre 2015 Autore Segnala Inserita: 31 dicembre 2015 (modificato) Ecco lo schema....in fase di collaudo Modificato: 31 dicembre 2015 da dott.cicala
dott.cicala Inserita: 31 dicembre 2015 Autore Segnala Inserita: 31 dicembre 2015 Sequenza 1234567890 generata con durata tono 100ms e incremento 200mstutti i tono vengono riconosciuti
Messaggi consigliati
Crea un account o accedi per commentare
Devi essere un utente per poter lasciare un commento
Crea un account
Registrati per un nuovo account nella nostra comunità. è facile!
Registra un nuovo accountAccedi
Hai già un account? Accedi qui.
Accedi ora