|
|
View previous topic :: View next topic |
Author |
Message |
on7nh
Joined: 05 Jun 2006 Posts: 41 Location: Belgium
|
receiving one char on rs232 then rebooting |
Posted: Mon Jun 13, 2011 2:35 pm |
|
|
ok, i have something strange.
some code... works fine,
but after transmitting a serial character, the pic reboot
is there a solution to find out whats happening?
Carl |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
Re: receiving one char on rs232 en rebooting |
Posted: Mon Jun 13, 2011 2:49 pm |
|
|
on7nh wrote: | ok, i have something strange.
some code... works fine,
but after transmitting a serial character, the pic reboot
is there a solution to find out whats happening?
Carl |
You need to provide more information. What PIC family and what compiler. For example, if you are using a PIC24 / dsPIC then the problem could be as a WORD alignment problem causing a TRAP and not an RS232 issue. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Mon Jun 13, 2011 2:50 pm |
|
|
Start by checking your code, and making sure you have not got an interrupt enabled, without an interrupt handler present. This _will_ cause the code to crash to an early memory location, and possibly behave as if the chip had reset....
Then add code right at the start of your main to read 'restart_cause', and put the value this returns out latter - on a port as a bit pattern perhaps. Have the code setup so it stops if this is _not_ a power on reset.
Hence code should run once, sending the byte to cause a problem, then on the restart, the 'cause' will become available for you to read with a meter/scope on the bit pattern. Look this up, and you may have a clue what is going on.
Compiler version?. Chip?. Small test program that shows the problem. All needed for us to help.
Best Wishes |
|
|
dorinjj
Joined: 21 Jan 2011 Posts: 5
|
dsPIC33FJ64GP202 - INT_RDA problem |
Posted: Thu Jun 30, 2011 8:36 am |
|
|
Hi, I have a problem with dsPIC33FJ64GP202 with UART Receive Interrupt (INT_RDA) and I don't know why.
The compiler version is 4.104.
I want to send at TX pin data that come from RX pin.
I made this simple program, but when I powered on the mcu, I received only one or two times this character "*" and after that if I want to send a character to mcu, nothing is happening.
Thank You.
Code: |
#include <33FJ64GP202.h>
#device *=16
#fuses NOJTAG,NOWDT,FRC_PLL,OSCIO
#use delay(clock=80000000, type=internal)
#pin_select U1TX=pin_B0
#pin_select U1RX=pin_B1
#use rs232(baud=9600, UART1)
static unsigned int8 data_received;
void mcu_setup(void){
setup_oscillator(OSC_INTERNAL,80000000);
SETUP_WDT(WDT_OFF);
setup_uart(9600);
enable_interrupts(INTR_GLOBAL);
enable_interrupts(INT_RDA);
delay_ms(100);
}
void main(){
mcu_setup();
SET_TRIS_a(0x0000);
SET_TRIS_b(0x0000);
output_a(0xffff); // this has no influence
output_b(0xffff); // this has no influence
while(1){
#asm
nop
#endasm
}
}
#int_rda
void receive_data(void){
printf("*");
data_received=getch();
printf(data_received);
}
|
|
|
|
arunb
Joined: 08 Sep 2003 Posts: 492 Location: India
|
RE: |
Posted: Tue Jul 05, 2011 2:32 am |
|
|
Don't put the printf() statements inside the interrupt handler. Instead set a flag inside the interrupt handler, check to see if the flag is set in the main loop, do the printing then clear the flag.
It is usual practice to do memory intensive jobs outside the ISR. The code inside the ISR should be kept as minimum as possible.
In your case the ISR will contain the statement to set the flag, and another statement to receive the character.
Hope this helps you..
thanks
a |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19513
|
|
Posted: Tue Jul 05, 2011 4:44 am |
|
|
The code as written, _will_ hang the UART.
Problem is that for each single character received, the code sends two. After only a couple of charcaters, the output buffer will be full, so the printf, then _waits_ for the character to transmit. Meanwhile, other characters arriving, will have now overflowed the input buffer, resulting in this being in an error state, and the UART is hung.....
Add the keyword 'ERRORS' to the RS232 setup. This will add code to clear the hang. Data will still be lost, but at least things will keep working....
If you want to send two characters back, you need to be using an interrupt driven transmit, as well as the receive, and have a software buffer large enough to handle the extra characters, and/or flow control (pause the transmission when the buffer approaches full).
Best Wishes |
|
|
dorinjj
Joined: 21 Jan 2011 Posts: 5
|
|
Posted: Tue Jul 05, 2011 3:59 pm |
|
|
I had modified a bit the program after "arunb" advice and now I can receive data from mcu.
However, I can't use printf() function, for example: if I use printf() (with "ERRORS" in #use rs232...) and If I send any text to the mcu with 10 chars for example, I receive totally something else with a small number of chars, so I must use putc() function.
Code: |
#include <33FJ64GP202.h>
#device *=16
#fuses NOJTAG,NOWDT,FRC_PLL,OSCIO
#use delay(clock=80000000, type=internal)
#pin_select U1TX=pin_B0
#pin_select U1RX=pin_B1
#use rs232(baud=9600, UART1, ERRORS) // use ERRORS
static unsigned int8 data_received;
static int1 rx_flag=0;
void mcu_setup(void){
setup_oscillator(OSC_INTERNAL,80000000);
SETUP_WDT(WDT_OFF);
setup_uart(9600);
enable_interrupts(INTR_GLOBAL);
enable_interrupts(INT_RDA);
delay_ms(100);
}
void main(){
mcu_setup();
SET_TRIS_a(0x0000);
//SET_TRIS_b(0b0000000000000010); // RX pin -> input
SET_TRIS_b(0x0000); // this has no effect on RX pin
output_a(0xffff);
output_b(0b1111111111111100);
output_float(pin_B1); // RX pin must "float"
//output_float(pin_B0); // TX is not necessary to "float"
while(1){
if(rx_flag==1){
putc(data_received);
//printf(data_received); //doesn't work
rx_flag=0;
}
}
}
#int_rda
void receive_data(void){
data_received=getch();
rx_flag=1;
//putc('*'); // if I use this uart will hang
//putc(data_received); // I can use this instead "rx_flag"
}
//Conclusion:
//If I use UART, I should make RX pin "to float"
|
|
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9226 Location: Greensville,Ontario
|
|
Posted: Tue Jul 05, 2011 4:30 pm |
|
|
ISR (Interrupt Service Routines) are supposed to be very, very short !
Set a 'flag' that 'you got data' then exit, your 'main' routine will then see that the 'flag' has been set, take appropriate action and reset the 'flag'.
hth |
|
|
dyeatman
Joined: 06 Sep 2003 Posts: 1934 Location: Norman, OK
|
|
Posted: Tue Jul 05, 2011 4:38 pm |
|
|
Another option is to use a global variable that you assign from getc(). In
the main loop, if a character has arrived it will be non-zero. Save the
character then zero the variable and wait for it to be non-zero again.
The downside is you will have to check this often to keep from losing
characters. The best bet is to use the CCS example ex-sisr.c for a guide. _________________ Google and Forum Search are some of your best tools!!!! |
|
|
|
|
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
|