|
|
View previous topic :: View next topic |
Author |
Message |
cmcnr
Joined: 18 Mar 2011 Posts: 6
|
couldnt use int_rda interrupt for rs232 communication |
Posted: Fri Mar 18, 2011 2:49 pm |
|
|
I tried to use #int_rda interrupt but I couldn't be successful. I am trying to learn rs232 communication between two pic also pc. Master program works well as I tested with pc. Pc could read the information which is sent. Unfortunately slave pic couldn't receive the information. I checked the forum and I see that some version of ccs devices.dat file isn't suitable for hardware int_rda interrupt. I don't know how to check my version is suitable or not. My version is 4.084.
I created basic program to check interrupts job. Also codes are shown at the below.
Slave:
Code: |
#include <16f628a.h>
#fuses XT,NOPROTECT,NOCPD,NOBROWNOUT,NOPUT,NOWDT,NOLVP
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1)
#int_rda
void komut_al()
{
disable_interrupts(int_rda);
output_high(pin_b4);
}
main()
{
set_tris_a(0b00000011);
set_tris_b(0b00000000);
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
basla:
enable_interrupts(int_rda);
goto basla;
}
|
Master
Code: |
#include <16f628a.h>
#fuses XT,NOPROTECT,NOCPD,NOBROWNOUT,NOPUT,NOWDT,NOLVP
#use delay(clock=4000000)
#use fast_io(a)
#use fast_io(b)
#use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1)
main()
{
#asm
MOVLW 03;
MOVWF 05;
#endasm
basla:
if(input(pin_a0))
{
}
else
{
printf("Open\n\r");
}
if(input(pin_a1))
{
}
else
{
printf("Close\n\r");
}
delay_ms(150);
goto basla;
}
|
And the test circuit:
Uploaded with ImageShack.us |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9247 Location: Greensville,Ontario
|
|
Posted: Fri Mar 18, 2011 2:57 pm |
|
|
If the schematic is of real hardware, then your programs will never work. You must use a MAX232 or equal chip as a level translator between the PICs. This is necessary for the ISR to function correctly.
Also, it is easier for novice programmers to NOT use the tris() and fast() functions but let the compiler automatically handle the required code.
Also you do not need to disable interrupts within the ISR, again the compiler does that for you.
Also your schematic does not show the xtal and caps ,as well as VDD and VSS which are required for the PIC to work. |
|
|
cerr
Joined: 10 Feb 2011 Posts: 241 Location: Vancouver, BC
|
|
Posted: Fri Mar 18, 2011 3:03 pm |
|
|
temtronic wrote: | If the schematic is of real hardware, then your programs will never work. You must use a MAX232 or equal chip as a level translator between the PICs. This is necessary for the ISR to function correctly.
|
I got RS232 between two pics to work with no MAX232 on either side - I however didn't utilize INT_RDA. If you want to communicate over RS232 with a PC you will need an level translator in your circuit. |
|
|
cmcnr
Joined: 18 Mar 2011 Posts: 6
|
|
Posted: Fri Mar 18, 2011 3:25 pm |
|
|
temtronic wrote: | If the schematic is of real hardware, then your programs will never work. You must use a MAX232 or equal chip as a level translator between the PICs. This is necessary for the ISR to function correctly.
Also, it is easier for novice programmers to NOT use the tris() and fast() functions but let the compiler automatically handle the required code.
Also you do not need to disable interrupts within the ISR, again the compiler does that for you.
Also your schematic does not show the xtal and caps ,as well as VDD and VSS which are required for the PIC to work. |
Thank you! Yes i am novice but have eager to learn:)
i added two max 232. I tried it but didnt work. After that i deleted all tris and fastio function. And than it is worked!
Could you explain what was my mistake about tris and fast_io code?
Also new circuit .... I didnt add vdd and xtal because isis handles it
Uploaded with ImageShack.us |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Fri Mar 18, 2011 3:30 pm |
|
|
No, you do _not_ need a MAX232 between PIC's.
It is _not_ necessary for the 'ISR to function correctly'.
It _is_ necessary if you want to talk to a device using RS232 (like the PC), but the PIC's themselves talk 'async TTL serial', and will happily connect together.
There are some very major software problems though. Do not disable INT_RDA in the RDA interrupt. What you _must_ do, is read the received character.
As it stands, not reading the character _will_ cause the UART to become hung...
Get rid of the ASM. The whole point of having a compiler, is to let _it_ do the work. There is only perhaps 1 in 10000 programs now, that ever need touch a line of assembler. This is _not_ one.
Stop using Goto's. You do not need them, and they encourage bad programming. On most computer courses these would guarantee a 'fail'.
Get rid of the #use fast_io lines. These will stop your code working. You are saying to the compiler 'I am taking charge of controlling TRIS', and then you are not setting the TRIS. Without these lines, and with the character read in the ISR, the code has a chance of working.
Best Wishes |
|
|
cmcnr
Joined: 18 Mar 2011 Posts: 6
|
|
Posted: Fri Mar 18, 2011 3:48 pm |
|
|
I tried it without max232 Ttelmah. It is working as you said. From now,I will also get rid of goto's .
I read in a document that we need to use "disable_interrupts(int_rda)" code in interrupt routine. And the explanation is "if we dont disable interrupt, it will always need to go to begining of int_rda codes when new uart data will come. As a result it will break int_rda codes' process"
Maybe it wont prevent a simple led lightining function. I think it will be problem when the codes will longer. Am i right?
By the time i realised that, the program always go to the int_rda interrupt altough there is no new uart data
Cycle:
Main->int_rda->Main->int_rda and goooo on... |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9247 Location: Greensville,Ontario
|
|
Posted: Fri Mar 18, 2011 6:19 pm |
|
|
I'd assumed that the OP was using a builtin UART and according to CCS, you have to use the 'invert' option of the RS232(...) directive in order to get the right signalling level for proper serial communications. Otherwise 1s are 0s, and vice versa.
Course I also don't understand the 'get rid of 'gotos' or fail philosophy.
Gotos are nothing more than a high level language equivalent to the PIC instruction Goto, or Jump in other microcomputers. If it's fine in assembler, why shun it's use in another language? |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19553
|
|
Posted: Sat Mar 19, 2011 3:15 am |
|
|
cmcnr wrote: | I tried it without max232 Ttelmah. It is working as you said. From now,I will also get rid of goto's .
I read in a document that we need to use "disable_interrupts(int_rda)" code in interrupt routine. And the explanation is "if we dont disable interrupt, it will always need to go to begining of int_rda codes when new uart data will come. As a result it will break int_rda codes' process"
Maybe it wont prevent a simple led lightining function. I think it will be problem when the codes will longer. Am i right?
By the time i realised that, the program always go to the int_rda interrupt altough there is no new uart data
Cycle:
Main->int_rda->Main->int_rda and goooo on... |
No.
You are reading something applying to a different processor.
On a processor like the PIC, which does not support 're-entrancy' (code called inside itself), it is _vital_ that interrupts are disabled inside the interrupt handlers. However, the manufacturers 'know' this, so the chip's _hardware_ automatically performs a disable_interrupt, when the interrupt handler is called. There is then a special 'return' instruction, used to return from the interrupt handler (the compiler automatically uses this), which enables the interrupts _after_ the code returns.
So as a 'generic' thing, the comment is right, but on the PIC, the hardware handles this, and you don't have to disable interrupts.
Best Wishes |
|
|
cmcnr
Joined: 18 Mar 2011 Posts: 6
|
|
Posted: Sat Mar 19, 2011 5:04 am |
|
|
Thank you for this information Ttelmah.I remove the disable and enable codes as you said and still working. But couldnt handle a problem yet.
"the program always go to the int_rda interrupt altough there is no new uart data" cycle Main->int_rda->Main->int_rda and goooo on...
New codes...
Receiver
Code: |
#include <16f628a.h>
#fuses XT,NOPROTECT,NOCPD,NOBROWNOUT,NOPUT,NOWDT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1)
#int_rda
void komut_al()
{
output_high(pin_b4);
delay_ms(1000);
output_low(pin_b4);
delay_ms(1000);
}
main()
{
enable_interrupts(int_rda);
enable_interrupts(GLOBAL);
while(1)
{
}
}
|
Receiver
Code: |
#include <16f628a.h>
#fuses XT,NOPROTECT,NOCPD,NOBROWNOUT,NOPUT,NOWDT,NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=pin_B2, rcv=pin_B1)
main() {
while(1)
{
if(input(pin_a0))
{
}
else
{
printf("Open\n\r");
}
if(input(pin_a1))
{
}
else
{
printf("Close\n\r");
}
delay_ms(150);
}
}
|
|
|
|
cmcnr
Joined: 18 Mar 2011 Posts: 6
|
|
Posted: Sat Mar 19, 2011 10:41 am |
|
|
I read the topic http://www.ccsinfo.com/forum/viewtopic.php?t=36800
Ttelmah wrote: | The 'idle' state for TTL RS232, is with the signal _high_ (5v). A disconnected pin, is probably floating _low_. This is seen as continuous RS232 data.
Then, the second reason, is your interrupt code. Once even one character is seen, it'll trigger for ever. When the RS232 interrupt occurs, it is saying 'I have a character that _needs_ reception'. Your routine does not retrieve the character, so it'll trigger again (and again, and again......).
So, do two things:
1) Add something to pull the RX pin high (a 100K resistor to +5v, or connect th line to the output of a MAX232 which will idle high - however you will still probably see one garbage character, as the chip wakes up).
2) Add a 'getc' to your interrupt.
Best Wishes |
After i read that i added "getc(c)" code into int_rda interrupt. Unfortunately result is same |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Mar 19, 2011 2:34 pm |
|
|
Quote: | After i read that i added "getc(c)" code into int_rda interrupt. |
That's not the correct syntax. You must read the CCS manual for
any function you use, and you must look at the many examples of code
posted in this forum. Never "invent" your own syntax. If you do that,
people will stop responding to your posts. You need to encourage people
to help you. Study the CCS manual. Try to do everything correctly.
Here is an example of #int_rda function that gets an incoming character
and immediately sends it back to the sender. (Just for an example).
Code: |
#int_rda
void rda_isr(void)
{
char c;
c = getc(); // Get character from PC
putc(c); // Send it back to the PC
} |
|
|
|
cmcnr
Joined: 18 Mar 2011 Posts: 6
|
|
Posted: Sat Mar 19, 2011 3:09 pm |
|
|
PCM programmer wrote: | Quote: | After i read that i added "getc(c)" code into int_rda interrupt. |
That's not the correct syntax. You must read the CCS manual for
any function you use, and you must look at the many examples of code
posted in this forum. Never "invent" your own syntax. If you do that,
people will stop responding to your posts. You need to encourage people
to help you. Study the CCS manual. Try to do everything correctly.
Here is an example of #int_rda function that gets an incoming character
and immediately sends it back to the sender. (Just for an example).
Code: |
#int_rda
void rda_isr(void)
{
char c;
c = getc(); // Get character from PC
putc(c); // Send it back to the PC
} |
|
Yes i am rookie, and trying to learn it by myself.. I didnt joined any electronic lesson before in my life. just reading books. just for hobby and have eager. Actually it was a typo mistake, i added "gets(c)"... nevermind.... i think i am not capable for this forum.... thank you anyway |
|
|
|
|
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
|