Kylobeetle
Member
Hello again guys, its me again .. this time im playing (or trying to) with RB0 external interrupt, since i finally could control the UART interrupts now im trying to understand the external interrupt. For this dutty i have made some research (also i tried to look here but no luck) and I found a "working" code, i ran it and the code works, but the interrupt doesnt. So i have read the datasheet multiple times and i have understood that important values like, rising edge, global interrupt, rb0 interrupt, who is output and input are correct but i cant understand why is not working... I ll post this borrowed code just for learning purposes since my code are packed in headers and this one is fastest for posting purposes haha.
In this code you will find the Init for the 16X2 LCD also a counter, which will represent the main program, the idea would be press RB0 and show that you are in an ISR then return back to the count.. i dont know if my problem is during my electrical conections which im almost sure that are not.. (i ll still check it again if is needed) .. thanks beforehand.
Code:
#define _XTAL_FREQ 4000000
#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7
#include <xc.h>
#include "config.h"
//LCD Functions Developed by Circuit Digest.
void Lcd_SetBit(char data_bit) //Based on the Hex value Set the Bits of the Data Lines
{
if(data_bit& 1)
D4 = 1;
else
D4 = 0;
if(data_bit& 2)
D5 = 1;
else
D5 = 0;
if(data_bit& 4)
D6 = 1;
else
D6 = 0;
if(data_bit& 8)
D7 = 1;
else
D7 = 0;
}
void Lcd_Cmd(char a)
{
RS = 0;
Lcd_SetBit(a); //Incoming Hex value
EN = 1;
__delay_ms(4);
EN = 0;
}
void Lcd_Clear()
{
Lcd_Cmd(0); //Clear the LCD
Lcd_Cmd(1); //Move the curser to first position
}
void Lcd_Set_Cursor(char a, char b)
{
char temp,z,y;
if(a== 1)
{
temp = 0x80 + b - 1; //80H is used to move the curser
z = temp>>4; //Lower 8-bits
y = temp & 0x0F; //Upper 8-bits
Lcd_Cmd(z); //Set Row
Lcd_Cmd(y); //Set Column
}
else if(a== 2)
{
temp = 0xC0 + b - 1;
z = temp>>4; //Lower 8-bits
y = temp & 0x0F; //Upper 8-bits
Lcd_Cmd(z); //Set Row
Lcd_Cmd(y); //Set Column
}
}
void Lcd_Start()
{
Lcd_SetBit(0x00);
for(int i=1065244; i<=0; i--) NOP();
Lcd_Cmd(0x03);
__delay_ms(5);
Lcd_Cmd(0x03);
__delay_ms(11);
Lcd_Cmd(0x03);
Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
Lcd_Cmd(0x02); //02H is used for Return home -> Clears the RAM and initializes the LCD
Lcd_Cmd(0x08); //Select Row 1
Lcd_Cmd(0x00); //Clear Row 1 Display
Lcd_Cmd(0x0C); //Select Row 2
Lcd_Cmd(0x00); //Clear Row 2 Display
Lcd_Cmd(0x06);
}
void Lcd_Print_Char(char data) //Send 8-bits through 4-bit mode
{
char Lower_Nibble,Upper_Nibble;
Lower_Nibble = data&0x0F;
Upper_Nibble = data&0xF0;
RS = 1; // => RS = 1
Lcd_SetBit(Upper_Nibble>>4); //Send upper half by shifting by 4
EN = 1;
for(int i=2130483; i<=0; i--) NOP();
EN = 0;
Lcd_SetBit(Lower_Nibble); //Send Lower half
EN = 1;
for(int i=2130483; i<=0; i--) NOP();
EN = 0;
}
void Lcd_Print_String(char *a)
{
int i;
for(i=0;a[i]!='\0';i++)
Lcd_Print_Char(a[i]); //Split the string using pointers and call the Char function
}
/*****End of LCD Functions*****/
/****Interrupt function ****/
void interrupt ISR_example()
{
if (INTF==1) //External Interrupt detected
{
Lcd_Clear();
Lcd_Set_Cursor(1,1);
Lcd_Print_String(" Entered ISR");
INTF = 0; // clear the interrupt flag after done with it
__delay_ms(2000);
Lcd_Clear();
}
}
/****End of Interrupt Function****/
int number =0;
char ch1,ch2,ch3,ch4;
int main()
{
TRISD = 0x00; //PORTD declared as output for interfacing LCD
TRISB0 = 1; //DEfine the RB0 pin as input to use as interrupt pin
OPTION_REG = 0b00000000; // Enables PULL UPs
GIE=1; //Enable Global Interrupt
PEIE=1; //Enable the Peripheral Interrupt
INTF=0;
INTE = 1; //Enable RB0 as external Interrupt pin
Lcd_Start();
while(1)
{
ch1 = (number/1000)%10;
ch2 = (number/100)%10;
ch3 = (number/10)%10;
ch4 = (number/1)%10;
Lcd_Set_Cursor(2,1);
Lcd_Print_String("Inside Main Loop");
Lcd_Set_Cursor(1,1);
Lcd_Print_String("Number: ");
Lcd_Print_Char(ch1+'0');
Lcd_Print_Char(ch2+'0');
Lcd_Print_Char(ch3+'0');
Lcd_Print_Char(ch4+'0');
__delay_ms(500);
number++;
}
return 0;
}
In this code you will find the Init for the 16X2 LCD also a counter, which will represent the main program, the idea would be press RB0 and show that you are in an ISR then return back to the count.. i dont know if my problem is during my electrical conections which im almost sure that are not.. (i ll still check it again if is needed) .. thanks beforehand.