PIC16F877A Microcontroller Datasheet - I/O and Timer Interrupts

Thread Starter

Gajyamadake

Joined Oct 9, 2019
138
I need help to configure port and pins of PIC16F877A

Switch 1 connected to Port B0 Pin of PIC16F877A
Switch 2 connected to Port B2 Pin of PIC16F877A
Switch 3 connected to Port B4 Pin of PIC16F877A

LED 1 connected to Port B1 Pin of PIC16F877A
LED 2 connected to Port B3 Pin of PIC16F877A
LED 3 connected to Port B5 Pin of PIC16F877A

Can we configure as following

C:
#include <xc.h>

int main()
{
  TRISB = 0b00010101;

  TRISD = 0b00000000;

  while(1)
  {

  }
  return 0;
}
Please let me know if missing something
 

jpanhalt

Joined Jan 18, 2008
8,081
The binary for TRISB seems to be set correctly for those assignments. There may be other settings needed too. Is that all of your settings? Remember, analog settings are default and need to be disabled for digital inputs.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
138
The binary for TRISB seems to be set correctly for those assignments. There may be other settings needed too. Is that all of your settings? Remember, analog settings are default and need to be disabled for digital inputs.
No I haven't gone into deep. I mainly focused to configure pins as input/output
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
138
Datasheet page 55 Timer0
1573311877649.png

Timer0 has a register TMR0 Register, which is 8 bits of size.
INTCON Register
Bit 2->TMR0IF /the TMR0 interrupt is generated when the TMR0 register overflows from FFh to 00h
OPTION_REG register

I do not understand how does timer0 work there is no sufficient details in datasheet
 

AlbertHall

Joined Jun 4, 2014
8,514
Read the TMR0 section several times until more sinks in.
Then ask specific questions about whatever you still do not understand.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
138
Read the TMR0 section several times until more sinks in.
Then ask specific questions about whatever you still do not understand.
There is no details after page 55 for timer 0. timer 1 topics start at page 57. There no details for INTCON register
counter is 8 bit size so it would run from 0 to 255. I do not understand where to load counter value
 

jpanhalt

Joined Jan 18, 2008
8,081
If you are using Table 5-1 to understand TIMER0, that will not do by itself. There are so many things that table does not have, such as which bits can be written to and which are read only. As others have said, you need to read about TIMER0, and INTCON in the sections devoted to each of them. Finally, it seems you need to read about the interrupt structure. There are several enabling bits that need to be set to get an interrupt.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
138
As others have said, you need to read about TIMER0, and INTCON in the sections devoted to each of them. Finally, it seems you need to read about the interrupt structure. There are several enabling bits that need to be set to get an interrupt.
PIC16F877A timer0 has 8 bit timer register that can count 0 to 255 counts. for example if counter start from 0, value of timer will increase every time one by one when it reaches its maximum value 255, timer will overflow to 0 and timer will call to interrupt service. When interrupt enable do the task and disable the interrupt after that timer will start from 0

1573372310233.png
Please correct me If I missed something
 
Last edited:

jpanhalt

Joined Jan 18, 2008
8,081
1) Why are you setting PIE=1? Does that compile? There is no PIE per se, but there is PIE1 and PIE2.

1573383504400.png

Which one do you think has anything to do with TMR0?

2) I would always clear the interrupt flag (in this case TMR0IF) before enabling its interrupt. Setting TMR0 =0 does not do that, according to the datasheet.

3) Further down your flowchart you "enable interrupt." That was already done with GIE=1 and TMR0IE=1 above. If that is intended as part of your ISR, you may need to do more.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
138
1) Why are you setting PIE=1? Does that compile? There is no PIE per se, but there is PIE1 and PIE2.
Which one do you think has anything to do with TMR0?
2) I would always clear the interrupt flag (in this case TMR0IF) before enabling its interrupt. Setting TMR0 =0 does not do that, according to the datasheet.
3) Further down your flowchart you "enable interrupt." That was already done with GIE=1 and TMR0IE=1 above. If that is intended as part of your ISR, you may need to do more.
1) It was typing mistake PEIE : Peripheral Interrupt Enable bit

2) I have cleared TMR0IF see bottom of flow chart

I think we can set timer at any value for example TMR0 = 5 timer will start from 5 not from 0

3) Take look at this

1573386856516.png
 

jpanhalt

Joined Jan 18, 2008
8,081
While TMR0 is called a peripheral in Microchip documents, it is enabled differently than other peripheral interrupts and does not require any settings in PIE/PIEn registers.

