lsteele
Joined: 02 Jan 2007 Posts: 18
|
Trouble receiving serial data |
Posted: Tue Dec 18, 2007 7:00 am |
|
|
Hello,
I'm trying to get a simple interrupt driven serial program going on my 16f876a. At the moment I just want my program to take all bytes received by the usart and stick them in a buffer, then when the user hits enter on the pc, have the program print the contents of the buffer on the screen.
At this point I have successfully output data From the pic to the PC. But I'm having problems the other way round.
In my int_rda isr I also (besides storing the received character) turn an led on and off so that I get a visual indication of when it's triggering. At the moment when I power up my pic I can see the led flickering on and off rapidly. If I disconnect the pic from the max232 (with C6 & c7 floating) I get the same result. If I ground or tie the receive pin (c7) high the led goes off. I've included the program listing below.
Any help is gratefully received! If any more information is needed please tell me and I will try and provide it.
Thanks,
Luke
Code: | #include <16f876a.h>
#device ADC=10
#fuses HS,NOWDT,NOPROTECT,NOBROWNOUT,NOPUT,NOPROTECT
#use delay(clock=20000000)
#use rs232(baud=57600, xmit=pin_c6,rcv=pin_c7, ERRORS)
#use fast_io (A)
#use fast_io (B)
#use fast_io (C)
//#use fast_io (C)
#define RLED pin_c5
// GLOBAL VARS
unsigned char lastPortB=0;
signed int32 mPos=0, dmPos=0;
// Portb 4-7 interrupt handler
#int_rb // Activated every time a change in portb state, i.e. a transition from black to white, occurs.
void rb_isr() {
unsigned char portbVal;
signed char direction;
portbVal = input_b(); // Have to read port b to clear mismatch condition.
// other stuff
}
// Serial global variables
char inputBuffer[25];
int1 dataReady = false;
#int_rda
void serial_isr() {
char i, byteIn;
static unsigned char buffIdx=0;
output_high(RLED);
if(buffIdx>=24) buffIdx=0;
byteIn=getc();
// Check if EOL, i.e. end of command
if((byteIn=="\n") || (byteIn=="\r")) {
inputBuffer[buffIdx]=0; // Terminate string
dataReady=true;
buffIdx=0;
}
else {
inputBuffer[buffIdx]=byteIn;
dataReady=false;
buffIdx++;
}
output_low(RLED);
}
// Timer ISR and variables.
int1 timeToUpdate=false;
#INT_TIMER1
void timer1_isr()
{
timeToUpdate = true; // Tells main program loop to update balance calculations.
}
void flashLed();
void main(void) {
unsigned long i, wvDly, pwmDuty;
signed char cnt;
set_tris_c(0x00);
set_tris_b(0xff);
flashLed();
printf("\n\rrunning\n\r");
enable_interrupts(INT_RB); // Detects state changes on port b to count encoder wheel transitions
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2); // 40hz
set_timer1(0);
enable_interrupts(INT_TIMER1); // Timer interrupt
enable_interrupts(int_rda); // Detects incomming serial transmissions.
enable_interrupts(GLOBAL); // Turn all interrupts on
cnt=1;
pwmDuty=511;
wvDly=0;
i=0;
do {
if(timeToUpdate) {
timeToUpdate=false;
printf("\n\r%ld", i++);
if(dataReady) {
printf("\n\r%s\r\n", inputBuffer);
dataReady=false;
}
// Other stuff...
if(timeToUpdate) {
printf("\n\rWarning: Taking too long in loop");
}
}
} while(true);
}
void flashLed()
{
char i;
for(i=0; i<10; i++) {
output_high(RLED);
delay_ms(30);
output_low(RLED);
delay_ms(30);
}
}
|
|
|