|
|
View previous topic :: View next topic |
Author |
Message |
wewa
Joined: 02 Jul 2008 Posts: 27
|
Receiving serial data |
Posted: Wed Jul 02, 2008 11:01 am |
|
|
Hi!
I'm using an PIC18F4525 and I want to communicate over RS232 with this chip. The program is compiled with MPLAB IDE and CCS C.
And thats my program:
Code: | #include <18F4525.h>
#device ICD=true
#device ADC=8
#use delay(clock=20000000) //Geschw. des Oszillators (für delay)
#BIT RDA_INT_enable = 0xF9D.5
#BIT GIE = 0xFF2.7
#BIT CCP1IF = 0xF9E.2
#BIT BUFFER_FULL = 0xF9E.5
#BYTE port_b = 0xF81
#fuses NOWDT, HS //kein WatchDog-Timer, HighSpeed Crystal Oscillator
#use rs232(baud=4800, xmit=PIN_c6, rcv=PIN_c7, stream=PC) //für serielle Kommunikation mit PC (xmit=PIN_c6, rcv=PIN_c7)
#priority Timer1,RDA,CCP1,RTCC
#define run_led pin_b4
#define init_led pin_b5
#define gsm_led pin_b6
#define alarm_led pin_b7
#define alarm1 input(pin_b1)
#define com pin_a5 //orig. "SP Ausfall"; wird benutzt um RX zu PC zu unterbrechen; steuert 3stateBuffer an (schaltet bei LO durch)
#define pc_con input(pin_a4) //HI wenn Kabel angesteckt
#int_rda
void serial_isr() {
fprintf(PC,"\r\nseriell empfangen\r\n");
output_high(init_led);
output_high(run_led);
delay_ms(1000);
}
void main()
{
enable_interrupts(INT_RDA); //Interrupt für seriellen Empfang
enable_interrupts(GLOBAL); //globaler Interrupt
output_low(com); //damit vom PC empfangen werden kann
output_high(init_led);
output_high(run_led);
delay_ms(1000);
while(1){
if(pc_con) //Kabel angeschlossen
{
output_high(run_led);
output_low(init_led);
}
if(!pc_con) //Kabel nicht angeschlossen
{
output_high(init_led);
output_low(run_led);
}
if(!pin_b0) //wird DI auf LO gezogen, wird Alarm ausgegeben (seriell)
{
fprintf(PC,"\r\nACHTUNG: Alarm!\r\n");
}
if(!alarm1) //wird DI auf LO gezogen, wird Alarm ausgegeben (seriell)
{
fprintf(PC,"\r\nACHTUNG: Alarm!\r\n");
}
}
} |
If I pull for example the "alarm1" pin low, the message is sent over RS232, because I can prove this with Hyperterminal or another Telnet prog.
But the problem is, nothing hapens if i send something to the µC. Do I have to enable the receivment of data somewhere?
I hope you can help me a little.
your wewa
PS: The board works. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Wed Jul 02, 2008 11:50 am |
|
|
Quote: | #int_rda
void serial_isr() {
fprintf(PC,"\r\nseriell empfangen\r\n");
output_high(init_led);
output_high(run_led);
delay_ms(1000);
} |
You need to "get" the character when you're inside the isr, to clear
the interrupt. When you're using streams, you can get the character
with this line:
Normally, you should not put large printf statements and large delays
inside your int_rda isr. If you do that, and you receive more than
two characters without reading them from the UART, the PIC will
generate an "overrun error" condition and the UART will lock-up.
If you insist upon putting large delays in the isr, then you should add the
ERRORS parameter to your #use rs232() statement. This will tell the
compiler to insert code to automatically clear any overrun error that
occurs (but you will still lose the character).
It's better to just not put printf or delay delay statements in the ISR.
Quote: | #use rs232(baud=4800, xmit=PIN_c6, rcv=PIN_c7, ERRORS,stream=PC) |
Also, it's a good idea to add the ERRORS parameter even if you don't
expect overrun errors. It makes the program more safe because it will
prevent a possible UART lockup condition. |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Wed Jul 02, 2008 12:04 pm |
|
|
Thanks for the quick help. I'll try it tomorrow.
I hope you forgive me such silly/simple questions, but until now I've only programmed 8051 µC.
What do you think about this, if I de- and reactivate the interrupt in the ISR, like this?
Code: | #INT_RDA
void serial_isr() {
disable_interrupts (INT_RDA);
fprintf(PC,"\r\nseriell empfangen\r\n");
output_high(init_led);
output_high(run_led);
delay_ms(1000);
enable_interrupts(INT_RDA);
} |
PS: Is there any good tutorial for the CCS C compiler?[/code] |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1909
|
|
Posted: Wed Jul 02, 2008 12:41 pm |
|
|
Still no good. Interrupt service routines MUST be short because the world doesn't stop turning while the PIC is executing the code in the ISR. It would be much better to instead set a flag inside of the ISR, for instance data_received = TRUE; data_received is declared as an int1. Make sure you declare its initial value to be FALSE.
In your main loop of the program you have an infinite loop:
Code: | while (TRUE) {
//program execution here
} |
In that loop, test for data_received to be true, like this:
Code: | if (data_received) {
data_received = FALSE;
// do whatever you want here
} |
Coding in this manner ensures that the processor doesn't spend much time in any ISR. This in turn ensures that the processor can react quickly to other interrupts. Clear? |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Thu Jul 03, 2008 2:18 am |
|
|
Now I've trested your advice, but it doesn't work. Therefore I've tested a simple prog to test die serial connection (it was posted somewhere in this board).
Code: | #include <18F4525.h>
#fuses HS,NOWDT,NOPROTECT,BROWNOUT,PUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=19200, xmit=PIN_c6, rcv=PIN_c7, STREAM = COM_A)
//============================
void main()
{
char c;
while(1)
{
c = getc(); // Get char from PC
putc(c); // Send it back to PC
}
} |
But again, I can only send data with the PIC, but I receive nothing.
What could be the problem? |
|
|
Ttelmah Guest
|
|
Posted: Thu Jul 03, 2008 2:33 am |
|
|
Hardware.
You need to to carefully through everything.
Start with a DVM or scope, on the PIC RCV pin. Is this sitting close to 5v, when the PC is sending nothing?. Then (if using a scope), do you see a -ve going pulse train, when you send a character from the PC?. Does this go down to almost the 0v level?. If this is not the case, then you need to move along the connections. Is the connection to the driver chip (MAX232 or equivalent), low resistance?. Does it go to the right pin?. You know the chip has power (since you can send), and that it's charge pump capacitors are OK, for the same reason. So, then are you sure you are connected to the correct pin on the PC 'side' of the chip?. Is the connection to the PC itself low resistance?. Make sure also, that each connection is not shorting to the GND, or 5v rails at any point. Don't 'assume' anything. Fr example, if the connection is on a PCB, and 'looks OK', still test it with a DVM, pin to pin. Tiny hairline cracks, or whiskers under pads, are the hardest failures to find.
Best Wishes |
|
|
wewa
Joined: 02 Jul 2008 Posts: 27
|
|
Posted: Thu Jul 03, 2008 4:54 am |
|
|
Hy again!
I've now tested the very simple prog. above on the development board PICDEM 2.
There's the same problem again. And I don't think that 2 boards have the same problem. I've also tested the connection of the com-cable, and it looks fine.
No ideas? |
|
|
|
|
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
|