Author Topic: PIC16F877a: mental LED blink timing  (Read 1463 times)

0 Members and 1 Guest are viewing this topic.

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
PIC16F877a: mental LED blink timing
« on: August 24, 2020, 04:22:46 pm »
I have the very simplest circuit imaginable. A PIC16F877a with a 12MHz crystal and one LED connecting port RB0 via a 330Ohm resistor to ground.

I run the following programme:

Code: [Select]
#define _XTAL_FREQ 12000000

#include <xc.h>

// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = ON // 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

int main()
{
  TRISB0 = 0; //RB0 as Output PIN
  while(1)
  {
    RB0 = 1;  // LED ON
    __delay_ms(500); // 1 Second Delay
    RB0 = 0;  // LED OFF
    __delay_ms(500); // 1 Second Delay
  }
  return 0;
}
and get the LED flash as per trace "500_500" attached. It looked to me that each alternate "on" was longer than the one before. So, I change the timings to:

500 on, 1000 off

and got trace "500_1000" attached. Though the "off" time has roughly doubled, as expected, there is now a completely mental pattern!  |O

Then, for good measure, I made it:

2000 on, 500 off

and got trace "2000_500". I would have expected the "on" time to quadruple (it did) and the "off" time to be the same. However, the "off" time is less than half what I expected.

What on earth is happening? I realise that these delay times are not super accurate and probably not hugely consistent but this is outrageous!

Could you please point me in the right direction understanding.

Cheers.

You can release yourself but the only way to go is down!
RJD
 

Offline NorthGuy

  • Super Contributor
  • ***
  • Posts: 3146
  • Country: ca
Re: PIC16F877a: mental LED blink timing
« Reply #1 on: August 24, 2020, 04:43:46 pm »
Disable watchdog timer. Or it will reset your PIC periodically and your pattern will restart every time it resets.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: PIC16F877a: mental LED blink timing
« Reply #2 on: August 24, 2020, 04:56:10 pm »
Congratulations, Your watchdog timer is running 7% faster than nominal, though it is within spec. (see datasheet Table 17-5, param. 31 & Fig. 18-15).  Your lab *may* be a bit cooler than 25 deg C, though I am making too much soup from not enough data.  :popcorn:  Try warming and cooling the chip, and you should see the period in trace 2000_500 vary.

Code: [Select]
#pragma config WDTE = ON // Watchdog Timer Enable bit (WDT enabled)If you don't want a wachdog reset, either don't enable it,  |O or service it regularly with CLRWDT(); before it times out!  :horse:
N.B. its period is determined by a crappy internal RC oscillator (see specs in datasheet I noted above) that is divided down by a prescaler shared with timer 0.  As you haven't configured Timer 0, the power-on defaults for the OPTION register apply, and the prescaler is assigned to the WDT and the WDT rate is 1:128 of the raw WDT oscillator period.
« Last Edit: August 24, 2020, 04:58:15 pm by Ian.M »
 
The following users thanked this post: PerranOak

Offline Wilksey

  • Super Contributor
  • ***
  • Posts: 1329
Re: PIC16F877a: mental LED blink timing
« Reply #3 on: August 24, 2020, 05:59:42 pm »
That watchdog timer is a real bitch, don't forget to kick the pooch!
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: PIC16F877a: mental LED blink timing
« Reply #4 on: August 24, 2020, 07:28:59 pm »
I am such a numpty! I could not for the life of me think what was wrong with such a simple programme!  :-[

Thank you all very much.

I feel like a Mega-noob.

You can release yourself but the only way to go is down!
RJD
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: PIC16F877a: mental LED blink timing
« Reply #5 on: August 24, 2020, 08:07:04 pm »
BTDTGTTS
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: PIC16F877a: mental LED blink timing
« Reply #6 on: August 24, 2020, 09:08:09 pm »
I’m gonna get that on a t-shirt.  ;)
You can release yourself but the only way to go is down!
RJD
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: PIC16F877a: mental LED blink timing
« Reply #7 on: August 25, 2020, 10:08:39 am »
I decided to investigate the watchdog timer problem.

I have fallen at the first hurdle!

I've diligently followed a C course (having been advised by many to use C not asembly) and so I get that. However, it wasn't specific to microcontrollers and didn't say how registers are addressed.

In assembly this is easy but I can't find out how to do it in C. I looked in the XC8 manual but couldn't even see what section to use! All I want to do is check the value of the TO bit in the STATUS register.

Where do I look to find the correct for for this and other registers please?

You can release yourself but the only way to go is down!
RJD
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: PIC16F877a: mental LED blink timing
« Reply #8 on: August 25, 2020, 11:13:55 am »
I'm betting that will be something like STATUSbits.TO and to confirm that you'll have to dig in the device specific header "pic16f877a.h" for your PIC.   I've just looked and the datasheet has the bit as /TO ('overbar capital t capital o'), so the header declares it as nTO and the complete bit reference is STATUSbits.nTO.

Other bits and bitfields that may prove useful to you are:
OPTION_REGbits.PSA - the prescaler assignment bit
OPTION_REGbits.PS - the group of three prescaler selection bits PS2:PS0

HTH
Ian.
 

Offline PerranOakTopic starter

  • Frequent Contributor
  • **
  • Posts: 548
  • Country: gb
Re: PIC16F877a: mental LED blink timing
« Reply #9 on: August 25, 2020, 04:53:10 pm »
Brilliant, cheers. It worked a treat.
You can release yourself but the only way to go is down!
RJD
 

Offline Wilksey

  • Super Contributor
  • ***
  • Posts: 1329
Re: PIC16F877a: mental LED blink timing
« Reply #10 on: August 26, 2020, 05:43:58 pm »
IIRC you can use XC8's ClrWdt() command to clear the WDT, I usually stick it in the while loop.
It is in the XC8 manual somewhere.
 

Online Ian.M

  • Super Contributor
  • ***
  • Posts: 12860
Re: PIC16F877a: mental LED blink timing
« Reply #11 on: August 26, 2020, 06:24:37 pm »
IIRC you can use XC8's ClrWdt() command to clear the WDT, I usually stick it in the while loop.
It is in the XC8 manual somewhere.
Its C so identifier case matters.  |O If you don't 'recall correctly' and cant be arsed to check the manual before posting, at least review the whole topic,
... or service it regularly with CLRWDT(); before it times out!  :horse:
as I posted that, correctly capitalised (and checked against the user guide) back in reply #2!
 

Offline Wilksey

  • Super Contributor
  • ***
  • Posts: 1329
Re: PIC16F877a: mental LED blink timing
« Reply #12 on: August 27, 2020, 08:30:28 am »
IIRC you can use XC8's ClrWdt() command to clear the WDT, I usually stick it in the while loop.
It is in the XC8 manual somewhere.
Its C so identifier case matters.  |O If you don't 'recall correctly' and cant be arsed to check the manual before posting, at least review the whole topic,
... or service it regularly with CLRWDT(); before it times out!  :horse:
as I posted that, correctly capitalised (and checked against the user guide) back in reply #2!
:-DD Christ, who pissed on your Christmas dinner, calm down sunshine! CLRWDT() for the anal retentives.
« Last Edit: August 27, 2020, 08:44:56 am by Wilksey »
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf