pia-468x60

pia-728x90

Monday, November 2, 2020

PIC16F887 Interrupt-On-Change in MikroC

Introduction

Port B of PIC16F887 is individually able to trigger interrupt signal to the controller. It's called INTERRUPT-ON-CHANGE. It also cover the external interrupt on RB0. However this interrupt source comes with most of new version of PIC microcontroller.

There are some registers relate to this interrupt source, IOCB, and INTCON.

Interrupt Control Register - INTCON

This register contains control and flag bit of interrupt-on-change.

PIC16F887 External Interrupt Example With 7-Segments Display In MikroC
Interrupt Control Register (INTCON)

Set the Global Interrupt Enable bit (GIE) to turn on interrupt for PIC16F887 microcontroller. Bit 3 is called PORTB Change Interrupt Enable bit (RBIE). This bit must be set to turn on the PortB-Interrupt-On-Change. RBIF is PORTB Change Interrupt Flag bit. In the ISR the program must test this bit for its interrupt request.

Interrupt-On-Change PORTB Register - IOCB

This 8-bit wide special function register configures the present of PortB-Interrupt-On-Change.

PIC16F887 Interrupt-On-Change in MikroC
Interrupt-On-Change PortB Register - IOCB
It corresponds to all 8 pins of PortB. It can be individually turn on and off up to the user.

IOCB of PIC16F887 Programming in MikroC

Introduction

There are some more register to make this programming work well. Port B weak pull up resistors must be turned on to save component counts. This job will be done with the OPTION_REGand the WBPU register.

Its internal oscillator with a frequency of 8MHz could fit this simple task. Program will need to configure the OSCCON register to select its 8MHz internal oscillator.



Unlike external interrupt, this interrupt source doesn't have edge selection control bit. Its interrupt flag RBIF is set at the instance of port reading mismatch the previous port value.

Hardware

I made its schematic in Proteus due to its ease of design.

PIC16F887 Interrupt-On-Change in MikroC
Schematic Diagram

SW1 connects to RB7 creates interrupt when it's pressed (shorted to ground). D1 toggles each time the interrupt occurs.

Programming in MikroC

The controller is configured to clock from its internal 8MHz oscillator. Port B input doesn't need external pull up resistor since it's internally connected to its weak pull up resistor by software.

Interrupt-On-Change occurs when the input logic to RB7 change from high to low.

  1. void interrupt() {
  2. if(INTCON.RBIF)
  3. if(PORTB.RB7==0) // check if RB7 is shorted to GND
  4. PORTB.RB0^=1;
  5. INTCON.RBIF=0;
  6. }
  7.  
  8. void main() {
  9. PORTB=0x00; // CLEAR PORTB
  10. TRISB=0x80; // RB7 IS INPUT
  11. ANSELH=0x00; // DISABLE ALL ANALOG FUNCTION
  12. OPTION_REG.F7=0; // ENABLE WPUB
  13. WPUB=0x80; // TURN ON WPUB FOR RB7
  14. OSCCON|=0x70; // SELECT INTRCIO 8MHz
  15. INTCON.GIE=1; // TURN ON GLOBAL INTERRUPT
  16. INTCON.RBIE=1; // TURN ON IOCB
  17. IOCB=0x80; // RB7 IS USE TO CREATE INTERRUPT
  18. INTCON.RBIF=0; // CLEAR INTERRUPT FLAG
  19. while(1); // STAY HERE
  20. }

Both MikroC and Proteus simulation were recorded in this video.


 

Monday, October 12, 2020

PIC16F887 External Interrupt Example With 7-Segments Display In MikroC

An Overview Of External Interrupt

An interrupt of the MCU is an event that triggers a notification to the CPU. The CPU itself could responds to that events, or could ignore. Responding to the interrupt takes a very short time to handle and come back to the program main loop. Interrupt is very fast. It make the embedded controller program more responsive and more effective.

In the mid-range PIC microcontroller, an interrupt could create by an external events or by an internal peripheral operation. The external event may cause by any logic change to any digital input pin. A communication to the external device also create an interrupt, but we don't want to talk more about this here.

PIC16F887 External Interrupt Example With 7-Segments Display In MikroC
Programming Sample Of External Interrupt

For PIC16F887 the interrupt creates by the digital input output pin has two categories - an external interrupt creates by RB0-INT input pin, and the interrupt on change creates by any pin on PORTB input.

In this post we gonna talk about the external interrupt creates by INT pin. There are two choices of logic changes that could trigger an interrupt on this pin - on the falling edge and on the rising edge. The OPTION_REG register configures each choices.



The OPTION_REG register

Bit 6 (INTEDG) selects between the rising and the falling edge of interrupt creates by the pin INT. Programming the external interrupt we need to configure the following stuffs:

  1. Set RB0-INT pin as a digital input
  2. Optionally turn on its individual weak pull up resistor.
  3. Turn on the external interrupt enable (INTE) bit and the global interrupt enable (GIE) bit in the interrupt control register (INTCON).
  4. Select between that two interrupt edge
  5. Clear the external interrupt flag (INTF) of the INTCON register.
  6. In MikroC, write the Interrupt Service Routine (ISR) to handle the job. Within this routine the programmer must firstly test the INTF to get the external interrupt event, then writing a block of codes to for this event. Within the final line of this block, the INTF bit must be clear by software.