Source=http://ww1.microchip.com/downloads/en/DeviceDoc/51702a.pdf , page 7
Next, each peripheral will have individual interrupt enable bits. These individual interrupt enable bits may be contained within a separate Peripheral Interrupt Register (PIRx). However, the Timer0 peripheral interrupt enable bit is contained within the INTCON register. The Timer0 Overflow Interrupt Flag bit (T0IF) is set, and remains set until cleared in software, when a Timer0 overflow has occurred. This bit needs to be cleared if further interrupts are required for this peripheral. The following recommended sequence should be used when configuring any interrupt and following any ISR:
1. Clear the interrupt flag (Timer0 Overflow Interrupt Flag).
2. Enable the individual peripheral interrupt (set the Timer0 Overflow Interrupt Enable bit).
3. Enable PIC mid-range MCU interrupt capability by setting the Global Interrupt Enable bit.
That is, TMR0 is enabled by setting INTCON,TMR0IE =1. Nothing more needs to be done to enable it, except setting GIE=1. From the same source given above:

1573388487203.png

And from the 16F877a dtatsheet:

1573388623414.png

I have highlighted the 3 relevant bits. NB: Note the sequence recommended by Microchip.
 

Thread Starter

Gajyamadake

Joined Oct 9, 2019
138
While TMR0 is called a peripheral in Microchip documents, it is enabled differently than other peripheral interrupts and does not require any settings in PIE/PIEn registers.

That is, TMR0 is enabled by setting INTCON,TMR0IE =1. Nothing more needs to be done to enable it, except setting GIE=1. From the same source given above:

And from the 16F877a dtatsheet:

View attachment 191027

I have highlighted the 3 relevant bits. NB: Note the sequence recommended by Microchip.
@jpanhalt
Take a look at this source
https://www.exploreembedded.com/wiki/PIC16f877a_Timer
https://circuitdigest.com/microcontroller-projects/pic-microcontroller-timer-tutorial

They Enable Peripheral Interrupt I don't understand why thy Enable Peripheral Interrupt ?

Now does it make any sense

1573390252683.png
 
Last edited:

jpanhalt

Joined Jan 18, 2008
8,081
@jpanhalt

They Enable Peripheral Interrupt I don't understand why thy Enable Peripheral Interrupt ?
I so not see that tutorial enabling "PIE" for TMR0. TMR0 is controlled by INTCON and OPTION_REG registers. Timer0 is a type of timer, just as Timer1 is a different type of timer. I do not know the history of PIC chips, but I suspect it was in the earliest and simplest chips, and its controls were integrated into INTCON. Later chips with more peripherals could not be accommodated in INTCON, so those peripheral interrupts are enabled by different registers.

Now does it make any sense
Let's do a thought experiment:
1) You are setting TMR0IF = 1
2) You enable TMR0 interrupt: TMR0IE = 1
3) You enable GIE = 1
What will happen at that point?
MCU will immediately go to the ISR
You need to flesh out your ISR, including what command is used for return (presumably RETFIE).
I suspect that your program may idle in "FOREVER" and have an interrupt every 256 clicks (Your forever does not preload TMR0 = 5. If you want a preload, you need to do it EVERY time there is an interrupt.)

Finally, you need to set appropriate bits in OPTION_REG. If your MCU operates at some MHz frequency, TMR0 will rollover quite quickly.
 

JohnInTX

Joined Jun 26, 2012
3,816
I so not see that tutorial enabling "PIE" for TMR0. TMR0 is controlled by INTCON and OPTION_REG registers. Timer0 is a type of timer, just as Timer1 is a different type of timer. I do not know the history of PIC chips, but I suspect it was in the earliest and simplest chips, and its controls were integrated into INTCON. Later chips with more peripherals could not be accommodated in INTCON, so those peripheral interrupts are enabled by different registers.
The 'tutorials' show PEIE=1 but as you say they are wrong. The interrupt controls for timer 0 are in INTCON. You're correct about the origins of the INTCON controls. The earliest interrupt capable PIC was the 16C84. It had the same TIMER 0 setup as the older 16C5x with the addition of the interrupt capability. INTCON had just enough space to accommodate the interrupt controls for the timer and the small number of other interrupt sources. When the chips got bigger with more peripherals, INTCON,6 was rededicated as PEIE as a master control for those but TIMER0 controls stayed in INTCON.

EDIT: TS posted while I was typing.
(Sorry to butt in)
 
Last edited:
Top