home | area personale         schemi | tutorial | robotica | pic micro | recensioni         forum | chat irc         faq | contatti         store | Ordina PCB
username
password
cerca

 
FORUM: Pic Micro
Tutto quanto riguarda questi microprocessori... progetti, suggerimenti, aiuti, discussioni...ecc


PWM 16F876 MikroBasic
     
Autore Messaggio opzioni
agric





postato il:
13.08.2019, alle ore 10:42
magari postare quanto hai fatto, anche se non funziona.
E un modo come un'altro per capire dove si sbaglia con l'aiuto di un comunità



meglio essere un granello di pepe che una cacca d'asino
piero55




una ogni 10 livelli


postato il:
13.08.2019, alle ore 14:59
non riesco ad inserire il listato.... mi da errore SQL.............e non parte..... e naturalmente perdo tutto il messaggio che ho scritto.....
MB54




una ogni 100 livelli


postato il:
13.08.2019, alle ore 15:20
piero55:
.... mi da errore SQL.............


Quasi sicuramente hai inserito delle virgolette doppie: non sono ammesse. Usa eventualmente due virgoletti semplici in successione

piero55




una ogni 10 livelli


postato il:
13.08.2019, alle ore 18:05
Ci riprovo... sostituite le doppie virgolette con due virgolette semplici...
File originale in C che utilizza il modulo di comparazione del PIC:

 #define _XTAL_FREQ 20000000                // set crystal oscillator to 20MHz.
#define TMR1PRESCALE 8                     // timer1 prescaler is 8.
#define OUT RC2                            // use the name OUT for RC2 pin.

#include <xc.h>

// BEGIN CONFIG
#pragma config FOSC = HS   // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF  // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON  // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF   // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF   // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF   // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF    // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG



// variables and constants declarations 
unsigned long CCPR = 0;                    // holds the value needed to be put in CCP's registers.
unsigned long current_period = 0;          // holds the period that timer1 will use.
const unsigned long total_period = 12500;  // 20ms for 50hz frequency.


// interrupt service routine
void interrupt tmr1isr () {
   if (CCP1IF == 1) {                           // if CCP compare interrupt flag is set
      
      
       if ((current_period > 0) && (current_period < total_period)){ // if duty is > 0% AND < 100% then:
       
           if (OUT == 1) {                           // if the output was 1 -> was 'on-time'.         
           OUT = 0;                                  // set output to 0 in order to achieve 'off-tim'.
           CCPR = total_period - current_period;     // make it time for 'off-tim', off-time = full time - on time.
           }
                 
      else {                                    // if the output was 0 -> was 'off-time'.
         OUT = 1;                               // set output to 1 in order to achieve 'on-time'         CCPR = current_period;                 // make it time for 'on-time'.
      }
       }
       else {
           if (current_period == total_period) { OUT = 1;}             // if duty = 100%, then output 1 all the time.
           if (current_period == 0)            {OUT = 0;}              // if duty = 0%, then output 0 all the time.
       }
       
   
      // now set the value of CCPR into CCP module's registers:
      
      CCPR1H = CCPR >> 8;                       // right-shift CCPR by 8 then load it into CCPR1H register (load higher byte).
      CCPR1L = CCPR;                            // put the lower byte of CCPR in CCPR1L register.
      CCP1IF = 0;                               // reset CCP1 interrupt flag.
   }
}


// main function:
void main() {
   

   TRISC = 0;                 // port c is output.
   PORTC = 0;                 // port c = 0.
   
   T1CON = 0b00110000;        // timer1 uses prescaler value of 8 and it is off.
   TMR1H = 0;                 // timer1 registers have 0 (clear).
   TMR1L = 0;

   CCP1CON = 0x0b;            // set CCP module to compare mode and trigger special event when interrupt happens.
   CCPR = 0;                  // load 0 in CCPR.
   CCP1IF = 0;                // clear CCP1 interrupt flag.
   CCP1IE = 1;                // enable CCP1 interrupt. 
   INTCON = 0xC0;             // enable global and peripheral interrupt. 
   T1CON = 0b00110001;        // start timer1 with the same settings like before.
   

   

   while (1) {                                          // infinite loop.
      
       
       // TEST CODE...
       
       current_period = total_period * 0.5;            // 50% duty cycle.
       __delay_ms(2000);                               // delay 2s.
       current_period = total_period * 0.1;            // 10% duty cycle.
       __delay_ms(2000);                               // delay 2s.
       current_period = total_period * 1;              // 100% duty cycle.
       __delay_ms(2000);                               // delay 2s.
       current_period = total_period * 0;              // 0% duty cycle.
       __delay_ms(2000);                               // delay 2s.
      }
   }
 



