Sari la conținut
ELFORUM - Forumul electronistilor

pwm pic12f683


bogdan546

Postări Recomandate

Am modificat acest program de aici http://saeedsolutions.blogspot.com/2012/07/pic12f675-pwm-code-proteus-simulation.html   sa se compileze cu mikroc, se compileaza fara eroare, dar nu functioneza

#define PWM_Pin    GP0_bit

     void interrupt_ISR(void);
     void InitPWM(void);
     extern unsigned char PWM;
     unsigned char PWM = 0;



     void InitPWM(void)
{
        // Use timer0 for generatung PWM
        OPTION_REG &= 0xC0;     // Intialize timer0

          INTCON |= 0x90;           // Enable Timer0 interrupt
                                   // Enable global interrupts
}
        void interrupt_ISR()
{
        if(T0IF)  //If Timer0 Interrupt
        {
                if(PWM_Pin)        // if PWM_Pin is high
                {
                        PWM_Pin = 0;
                        TMR0 = PWM;
                }
                else             // if PWM_Pin is low
                {
                        PWM_Pin = 1;
                        TMR0 = 255 - PWM;
                }
        }
}
      void main()
{
        ANSEL  = 0x00;       // Set ports as digital I/O, not analog input
        ADCON0 = 0x00;       // Shut off the A/D Converter
        CMCON0  = 0x07;      // Shut off the Comparator
        VRCON  = 0x00;       // Shut off the Voltage Reference
        TRISIO = 0x08;       // GP3 input, rest all output
        GPIO   = 0x00;       // Make all pins 0

        InitPWM();                         // Initialize PWM

        // PWM=0 means 0% duty cycle and
        // PWM=255 means 100% duty cycle
        PWM = 127;                         // 50% duty cycle

        while(1)
        {
        }
}

Va rog spuneti-mi care este greseala

Editat de bogdan546
Link spre comentariu
  • Răspunsuri 14
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • bogdan546

    8

  • Elison

    3

  • costi002

    3

  • mars01

    1

Top autori în acest subiect

Eu niciodata nu am reusit sa citesc starea unui pin ce este declarat ca iesire cu mikroc. In cazul tau, as declara o variabila si as face-o egala cu zero/unu atunci cand in soft se schimba starea lui pwm_pin, iar in intrerupere as testa acea variabila.

Link spre comentariu

Pai asta incerc sa spun, ca posibil ca citirea acelui pin nu returneaza valoarea corecta.

O alta problema ar putea fi ca nu ai configurat in mikroc clock-ul corect pt pic, ca nu ai dezactivat watch dog-ul, etc.

Editat de costi002
Link spre comentariu

Nu ar trebui sa nu conteze valoarea lui deoarece se testeaza ambele valori ? Eu asa vad functionarea : se citeste starea pinului 7(gp0) si daca este 0 se face 1 timp de 50%(127) si daca este 1 se face 0( 255 - 127 ) .

Editat de bogdan546
Link spre comentariu

In datasheet scrie asa :
      T0IF: TMR0 Overflow Interrupt Flag bit
               1 = TMR0 register has overflowed (must be cleared in software)
               0 = TMR0 register did not overflow 
In cazul tau TOIF este unu tot timpul.

Link spre comentariu

Da, aveti dreptate . La compilare daca este scris asa da eroare " Undeclared identifier 'T0IF_' in expression MyProject.c" daca il scriu T0IF_bit = 0 ; nu da eroare, dar nu functioneaza

Editat de bogdan546
Link spre comentariu
/*
*  Project:    PWM
*  uC:         PIC12F683
*  Osc:        Internal OSC = 4MHz
*  Datasheet:  http://ww1.microchip.com/downloads/en/DeviceDoc/41211D_.pdf
*/

#define PWM_Pin   GP0_bit
#define ON        1
#define OFF       0

void InitPWM(void);

unsigned char PWM_value = 0;
unsigned char shadow_pwm_pin = 0;


void InitPWM(void){
   // Use timer0 for generatung PWM
   // Intialize timer0
   // OPTION_REG
   T0CS_bit = 0;  // TMR0 clock source is internal OSC = 4MHz
   PSA_bit = 0;   // prescaler assigned to TMR0
   // prescaler set to 1:2, TMR0 overflow frequency 1.968Khz (period tick = 2us)
   PS2_bit = 0;
   PS1_bit = 0;
   PS0_bit = 0;
   
   
   // Enable Timer0 interrupt
   // Enable global interrupts
   // INTCON
   T0IE_bit = 1;
   GIE_bit = 1;
}

void interrupt(){
   //If Timer0 Interrupt Flag is set and Timer0 is enabled
   if(T0IF_bit && T0IE_bit){
      T0IF_bit = 0;
      // if PWM_Pin is high
      if(shadow_pwm_pin){
         shadow_pwm_pin = OFF;
         TMR0 = PWM_value;
      }
     // if PWM_Pin is low
      else{
        shadow_pwm_pin = ON;
        TMR0 = 255 - PWM_value;
      }
      PWM_Pin = shadow_pwm_pin;
   }
}

void main(){
   ANSEL  = 0x00;       // Set ports as digital I/O, not analog input
   ADCON0 = 0x00;       // Shut off the A/D Converter
   CMCON0 = 0x07;       // Shut off the Comparator
   VRCON  = 0x00;       // Shut off the Voltage Reference
   TRISIO = 0x08;       // GP3 input, rest all output
   GPIO   = 0x00;       // Make all pins 0

   InitPWM();           // Initialize PWM

   // PWM_value = 0 means 0% duty cycle and
   // PWM_value = 255 means 100% duty cycle
   PWM_value = 127;     // 50% duty cycle

   while(1);
}

pwm.jpg

 

 

 

 

PWM.zip

Editat de mars01
Link spre comentariu

Am incercat sa vad de ce nu functioneaza programul modificat de mine si functioneaza dupa ce am modificat enable-ul la timer 0 si la intreruperi .Acum o sa incerc sa vad daca reusesc cu ajutorul unui potentiometru pus pe adc sa modific factorul de umplere.

#define PWM_Pin   GP0_bit

     void interrupt(void);
     void InitPWM(void);
        extern unsigned char PWM;
      unsigned char PWM = 0;
        void main()
{
        ANSEL  = 0x00;       // Set ports as digital I/O, not analog input
        ADCON0 = 0x00;                 // Shut off the A/D Converter
        CMCON0  = 0x07;                 // Shut off the Comparator
        VRCON  = 0x00;             // Shut off the Voltage Reference
        TRISIO = 0x08;       // GP3 input, rest all output
        GPIO   = 0x00;       // Make all pins 0

        InitPWM();                         // Initialize PWM

        // PWM=0 means 0% duty cycle and
        // PWM=255 means 100% duty cycle
        PWM = 127;                         // 50% duty cycle

        while(1)
        {
        }
}


     void InitPWM(void)
{
        // Use timer0 for generatung PWM
        OPTION_REG &= 0xC0;        // Intialize timer0
         T0IE_bit = 1;            // Enable Timer0 interrupt
         GIE_bit  = 1;           // Enable global interrupts
}
        void interrupt()
{
        if(T0IF)  //If Timer0 Interrupt
        {
                if(PWM_Pin)        // if PWM_Pin is high
                {
                       PWM_Pin = 0;
                        TMR0 = PWM;
                }
                else             // if PWM_Pin is low
                {
                       PWM_Pin = 1;
                        TMR0 = 255 - PWM;
                }
        }     INTCON.TMR0IF = 0;
}

karac3.jpg

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