Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

PWM doubts with PIC16f877a

Status
Not open for further replies.

PA3040

Advanced Member level 3
Advanced Member level 3
Joined
Aug 1, 2011
Messages
883
Helped
43
Reputation
88
Reaction score
43
Trophy points
1,308
Visit site
Activity points
6,936
Dear All,

As we all aware in the PWM operation is like bellow.
After configure all register for PWM

1 First load value for period register ( PR2 = 20)

2 Then Load duty cycle register (CCPR1L = 5)

3 Now Timer2 ON ( bsf T2CON,TMR2ON)

Then
TMR2 compare with PR2 register, when match occurred (TMR2 = PR2) OR TMR2 = 20 as per above )

Then
TMR2 compare with CCPR1H register , when match occurred (TMR2 = CCR1H) OR TMR2 = 5 as per above)

so my program is working properly

Only doubts I observed is when I load register to the watch window in the MPLAB TMR2 register always reset when match occurred to the PR2 register to the TMR2 register, even TMR2 register is matching with CCPR1H register

Please advice

PWM.JPG
 

PWM output is high at the beginning of the cycle. TMR2 starts counting. When TMR2 = CCPR1L, PWM output goes low. TMR2 continues counting. When TMR2 = PR2, TMR2 is reset and PWM output goes high and stays high until TMR2 = CCPR1L when the output goes low and then TMR2 resets when TMR2 = PR2 and so on.

So, for duty cycle, CCPR1L is used. TMR2 is compared against CCPR1L. TMR2 is not cleared or reset when TMR2 = CCPR1L.
For period, PR2 is used. TMR2 is compared against PR2. When there is a match between TMR2 and PR2, TMR2 is reset.

CCPR1H doesn't come into play here.

That's how it works.

Hope this helps.
Tahmid.
 
Dear Tahmid,
Thanks for the clear reply and I got the point

Dear Tahmid please see the attached clip

Can we drive the LED's like in the bellow clip, using PWM module
If can, can I have an idea

https://www.youtube.com/watch?v=qIjCLx1wwPA

Please advice
Thanks in advance
 
Last edited:

While it is certainly possible to utilize PWM to accomplish the effect of an LED chaser, the PIC16F877A does not enough PWM channels without either implementing some method of multiplexing or generating the PWM via software rather than the CCP modules.

A much simpler option is to utilize the logical left and right shift operators (<<, >>) to accomplish the task, by simply walking a set bit back and forth.

Persistence of Vision (POV) and the ambient light of the active LED will give an illusion the surrounding LEDs are lit at a dimmer level.

If you examine the following code from an Arduino LED chaser, which can be easily ported to the PIC, you see how the use of a directional flag combine with a couple of if statements can accomplish the desired results.

Increasing the delay routine will decrease the scan rate, decreasing the delay with increase the scan rate.

Code:
void loop(){
  // Turn ON one LED
  PORTD=LEDOn;   

  // Change the direction when reach 0 or 7
  if (LEDDirection == 0) {
    LEDOn=LEDOn << 1;      // Shift Left 1 Bit
    if (LEDOn >= 0x80) LEDDirection=1;        
  } else {
    LEDOn=LEDOn >> 1;      // Shift Right 1 Bit
    if (LEDOn <= 0x01) LEDDirection=0;        
  }  

  delay(LEDDelay);                   
          
}

**broken link removed**

The following PIC project accomplishes a similar unidirectional version of an LED chaser, with the addition of a direction flag or other techniques the algorithm can be converted to bidirectional.

Code:
void main()
{
  CMCON = 0x07; // To turn off comparators
  ADCON1 = 0x06; // To turn off adc
  TRISB = 0x00; // Sets all pins in PORTB as output
  PORTB = 1; // Set RB0 to high 00000001
  do // To set infinite loop
  {
    Delay_ms(300); // 300 mili seconds delay
    PORTB = PORTB<<1; //Shifting right by one bit
    if(PORTB >= 0b10000000) //To reset to 00000001
    {                          //when the count becomes 10000000
       Delay_ms(350); // 350 mili seconds delay
       PORTB = 1;
    }
  }while(1); // To set infinite loop
}




BigDog
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top