|
|
View previous topic :: View next topic |
Author |
Message |
kein
Joined: 23 Jul 2007 Posts: 103
|
INT_EXT external interrupt on RB0 not working |
Posted: Tue Feb 17, 2015 12:25 am |
|
|
Hi Gents,
I'm having issues with my external interrupt. I have set up PIN_B0 as a digital input input and PORTE, PIN1 is output. I have also set up INTCON BIT 7, BIT4 and BIT1 as shown on the code below. Similarly, OPTION_REG BIT6 is cleared for Interrupt on falling edge of RB0/INT pin.
Generally, the code works fine, but there are issues .
1. RB0 never cause interrupt to occur even when a character is received. so character 'D' is never printed.
2. code does nothing else if no character is received. I have tried timing out of the polling for a low, but this leads to character being missed and garbage being printed instead.
Can someone helps see what is wrong here please? Appreciate your time and kindness in advance.
Code: |
#include <16F877A.h>
#use delay(crystal=20MHZ)
#FUSES HS,NOWDT,NOLVP,NODEBUG,NOPUT,NOBROWNOUT,NOCPD,NOPROTECT
#define TRISE 0x89
#define TRISB 0x86
#define PORTE 0x09
#define PORTB 0x06
#define TX 0x01 //RE1
#define RX 0x00 //RB0
#define BIT7 0x07
#define BIT6 0x06
#define STATUS 0x0 3 //Status register
#define Z 0x02 //Zero bit
#define DC 0x01 //Zero bit
#define C 0x00 //Zero bit
#define RP0 0x05
#define RP1 0x06
#define INTCON 0x18B //interrupt control register
#define GIE 0x07 //Global interrupt enable bit
#define INTE 0x04
#define INTF 0x01
#define RBIF 0x00
#define OPTION_REG 0x81
#define INTEDG 0x06
#define dataBitCount 8
int1 flag;
void main()
{
InitSoftUART(); //Initialize PORTB, E, Option_Reg and INTCON
flag = 0; //Flag to 0
while(TRUE)
{
if(flag) ///if flag is cleared, send character 'D'
{
RX232putChar('D');
RX232putChar('\n');
RX232putChar('\n');
flag = 0; //reset the flag
}
output_low(PIN_B7);
rxData = RX232getChar();
RX232putChar(rxData);
}
}
#INT_EXT //Set external interrupt on pin RB0
void EXT_ISR()
{
#asm
btfss INTCON,INTF ;//IF RB0/INT External interrupt flag is set
goto EndISR ;//RB0/INT flag is not set
bsf PORTB,BIT7 ;RB7 is high
bsf flag ;//set the flag
bcf INTCON, INTF ;//clear the RB0/INT External interrupt flag
EndISR:
nop
;//bsf INTCON,GIE
;//retfie
#endasm
}
void InitSoftUART(void) // Initialize UART pins to proper values
{
#asm
bcf STATUS, RP1
bsf STATUS, RP0 ;//BANK 1
bsf TRISB, B0 ;Pin B0 is input
bsf TRISB, B7 ;Pin B7 is output
bsf TRISE, E1 ;Pin E1 is output
bcf OPTION_REG, INTEDG ;//Int on falling edge RB0/INT pin
bcf STATUS, RP0 ;//BANK 0
clrf PORTB ;//Initialize PORTB to zero
clrf PORTE ;//Initialize PORTE to zero
bsf INTCON, INTF ;//clear flag
bsf INTCON, INTE ;//Enable RB0/INT external interrupt
bsf INTCON, GIE ;//Enable Global interrupt
#endasm
}
//PORTA,RA4 is data received pin
unsigned char RX232getChar()
{
unsigned char temp;
unsigned char counter = 8;
#asm
clrf ERR ;//ERR = 256
clrf temp ;//Clear temp
getStartBit:
btfsc PORTB, RX ;//Start bit?
goto getStartBit ;//RX set, not start bit
nop
#endasm
baudDelay(28); ;//delay 50us
#asm
btfsc PORTB, RX ;//recheck if indeed start bit?
goto getStartBit ;//RX set, not start bit
#endasm
baudDelay(28); ;//delay 50us (28)
baudDelay(28); ;//delay 50us
#asm
getCharBit:
bcf STATUS, C ;//Clear carry
rrf temp, f ;//Shift 0 into carry
btfsc PORTB, RX ;//RX pin high PORTA, RX
bsf temp, BIT7 ;//set bit 7 to 1
#endasm
baudDelay(28); ;//delay 50us
baudDelay(28); ;//delay 50us
#asm
decfsz counter,f ;//decrement counter, skip next if zero
goto getCharBit
btfss PORTB, RX ;//Look for a stop bit
decf ERR ;//if low, error has occurred
goto endbyte
NotStartBit:
clrf temp
clrf timOut
endbyte:
#endasm
return temp;
}
// * Function: transmit one byte asynchronously
// * delay used is giving a 0.5 of bit
// *
void RX232putChar(unsigned char _char)
{
unsigned char temp;
unsigned char counter = 8;
#asm
movf _char, w
movwf temp;
bcf PORTE,TX ;start bit
#endasm
baudDelay(28);
baudDelay(28);
#asm
PutCharLoop:
rrf temp, f ;rotate right into carry
btfss STATUS,C ;Test carry bit is set
goto bitIsZero ;if bit is 0
bsf PORTE,TX ;if bit is 1
goto Nextbit
bitIsZero:
bcf PORTE,TX ;sent
Nextbit:
nop
#endasm
baudDelay(28);
baudDelay(28);
#asm
decfsz counter, f
goto PutCharLoop
bsf PORTE,TX
#endasm
baudDelay(28);
baudDelay(28);
}
//this a 0.0504 microseconds delay
void baudDelay(unsigned char _xtal)
{
#asm
movf _xtal,w ;1cycle - 0.2us
baudLoop:
addlw -1 ;1cycle - 0.2us
nop ;1cycle - 0.2us
nop ;1cycle - 0.2us
nop ;1cycle - 0.2us
nop ;1cycle - 0.2us
nop ;1cycle - 0.2us
btfss STATUS, Z ;1cycle - 0.2us --->(N-1)+2
goto baudLoop ;2cycle - 0.4us --->2*(N-1)
;Totalcyc = N*9 - 1 + 1 => Delay = N*9*0.2us = 1.8*N
#endasm
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19545
|
|
Posted: Tue Feb 17, 2015 12:53 am |
|
|
If you want to write assembler, use assembler and get rid of CCS. If you want to use CCS, then start programming in CCS C.
Seriously the CCS functions can do everything you are trying to do, and are less likely to get it wrong.
There is a huge amount of waste in what you are doing. CCS has already checked that the interrupt bit is set, before the INT_EXT routine will be called. It also clears the interrupt flag for you. At this point I gave up looking further.
I'd reckon that what this is trying to do, would only be about 10 lines of CCS code. You have the compiler, so use it. |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|