View previous topic :: View next topic |
Author |
Message |
bignick270
Joined: 11 Sep 2008 Posts: 44
|
what to do in INT_RDA |
Posted: Fri Oct 03, 2008 11:22 am |
|
|
I have never used the communications aspect of the PICs in detail and I need to figure it out now. Also I have looked at the examples from CCS and I didn't care for them.
In INT_RDA what should be done if I have 3 bytes coming in that needs to be stored?
Here is my code so far...I don't have a clue.
Code: |
#int_RDA
void RDA_isr(void)
{
OUTPUT_LOW(PIN_D6);
if(kbhit(IN))
{
for(i=0; i<3; i++)
{
msg[i] = fgetc(IN);
}
}
rxflag = 1;
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 03, 2008 11:32 am |
|
|
This is newbie-style code. I'm not blaming you. You probably found it
on the forum.
Don't sit in an isr and wait for two or more incoming bytes. What if the additional bytes never come ? Your whole program is locked up.
Get one byte per interrupt. Put it in a global buffer. See the Ex_sisr.c
example file in your CCS \Examples directory
We don't want to write your code for you. You need to do it and learn. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Fri Oct 03, 2008 11:38 am |
|
|
First of all, an ISR(interrupt service routine) is meant to be short and sweet. If the INT_RDA is flagged that means that there's a character waiting in the buffer that needs to be taken care of. The ISR will be entered, you will need to read the buffer with a getc(), if you will be expecting multiple characters then stuff it into an array, increment your variable that keeps track of the array and then get out of the ISR.
Once you have received, and stuffed, all of the characters that you need to handle then you can set a flag, in the ISR, and have that flag evaluated somewhere else, most likely in main(), and then manipulate the characters however you need to.
You have your ISR being entered with the first character and then it stays there until you try to read all three characters. Never cause the program to remain inside the ISR. Each time the PIC receives a character the ISR will be entered and you can do one getc() for each character. Simply increment your variable 'i' to place each character into the next slot.
There are numerous examples of this on the forums here but, hopefully, that will help get you headed in the right direction.
Ronald |
|
|
jmaurin
Joined: 29 Mar 2008 Posts: 26 Location: Ribeirão Preto, SP, Brasil
|
|
Posted: Thu Oct 09, 2008 4:11 pm |
|
|
I tried to use interrupts for RS232 but didn't work. This interrupt works only for hardware-rs232?
I'm using software-based RS232 (by ccs compiler).
This is my interrupt:
Code: | #int_rda
void isr_rda(void)
{
unsigned char charIn;
charIn = getc();
strcpy(temp,"Confirm received");
}
|
...
Code: | enable_interrupts(INT_RDA);
enable_interrupts(GLOBAL);
|
And in the main loop i always show 'temp' on the display, but is always blank (the default value), never 'Confirm received'
I'm not using hardware based because my pins aren't the same as hardware USART of PIC. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 09, 2008 4:22 pm |
|
|
Use pin B0 for the Rx pin (and pin B1 for Tx, for example). Then use the
External interrupt on pin B0 to signal the start of an incoming character.
Receive the byte in the INT_EXT interrupt service routine. Enable
INT_EXT interrupts instead of INT_RDA interrupts.
Here is a somewhat complicated example of a software UART. It puts
the incoming characters in a buffer.
http://www.ccsinfo.com/forum/viewtopic.php?t=36039&start=5 |
|
|
jmaurin
Joined: 29 Mar 2008 Posts: 26 Location: Ribeirão Preto, SP, Brasil
|
|
Posted: Thu Oct 09, 2008 4:34 pm |
|
|
the problem is that i'm already using these pins for other functions.
I need to use these:
#use rs232(baud=19200,parity=N,xmit=PIN_A3,rcv=PIN_A4,bits=8) |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 09, 2008 4:39 pm |
|
|
What PIC are you using ? |
|
|
jmaurin
Joined: 29 Mar 2008 Posts: 26 Location: Ribeirão Preto, SP, Brasil
|
|
Posted: Thu Oct 09, 2008 4:51 pm |
|
|
16F628A
I've tried the reverse way:
In the main loop, i always stay in gets(temp) and i've created an interrupt for timer1 (1ms) to call my display function....but didn't work too (i also have some small delays in display function).
The interrupts for RS232 data would be perfect (i think). |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 09, 2008 5:41 pm |
|
|
Pin A4 is the Timer0 input pin. It's possible that you could configure
Timer0 for an external clock input (with the H to L edge), and then
preload it with 0xFF. When it gets the falling edge of the start bit,
it will generate an INT_TIMER0 interrupt. You can read the software
UART byte in the Timer0 interrupt with a getc(). After getting the byte,
reload Timer0 with 0xFF again before you exit the interrupt routine.
I haven't tested this, but I think it might work.
It's best to design everything in advance and use the best pins for the
job, instead of having to invent work-arounds such as the one above. |
|
|
jmaurin
Joined: 29 Mar 2008 Posts: 26 Location: Ribeirão Preto, SP, Brasil
|
|
Posted: Thu Oct 09, 2008 7:27 pm |
|
|
Doesn't work :(
The problem is that i'm using portb to drive an LCD, wich i use do debug some information.
Is there any way to change just RB1 and RB2 in lcd420.c? If yes, i'll change to RA3 & RA4. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Oct 09, 2008 8:02 pm |
|
|
Quote: | Is there any way to change just RB1 and RB2 in lcd420.c? |
Use the Flex driver for that LCD, instead of lcd420.c. Then you can
specify whatever pins you want. It's in the code library:
http://www.ccsinfo.com/forum/viewtopic.php?t=28268 |
|
|
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Thu Oct 09, 2008 9:31 pm |
|
|
Personally, I prefer using hardware whenever its available, and try to design my circuits and software to allow for this. The UART pins on most 16 series PIC is a sore point for me - they are always on PORTB, which usually happens to be the only available port with fully bi-directional I/O. There is some relief if using 40 pin PICs, because then PORTD is available.
Quote: | Pin A4 is the Timer0 input pin. It's possible that you could configure
Timer0 for an external clock input (with the H to L edge), and then
preload it with 0xFF. When it gets the falling edge of the start bit,
it will generate an INT_TIMER0 interrupt |
PCM Programmer, this is like a genius-move! Its amazing how you can use peripherals to do things that they were never intended to do in the first place! I'm reasonably good with the PIC, but what I'm really trying to learn is these nifty workarounds - I guess once I've figured them out I can call myself a 'real' PIC programmer.
Rohit |
|
|
jmaurin
Joined: 29 Mar 2008 Posts: 26 Location: Ribeirão Preto, SP, Brasil
|
|
Posted: Fri Oct 10, 2008 5:53 pm |
|
|
yeah, PCM Programmer idea is great, but didn't worked for me...probably some mistake in my code...
Anyway, i changed ports on simulator and now it's working perfectly...i'll see if is possible to make some changes on the current hardware.
Thank you all! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 10, 2008 5:57 pm |
|
|
Simulator ? Then you could haved changed things to use any pin
connections you wanted, at any time. We didn't need to brainstorm to
supply work-arounds.
You should have told us you were using a simulator. |
|
|
jmaurin
Joined: 29 Mar 2008 Posts: 26 Location: Ribeirão Preto, SP, Brasil
|
|
Posted: Fri Oct 10, 2008 9:43 pm |
|
|
No, i have the hardware done....i'm using simulator just to test new software implementation. I ALREADY have hardware done. |
|
|
|