|
|
View previous topic :: View next topic |
Author |
Message |
MrColin
Joined: 05 Sep 2014 Posts: 13
|
INT_RDA Not firing on reception of serial data on PIC16F690 |
Posted: Fri Sep 05, 2014 7:39 am |
|
|
Hi. Problem as in title.
Bellow is the code I'm using to test out the uart on the PIC16F690. It's designed to send back via the UART the number of times the interrupt INT_RDA has fired and the last character received. The only time the interrupt fires is when the uC 1st boots. Never fires again after this.
Communication is handled via a FTDI USB serial port adapter. I've successfully had this device talking in both directions with a PIC16F1947, therefore I can rule it out as being the source of the problem. Characters are successfully received by RealTerm from the uC.
Currently using compiler v4.121.
My thought is that perhaps the Rx pin is still being held by another peripheral and not being released to the UART. But that's just a stab in the dark. I've been trying to get this working for a couple of days now and getting no-where!
Code: |
/*
* File: 16F690 Serial Test
* Author: Colin Waddell
*/
#include <16F690.h>
#fuses EC_IO, HS,PUT, NOFCMEN
#use delay(clock=8000000, restart_wdt)
#use rs232(uart1, baud=115200, xmit=PIN_B7, rcv=PIN_B5, PARITY=N, BITS=8, ERRORS, DISABLE_INTS, STOP=1)
#include <stdlibm.h>
// Global Varialbles for testing
int x = 0;
int i = 0;
void Setup_PIC(void) {
setup_wdt(WDT_2304MS);
setup_oscillator(OSC_NORMAL);
disable_interrupts(GLOBAL);
setup_adc_ports( NO_ANALOGS | VSS_VDD );
//SET_TRIS_B( 0x20 ); //Make sure Rx is an input
enable_interrupts(INT_RDA);//enable uart rcieve interrupt
enable_interrupts(INT_EXT);//enable exernal interrupt
enable_interrupts(GLOBAL);//enable global interrupts
}
void led_on(){
output_high(PIN_C5);
}
void led_off(){
output_low(PIN_C5);
}
void led_toggle(){
output_toggle(PIN_C5);
}
void main(void) {
// setup the PIC
Setup_PIC();
// Indicate a reset
led_on();
delay_ms(1000);
led_off();
while (1) {
restart_wdt();
putc(i);
putc(x);
delay_ms(1000);
}
}
#INT_RDA
void Serial_Rx_isr() {
x = getc();
i++;
clear_interrupt(INT_RDA);
}
|
Many thanks for your time. |
|
|
ezflyr
Joined: 25 Oct 2010 Posts: 1019 Location: Tewksbury, MA
|
|
Posted: Fri Sep 05, 2014 7:52 am |
|
|
Hi Colin,
To further your troubleshooting, I'd try two things:
1. Make a simple LED blink test to be sure your PIC is running at the correct speed. Make a simple loop in Main() that turns an LED On for 1 second, and Off for 1 second. Do this repeatedly, and time it to verify your PIC is running correctly.
2. Do a simply RS-232 Rx and Tx test. Make a simple loop in Main() that reads a character from the UART without the interrupt, and echos it right back. This will simply validate your hardware. You should be able to type characters on your PC terminal program, and the PIC should receive them, and echo them right back to the PC.
Code: |
While(1)
{
putc(getc());
}
|
A couple of notes. You don't need to Clear the int_rda inside the interrupt as the compiler does that for you. Also, you should NEVER enable an interrupt (int_ext) if you don't have a handler for it. That is deadly.
Try these things, and report back!
John |
|
|
MrColin
Joined: 05 Sep 2014 Posts: 13
|
|
Posted: Fri Sep 05, 2014 8:05 am |
|
|
Hi John. Thanks for your quick reply. I've just been through your suggestions with no success. Here are the results...
1) Checked the clock. It's happily ticking over at the expected rate.
1.5) Pulled out the unused interrupt code (curse of the copy/paste) but this had no effect.
2) I've posted the code below which I tested. When running this code the device repeatedly reset itself. This resetting was confirmed by toggling the LED for a second as the code begins. When testing this code the LED repeatedly flashed. This happens with and without the small delay inside the while loop.
Code: |
#include <16F690.h>
#fuses EC_IO, HS, PUT, NOFCMEN
#use delay(clock=8000000, restart_wdt)
#use rs232(uart1, baud=115200, xmit=PIN_B7, rcv=PIN_B5, PARITY=N, BITS=8, ERRORS, DISABLE_INTS, STOP=1)
#include <stdlibm.h>
void Setup_PIC(void) {
setup_wdt(WDT_2304MS);
setup_oscillator(OSC_NORMAL);
disable_interrupts(GLOBAL);
setup_adc_ports( NO_ANALOGS | VSS_VDD );
}
void led_on(){
output_high(PIN_C5);
}
void led_off(){
output_low(PIN_C5);
}
void led_toggle(){
output_toggle(PIN_C5);
}
void main(void) {
// setup the PIC
Setup_PIC();
// Indicate a reset
led_on();
delay_ms(1000);
led_off();
while(1)
{
restart_wdt();
putc(getc());
//delay_ms(10);
}
}
|
|
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19504
|
|
Posted: Fri Sep 05, 2014 8:34 am |
|
|
Change your UART setup to:
Code: |
#use rs232(uart1, baud=115200, PARITY=N, BITS=8, ERRORS)
|
UART1, says to use the two hardware pins, you don't want pin names as well. DISABLE_INTS, is used generally in _software_ serial to prevent the character being interrupted. It is not wanted in your setup.
Stop=1, is all the hardware can do, so is rather pointless too. |
|
|
MrColin
Joined: 05 Sep 2014 Posts: 13
|
|
Posted: Fri Sep 05, 2014 8:41 am |
|
|
Winner Winner, Chicken Dinner!!!
That's spot on. Thank you very much John. I can now enjoy my weekend without worrying about PIC's! |
|
|
|
|
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
|