Hello,
Thank you very much for your answer. I'm sorry I did not reply to you earlier I was out of town.
I have read what you said and now my questions have cleared. I have understood this module.
I wrote a piece of code in which I'm doing the following:
- I assigned value of MAXNT to 240(that is the number of pulses per revolution for my encoder - I'm simulating it in proteus)
- I configured the QEI module in x4 mode and every time POSCNT reaches MAXCNT an interrupt is generated and I'm incrementing the value of a counter(which is the number of rotations)
- I configured TMR0 to give an overflow at every second. In this ISR I'm reading the value of counter in a variable speed(and so I get RPS) and then clear the counter to get a new value.
- The priority for QEI module is low and priority for TMR0 is high.
I cannot get the Timer0 to interrupt at 1 second. I have calculated everything like this.
The calculations for the TMR0 were like this:
- Internall OSC is 4Mhz. So my Fcy = 4Mhz/1 = 1Mhz. Tcy = 1us.
- Prescaler period = 16*1us = 16us.
- Overflow period = 16us * 2^16 =~ 1 sec(tmr0 was configured as 16bit timer)
However I get overflows very frequent not at 1 second as I should(or at least I think I should) get.
Code:
/*
* File: main.c
* Author: Paul
*
* Created on April 17, 2017, 12:39 PM
*/
#include "header.h"
#include <stdio.h>
#include <stdlib.h>
#include <delays.h>
#include <xlcd.h>
void init_XLCD(void); //Initialize LCD display
void DelayFor18TCY( void ); //18 cycles delay
void DelayPORXLCD (void); // Delay of 15ms
void DelayXLCD (void); // Delay of 5ms
void configureQEI();
void configureIntrs();
void configureTMR0();
long long int speed;
long long int counter = 0;
void main(void)
{
OSCCON = 0x6F; // 4Mhz internal oscillator
ANSEL0 = 0x00; // Analog input disabled for EA and QEB. They are digital
TRISAbits.TRISA0 = 0;
configureQEI();
configureIntrs();
configureTMR0();
while(1)
{
}
}
void init_XLCD(void) //Initialize LCD display
{
OpenXLCD(FOUR_BIT&LINES_5X7); //configure LCD in 4-bit Data Interface mode
//and 5x7 characters, multiple line display
while(BusyXLCD()); //Check if the LCD controller is not busy
//before writing some commands?
WriteCmdXLCD(0x06); // move cursor right, don?t shift display
WriteCmdXLCD(0x0C); //turn display on without cursor
putrsXLCD("LCD"); //Display "Hello World"
SetDDRamAddr(0x40); //shift cursor to beginning of second line
putrsXLCD("Initialisation"); //Display "LCD display"
for(int i=0; i<50; i++) __delay_ms(5);
WriteCmdXLCD(0x01); // clear screen
}
void DelayFor18TCY( void ) //18 cycles delay
{
//Delay10TCYx(20);
Nop( ); Nop( ); Nop( ); Nop( ); // 18 cycle delay
Nop( ); Nop( ); Nop( ); Nop( );
Nop( ); Nop( ); Nop( ); Nop( );
Nop( ); Nop( );
return;
}
void DelayPORXLCD (void) // Delay of 15ms
{
Delay1KTCYx(30);
}
void DelayXLCD (void) // Delay of 5ms
{
Delay1KTCYx(10);
}
void configureQEI()
{
QEICONbits.QEIM2 = 1; // QEI enabled in 4x Update mode; position counter
QEICONbits.QEIM1 = 1; // is reset on
QEICONbits.QEIM0 = 0; // period match(POSCNT = MAXCNT)
MAXCNTL = 240; // load value maxcount(number of pulses per revolution)
}
void configureIntrs()
{
INTCONbits.GIE = 1; // enable all interrupts
INTCONbits.PEIE = 1; // enable pheripheral interrupts
INTCONbits.TMR0IE = 1; // enable TMR0 overflow interrupt
INTCON2bits.TMR0IP = 1; // TMR0 overflow priority set to high
RCONbits.IPEN = 1; // enable priority lvls on interrupts
PIE3bits.IC2QEIE = 1; // enable QEI interrupts
}
void configureTMR0()
{
T0CONbits.T016BIT = 1; // Timer0 is set as 16 bit counter
T0CONbits.T0CS = 0; // Timer0 clock source is FOSC/4
T0CONbits.PSA = 0; // Timer0 prescaler active
T0CONbits.T0PS2 = 0; // prescale value
T0CONbits.T0PS2 = 0; // set to:
T0CONbits.T0PS2 = 1; // 1:16
T0CONbits.TMR0ON = 1; // enable Timer0
}
void interrupt ISR_TMR0()
{
if(TMR0IE && TMR0IF)
{
LATAbits.LATA0 ^= 1;
}
TMR0IF = 0;
}
And the header.h
Code:
// PIC18F2431 Configuration Bit Settings
// 'C' source line config statements
// CONFIG1H
#pragma config OSC = IRCIO // Oscillator Selection bits (Internal oscillator block, port function on RA6 and port function on RA7)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = ON // Internal External Oscillator Switchover bit (Internal External Switchover mode enabled)
// CONFIG2L
#pragma config PWRTEN = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF // Brown-out Reset Enable bits (Brown-out Reset disabled)
// BORV = No Setting
// CONFIG2H
#pragma config WDTEN = OFF // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDPS = 32768 // Watchdog Timer Postscale Select bits (1:32768)
#pragma config WINEN = OFF // Watchdog Timer Window Enable bit (WDT window disabled)
// CONFIG3L
#pragma config PWMPIN = OFF // PWM output pins Reset state control (PWM outputs disabled upon Reset (default))
#pragma config LPOL = HIGH // Low-Side Transistors Polarity (PWM0, 2, 4 and 6 are active-high)
#pragma config HPOL = HIGH // High-Side Transistors Polarity (PWM1, 3, 5 and 7 are active-high)
#pragma config T1OSCMX = OFF // Timer1 Oscillator MUX (Standard (legacy) Timer1 oscillator operation)
// CONFIG3H
#pragma config MCLRE = OFF // MCLR Pin Enable bit (Disabled)
// CONFIG4L
#pragma config STVREN = ON // Stack Full/Underflow Reset Enable bit (Stack full/underflow will cause Reset)
#pragma config LVP = ON // Low-Voltage ICSP Enable bit (Low-voltage ICSP enabled)
// CONFIG5L
#pragma config CP0 = OFF // Code Protection bit (Block 0 (000200-000FFFh) not code-protected)
#pragma config CP1 = OFF // Code Protection bit (Block 1 (001000-001FFF) not code-protected)
#pragma config CP2 = OFF // Code Protection bit (Block 2 (002000-002FFFh) not code-protected)
#pragma config CP3 = OFF // Code Protection bit (Block 3 (003000-003FFFh) not code-protected)
// CONFIG5H
#pragma config CPB = OFF // Boot Block Code Protection bit (Boot Block (000000-0001FFh) not code-protected)
#pragma config CPD = OFF // Data EEPROM Code Protection bit (Data EEPROM not code-protected)
// CONFIG6L
#pragma config WRT0 = OFF // Write Protection bit (Block 0 (000200-000FFFh) not write-protected)
#pragma config WRT1 = OFF // Write Protection bit (Block 1 (001000-001FFF) not write-protected)
#pragma config WRT2 = OFF // Write Protection bit (Block 2 (002000-002FFFh) not write-protected)
#pragma config WRT3 = OFF // Write Protection bit (Block 3 (003000-003FFFh) not write-protected)
// CONFIG6H
#pragma config WRTC = OFF // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) not write-protected)
#pragma config WRTB = OFF // Boot Block Write Protection bit (Boot Block (000000-0001FFh) not write-protected)
#pragma config WRTD = OFF // Data EEPROM Write Protection bit (Data EEPROM not write-protected)
// CONFIG7L
#pragma config EBTR0 = OFF // Table Read Protection bit (Block 0 (000200-000FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF // Table Read Protection bit (Block 1 (001000-001FFF) not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF // Table Read Protection bit (Block 2 (002000-002FFFh) not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF // Table Read Protection bit (Block 3 (003000-003FFFh) not protected from table reads executed in other blocks)
// CONFIG7H
#pragma config EBTRB = OFF // Boot Block Table Read Protection bit (Boot Block (000000-0001FFh) not protected from table reads executed in other blocks)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
#include <xc.h>
#define _XTAL_FREQ 8000000