The Interrupt Control Register (INTCON) has many configurations and flag as lists below.

PIC16F887 External Interrupt Example With 7-Segments Display In MikroC
Interrupt Control Register (INTCON)

External Interrupt Programming In MikroC

This example may become difficult to some novice microcontroller programmer. To get a simple introductory programming example about using the external interrupt in MikroC, see this post.

Here, the MCU display the counting data on a multiplexed 7-segments display. The counting has a 99 maximum decimal values. After reaching the maximum value it rolls back to 0.

The counting increment creates by the falling edge of the INT pin. As mentioned earlier, using the interrupt the main program keeps executing its main task. The interrupt event occurs in a very short time and the main program doesn't need to poll for this event.

MikroC Program

  1. #define SW PORTB.RB0
  2. #define RATE 10
  3.  
  4. char CNT=0;
  5.  
  6. void interrupt() {
  7. if(INTCON.INTF)
  8. CNT++;
  9. INTCON.INTF=0;
  10. }
  11.  
  12. void SSD(char TEN,char ONE) {
  13. char LED[10]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};
  14. // ROUTINE FOR SEVEN SEGMENTS
  15. PORTA=LED[TEN];
  16. PORTB=0x80;
  17. delay_ms(RATE);
  18. PORTB=0x00;
  19.  
  20. PORTA=LED[ONE];
  21. PORTB=0x40;
  22. delay_ms(RATE);
  23. PORTB=0x00;
  24.  
  25. }
  26. void main() {
  27. char CNT1=0;
  28. PORTA=0x00; // CLEAR PORTBA
  29. PORTB=0x00; // CLEAR PORTB
  30. TRISA=0x00; // SET PORTA AS OUTPUT
  31. TRISB=0x01; // SET RB0 AS INPUT
  32. ANSELH=0x00; // DISABLE ANALOG FUNCTION ON PORTB
  33. OSCCON|=0x70; // SELECT 8MHz INTERNAL OSCILLATOR
  34. OPTION_REG.NOT_RBPU=0; // Enable Global WPUB
  35. OPTION_REG.INTEDG=0; // Interrupt from High TO Low
  36. WPUB=0x01; // Enable WPUB for RB0
  37. INTCON.GIE=1; // Enable Global Interrupt
  38. INTCON.INTE=1; // Enable External Interrupt
  39. INTCON.INTF=0; // Clear External Interrupt Flag
  40.  
  41. // MAIN ACTIVITY
  42. while(1) {
  43. if(CNT==10) { CNT=0; CNT1++; }
  44. if (CNT1==10) CNT1=0;
  45. SSD(CNT1,CNT);
  46. }
  47. }



Thursday, October 8, 2020

Accessing the internal 8 MHz oscillator of PIC16F887 in MikroC

Overview Of The Internal Oscillator of PIC16F887

One of the extended features of PIC16F887 over the previous PIC16F887A is the internal calibrated RC oscillator. Using this internal oscillator, the clocking module inside works statically, mostly prevented from the noisy environment creates by the external RF signal. 

Furthermore, there're many options with internal clock. The external clock pins - RA6 and RA7 could be selected as a digital input output pin when the MCU clock is configured as internal oscillator with digital I/O.

The internal oscillator is divided into two blocks - LFINTOSC and HFINTOSC. The LFINTOSC in a lower frequency clock below 31 kHz. The HFINTOSC is a higher frequency ranges from 125 kHz to 8 MHz.

The internal clock setup must be done in the configuration bits and the OSCCON register. Another register OSCTUNE give a steady tuning to any frequency while the program is running, without any interruption.

PIC MCU clock source block diagram

In MikroC the configuration of the MCU must be done in the MCU property window. In this IDE press Shift + Ctrl + E to get this window.


The OSCTUNE (Oscillator Tuning Register) 

The OSCCON (Oscillator Controller Register)


Programming in MikroC

In this example, I use the internal oscillator to clock the CPU up to 8 MHz. PORTA displays a shifting data repeatedly.

Accessing the internal 8 MHz oscillator of PIC16F887 in MikroC
Schematic Diagram

The C source code in MikroC setup the internal oscillator one-by-on.

  1. void main() {
  2. char LED;
  3. PORTA=0x00; // CLEAR ALL PORTA
  4. TRISA=0x00; // ALL PORTA AS OUTPUT
  5. OSCCON.IRCF0=1; // Set IRCF=0b111
  6. OSCCON.IRCF1=1; // to select 8MHz
  7. OSCCON.IRCF2=1;
  8. while(1)
  9. {
  10. LED=0x01;
  11. while(LED!=0x00) {
  12. PORTA=LED;
  13. delay_ms(100);
  14. LED<<=1;
  15. }
  16. }
  17. }

Labels