Ho convertito in basic la parte dell'interrupt:

 
'if CCP1IF_bit=1   then   ' pir1.2=1 then   ' CCP1IF_bit=1 then
'    if (current_period>0) and (current_period<total_period) then
'       if OUT=1 then
'         OUT=0
'         CCPR=total_period - current_period
'        else
'         OUT=1
'         CCPR=current_period
'       end if
'     else
'       if (current_period=total_period) then
'          OUT=1
'       end if
'       if current_period=0 then
'          OUT=0
'       end if
'    end if
'  CCPR1H=CCPR>>8
'  CCPR1L=CCPR
'  CCP1IF_bit=0   ' pir1.2=0
'end if 


Essendo molto nidificato (quello in C) non so se ho convertito bene... forse il problema è li.

Naturalmente ho inserito anche la parte di INIT:

  
 'T1CON=%00110001    '00110000
 'TMR1H=0
 'TMR1L=0
 'CCP1CON=%00001011   '0x0b
 'CCPR=0
 'pir1.2=0    'CCP1IF=0
 'pie1.2=1   'CCP1IE=1
 'INTCON=%00110001

  total_period=12500
  CCPR=0
  current_period=0 


e la parte MAIN in un ciclo while:

    
   current_period=total_period/2
   pausa_ms(2000)
   current_period=total_period/10
   pausa_ms(2000)
   current_period=total_period*1
   pausa_ms(2000)
   current_period=total_period*0
   pausa_ms(2000)



non va....
piero55




una ogni 10 livelli


postato il:
13.08.2019, alle ore 18:08
dimenticavo...
 
dim CCPR as WORD
dim current_period as WORD
dim total_period as word 


WORD per le unsigned long...
piero55




una ogni 10 livelli


postato il:
14.08.2019, alle ore 18:13
Risolto... bastava solo trovare più tempo per ragionarci su.....
Utilizzo il TIMER1 e basta.

 sub procedure interrupt
  if (TMR1IF_bit) then        'interrupt ogni 200uS
    TMR1IF_bit = 0
    TMR1H         = 0xFC      '64535
    TMR1L         = 0x17

    inc(timer)
    
    if timer<duty then
       OUT=1
      else
       OUT=0
    end if
    
    if timer=100 then
       timer=0
    end if

  end if
 


la parte main del programma utilizzata come test:

   while true

   leggi_adc_van0       'tensione 
   pausa_ms(50)
   leggi_adc_t          'legge temperatura
   pausa_ms(50)
   
   for aa=0 to 100          'incrementa
   duty=aa
   visualizza_duty
   leggi_adc_van0
   pausa_ms(50)
   leggi_adc_t
   pausa_ms(2000)
   next aa
   
   for aa=100 to 0 step -1   'decrementa
   duty=aa
   visualizza_duty
   leggi_adc_van0
   pausa_ms(50)
   leggi_adc_t
   pausa_ms(2000)
   next aa
   
  wend 


Grazie picmicro.....
picmicro675




una ogni 10 livelli


postato il:
15.08.2019, alle ore 16:20
Ma non ho fatto tempo a tirar fuori gli attrezzi


Anno nuovo, forum nuovo.
Mi sa che lascio.
piero55




una ogni 10 livelli


postato il:
16.08.2019, alle ore 10:39
E' solo questione di tempo libero..... trovare un po' di tempo che permetta di immergersi nel problema e trovare la soluzione..... Comunque, grazie ugualmente...
picmicro675




una ogni 10 livelli


postato il:
17.08.2019, alle ore 07:29
Curiosità.... perché ti serve un PWM così lento?


Anno nuovo, forum nuovo.
Mi sa che lascio.
piero55




una ogni 10 livelli


postato il:
17.08.2019, alle ore 19:19
Certamente.... stavo cercando di gestire la velocita' di alcune ventole da PC 12V.
Dopo vari tentativi che non producevano buoni risultati, mi sono messo a cercare qualche spunto. finalmente, qualcosa di interessante. http://www.grix.it/viewer.php?page=12369 aveva tutto quello che mi serviva, l'ho subito provato con un modulino cinese da 1€ generatore di frequenza con duty variabile(ottimo acquisto). Il problema era risolto ora dovevo trovare il sistema di accoppiare lo stadio a transistor del progetto recuperato, ad un pic. Problema successivo, il PWM a circa 50Hz: risolto anche questo.
segui questo thread con grixFC, per questa funzione devi aver installato il software grixFC

torna su
     

Come utente anonimo puoi leggere il contenuto di questo forum ma per aprire una discussione
o per partecipare ad una discussione esistente devi essere registrato ed accedere al sito




 







 
 
indietro | homepage | torna su copyright © 2004/2024 GRIX.IT - La community dell'elettronica Amatoriale