CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Is this possible in PIC18F452

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

Is this possible in PIC18F452
PostPosted: Wed Oct 29, 2003 2:35 am     Reply with quote

Mabuhay!

I have an application that use the PIC18F452 as my slave device. The UART of this chip is used for my RS485 network and I use the #int_rda for data transfer to my PC host computer. The #int_tbe is used for PC host to send command to my devices..

In this device I added an RF ID reader (Series 2000 Micro Reader) from texas instrument. This micro reader has a tx & rx at ttl level and I decided to use an interrupt to capture the data from the micro reader to my device unfortunately, the PIC18F452 has only one UART. BTW, the micro reader is use for one-way communication only.. the micro reader transmit data to the PIC18F452.

What other options that I have in using interrupt for my micro reader? I try software UART but this is not a good solution coz it will poll my main loop.

Would it be possible if I am going to use the interrupt on change of PIC18F452 on PortB?

I need your comments or tips on this.... a sample code snippet will also help.

Thnx
Ttelmah
Guest







Re: Is this possible in PIC18F452
PostPosted: Wed Oct 29, 2003 3:12 am     Reply with quote

ritchie wrote:
Mabuhay!

I have an application that use the PIC18F452 as my slave device. The UART of this chip is used for my RS485 network and I use the #int_rda for data transfer to my PC host computer. The #int_tbe is used for PC host to send command to my devices..

In this device I added an RF ID reader (Series 2000 Micro Reader) from texas instrument. This micro reader has a tx & rx at ttl level and I decided to use an interrupt to capture the data from the micro reader to my device unfortunately, the PIC18F452 has only one UART. BTW, the micro reader is use for one-way communication only.. the micro reader transmit data to the PIC18F452.

What other options that I have in using interrupt for my micro reader? I try software UART but this is not a good solution coz it will poll my main loop.

Would it be possible if I am going to use the interrupt on change of PIC18F452 on PortB?

I need your comments or tips on this.... a sample code snippet will also help.

Thnx

Have a look back through the archives. This has been covered here before.
Basically, you can use either interrupt on change (but this then places limits on what you can do with the other pins on this part of the port), or the simple INT0 (RB0) pin (probably the preferred route). Then you set the code to interrupt on the edge that corresponds to the beginning of the 'start' bit for the incoming serial data, and setup the 'software' UART, to use the same pin for receive, with the correct polarity (you may need to use 'invert' if this is a TTL serial stream).
Then in the interrupt code for INT0, you call the software receive routine.
The sequence then is that the interrupt handler gets called as soon as the active edge of the start bit is seen, and then calls the software serial handler, to receive the character. The downside, is that the code will sit in the interrupt handler for the entire 'byte time' of the incoming character, so you have to be careful about the effects on other parts of your code.

Best Wishes
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

PostPosted: Wed Oct 29, 2003 5:15 am     Reply with quote

Mabuhay!

I have no other option but to use the portB3 of PIC18F452 as my interrupt on change for the RF ID reader.

I review the data sheet of pic18f452 and it said that it can be configured for interrupt on change but the CCS compiler only support the #int_rb from b4 to b7.

I also search this forum and it discuss mostly on #int_rb0 and #int_ext.

Anybody in this forum would like to share some sample code.

Thnx
Ttelmah
Guest







PostPosted: Wed Oct 29, 2003 6:02 am     Reply with quote

ritchie wrote:
Mabuhay!

I have no other option but to use the portB3 of PIC18F452 as my interrupt on change for the RF ID reader.

I review the data sheet of pic18f452 and it said that it can be configured for interrupt on change but the CCS compiler only support the #int_rb from b4 to b7.

I also search this forum and it discuss mostly on #int_rb0 and #int_ext.

Anybody in this forum would like to share some sample code.

Thnx

The 18F452, only supports interrupt on change on the high four bits. The data sheet makes this clear (paragraph 8.8).
You cannot interrupt on pin RB3. There is a 'fault' in the data sheet in this regard. If you look at the sheet, it shows seperate interrupts on RB0 to RB3 (Table 9.3), but if you look at the configuration register description, it only gives definitions for RB0 to RB2 (registers 8.2). The pin diagrams also only show interrupts on the low three pins.
Using the interrupt, will work happily with the same code, on INT_EXT1, or INT_EXT2, but RB3, has no ability to be used this way.
For the higher bits (RB4 to RB7), the problem with interrupt on change (which is why it is not the preferred route for this application), is that the interrupt will occur whenever any of the bits change, and hence it really restricts the use of the other pins in this part of the port, or adds a lot of overhead.
I'm afraid you are going to have to reconsider how the circuit itself is wired.

Best Wishes
tut
Guest







PostPosted: Wed Oct 29, 2003 6:43 am     Reply with quote

You might be able to use capture mode of the CCP module. RB3 is listed in the data sheet as the alternate CCP2 pin for the 18F452. You could set it to capture and interrupt on the transition and either proceed from that point with the software uart, or use the CCP module to capture the pulse widths and decode them yourself. You would have to alternate between positive and negative edge detection. See the CCP module info in the data sheet.

Good luck,
Tut
Ttelmah
Guest







PostPosted: Wed Oct 29, 2003 7:16 am     Reply with quote

tut wrote:
You might be able to use capture mode of the CCP module. RB3 is listed in the data sheet as the alternate CCP2 pin for the 18F452. You could set it to capture and interrupt on the transition and either proceed from that point with the software uart, or use the CCP module to capture the pulse widths and decode them yourself. You would have to alternate between positive and negative edge detection. See the CCP module info in the data sheet.

Good luck,
Tut

Yes, using the edge to start things like this, might be possible. Using the 'edge detection', to decode the byte though, wouldn't work easily with normal RS232 (might work if you used some form of machester encoded data). Remember you are only 'guaranteed', one edge on the start bit, and the return to 'idle' level somewhere. If this happened on the first bit, there would be no more edges for the entire character, and the code could sit for ever. You could do it using a second timer, programmed to interrupt at bit times, once started, wait for half a bit time after the first edge, and then sample the data every bit time for the byte length, or use the second timer as a 'timeout' counter in the middle of the stop bit, and work out the bit pattern from the transition times.

Best Wishes
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Wed Oct 29, 2003 7:17 am     Reply with quote

You could also use a external UART that is either SPI or I2C.
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

PostPosted: Wed Oct 29, 2003 6:46 pm     Reply with quote

Ttelmah wrote:
The 18F452, only supports interrupt on change on the high four bits. The data sheet makes this clear (paragraph 8.8).
You cannot interrupt on pin RB3. There is a 'fault' in the data sheet in this regard. If you look at the sheet, it shows seperate interrupts on RB0 to RB3 (Table 9.3), but if you look at the configuration register description, it only gives definitions for RB0 to RB2 (registers 8.2). The pin diagrams also only show interrupts on the low three pins.
Using the interrupt, will work happily with the same code, on INT_EXT1, or INT_EXT2, but RB3, has no ability to be used this way.
For the higher bits (RB4 to RB7), the problem with interrupt on change (which is why it is not the preferred route for this application), is that the interrupt will occur whenever any of the bits change, and hence it really restricts the use of the other pins in this part of the port, or adds a lot of overhead.
I'm afraid you are going to have to reconsider how the circuit itself is wired.
Best Wishes



Mabuhay!

I review my schematics and I found out that the tx & rx pin of the RF ID micro reader is coonected to portB2 --> tx while portB3 --> rx of RF ID micro reader.

I decided to reverse the pin configuration such that I can use the #int_ext2 for reception. Anyway, the PIC18F452 will only receive data from the micro reader not transmit.

I guess this would provide a solution on my part to use the external interrupt rather than using the interrupt on change.

BTW, do I need to enable pullups on portB? does this affect if my enable pullups with #int_ext2?

Can u share some sample codes in using #int_ext2? a link will also help

tenkyu
Ttelmah
Guest







PostPosted: Thu Oct 30, 2003 3:22 am     Reply with quote

ritchie wrote:
Ttelmah wrote:
The 18F452, only supports interrupt on change on the high four bits. The data sheet makes this clear (paragraph 8.8).
You cannot interrupt on pin RB3. There is a 'fault' in the data sheet in this regard. If you look at the sheet, it shows seperate interrupts on RB0 to RB3 (Table 9.3), but if you look at the configuration register description, it only gives definitions for RB0 to RB2 (registers 8.2). The pin diagrams also only show interrupts on the low three pins.
Using the interrupt, will work happily with the same code, on INT_EXT1, or INT_EXT2, but RB3, has no ability to be used this way.
For the higher bits (RB4 to RB7), the problem with interrupt on change (which is why it is not the preferred route for this application), is that the interrupt will occur whenever any of the bits change, and hence it really restricts the use of the other pins in this part of the port, or adds a lot of overhead.
I'm afraid you are going to have to reconsider how the circuit itself is wired.
Best Wishes



Mabuhay!

I review my schematics and I found out that the tx & rx pin of the RF ID micro reader is coonected to portB2 --> tx while portB3 --> rx of RF ID micro reader.

I decided to reverse the pin configuration such that I can use the #int_ext2 for reception. Anyway, the PIC18F452 will only receive data from the micro reader not transmit.

I guess this would provide a solution on my part to use the external interrupt rather than using the interrupt on change.

BTW, do I need to enable pullups on portB? does this affect if my enable pullups with #int_ext2?

Can u share some sample codes in using #int_ext2? a link will also help

tenkyu

Whether you need pull-ups of not, is dependant on the output of the units attached (data sheet...).
The code is identical to the examples you have allready found in the archives, except you substitute INT_EXT2, for INT_EXT (both in setup, and in use).
You also need to look at the polarity of the data being returned. Remember that 'normal' RS232, undergoes inversion in the line drivers. According to whether the data is the normal RS232 'source', or a 5v version of the normally transmitted data, you will have to set the triggering edge to either be on a 'fall', or a 'rise' (you can also check this with a scope/meter on the line from the remote unit. If the line 'idles' high, then you want to detect the falling edge, while if it idles low, you need to detect the rising edge. This also controls whether you need to use the 'invert' keyword in the RS232 setup. If the line idles high, this is not needed, while if it idles low it is.

Best Wishes
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

PostPosted: Thu Oct 30, 2003 4:29 am     Reply with quote

Ttelmah wrote:
Whether you need pull-ups of not, is dependant on the output of the units attached (data sheet...).
The code is identical to the examples you have allready found in the archives, except you substitute INT_EXT2, for INT_EXT (both in setup, and in use).
You also need to look at the polarity of the data being returned. Remember that 'normal' RS232, undergoes inversion in the line drivers. According to whether the data is the normal RS232 'source', or a 5v version of the normally transmitted data, you will have to set the triggering edge to either be on a 'fall', or a 'rise' (you can also check this with a scope/meter on the line from the remote unit. If the line 'idles' high, then you want to detect the falling edge, while if it idles low, you need to detect the rising edge. This also controls whether you need to use the 'invert' keyword in the RS232 setup. If the line idles high, this is not needed, while if it idles low it is.

Best Wishes



With the suggestion u shared, I am still going to use the #use rs232 routines of the CCS compiler but my Rx of PIC18F452 will get the data from #int_ext2 interrupt. Am I right?

Before I enable the external interrupt I have to set ext_int_edge() function either L-to_H or H-to_L depending on the RF ID micro reader configuration.

The RF ID micro reader does not have a max232 level translator rather it outputs data at 5V TTL level but I still need to check the polarity of the signal.

With this, Is it possible that I will not use the #use rs232() but rather directly capture the signal from the #int_ext2 by defining a RxBuffer[]?

I need your comments.

Thnx
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

PostPosted: Thu Oct 30, 2003 4:58 am     Reply with quote

Ttelmah wrote:
Whether you need pull-ups of not, is dependant on the output of the units attached (data sheet...).
The code is identical to the examples you have allready found in the archives, except you substitute INT_EXT2, for INT_EXT (both in setup, and in use).
You also need to look at the polarity of the data being returned. Remember that 'normal' RS232, undergoes inversion in the line drivers. According to whether the data is the normal RS232 'source', or a 5v version of the normally transmitted data, you will have to set the triggering edge to either be on a 'fall', or a 'rise' (you can also check this with a scope/meter on the line from the remote unit. If the line 'idles' high, then you want to detect the falling edge, while if it idles low, you need to detect the rising edge. This also controls whether you need to use the 'invert' keyword in the RS232 setup. If the line idles high, this is not needed, while if it idles low it is.

Best Wishes


I alredi measure using my scope and I found out that the output of the RF ID micro reader is 5v TTL level with positive polarity and falling-edge.
Ttelmah
Guest







PostPosted: Thu Oct 30, 2003 6:52 am     Reply with quote

ritchie wrote:
Ttelmah wrote:
Whether you need pull-ups of not, is dependant on the output of the units attached (data sheet...).
The code is identical to the examples you have allready found in the archives, except you substitute INT_EXT2, for INT_EXT (both in setup, and in use).
You also need to look at the polarity of the data being returned. Remember that 'normal' RS232, undergoes inversion in the line drivers. According to whether the data is the normal RS232 'source', or a 5v version of the normally transmitted data, you will have to set the triggering edge to either be on a 'fall', or a 'rise' (you can also check this with a scope/meter on the line from the remote unit. If the line 'idles' high, then you want to detect the falling edge, while if it idles low, you need to detect the rising edge. This also controls whether you need to use the 'invert' keyword in the RS232 setup. If the line idles high, this is not needed, while if it idles low it is.

Best Wishes


I alredi measure using my scope and I found out that the output of the RF ID micro reader is 5v TTL level with positive polarity and falling-edge.


Ok. The code then basically becomes:
//setup soft RS232, to use the required bit as the input.
//I have assumed a stream name of 'SOFTRS'. So something like:
#USE RS232(BAUD=19200,RCV=PIN_B2,PARITY=N,BITS=8,STREAM=SOFTRS)
#BIT INTEDGE2=0xFF1.4
#BIT INT2IF=0xFF0.1

int8 rcv_chr;
short char_available=false;
//Add more buffering if required.

#INT_EXT2
void seen_edge(void) {
rcv_chr=fgetc(SOFTRS);
char_available=true;
}

void main() {
int val;
//Other setups here as needed.

//Set for falling edge (start bit)
INTEDGE2=0;
//Note that changing the edge may result in the interrupt being set
//Since this will result in a hang (if no serial data is arriving)
//I must ensure the interrupt is clear before enabling.
INT2IF=0;
ENABLE_INTERRUPTS(INT_EXT2);
ENABLE_INTERRUPTS(GLOBAL);
while (true) {
//Obviously you can do anything you want while waiting...
if (char_available) {
val=rcv_chr;
char_available=false;
}
}
}
ritchie



Joined: 13 Sep 2003
Posts: 87

View user's profile Send private message

PostPosted: Thu Oct 30, 2003 11:05 pm     Reply with quote

Mabuhay!

Thank u for the comments, tips and support.

BTW, I've use this code for my #INT_EXT2 but the data receive is corrupted.


#use rs232(baud=9600,parity=N,rcv=PIN_B2,bits=8,stream=RFidCom)

unsigned char INTCON2;
#locate INTCON2=0x0FF1

struct {
unsigned char RBIP:1;
unsigned char TMR0IP:1;
unsigned char INTEDG2:1;
unsigned char INTEDG1:1;
unsigned char INTEDG0:1;
unsigned char RBPU:1;
} INTCON2bits ;
#locate INTCON2bits=0x0FF1

unsigned char INTCON3;
#locate INTCON3=0x0FF0

struct {
unsigned char INT1IF:1;
unsigned char INT2IF:1;
unsigned char INT1IE:1;
unsigned char INT2IE:1;
unsigned char INT1IP:1;
unsigned char INT2IP:1;
} INTCON3bits ;
#locate INTCON3bits=0x0FF0

void init_chip() { // Initialize the MCU Chip

lcd_init(); // LCD should be initialized first

INTCON2bits.INTEDG2 = 0; // set external interrupt on falling edge
INTCON3bits.INT2IF = 0; // clear external interrupt before enabling

enable_interrupts(int_ext2); // external interrupt 2
enable_interrupts(GLOBAL); // Global interrupt
}

main()
{

nulrfbuffer(); // put NULL at RF buffer array
nulrfrawcode(); // put NULL at RF raw code array

init_chip(); // Initialize the MCU Chip

lcd_gotoxy(1,1);
printf(lcd_putc,"HTI-200R");

glRfIdBufferAvailable = 1; // Rx buffer is empty
glRfIdBufferDataReady = 0; // RF data buffer is empty

while (TRUE)
{
if (glRfIdBufferDataReady)
{
lcd_gotoxy(1,1);
printf(lcd_putc,"%x%x%x%x%x%x%x%x",rfbuffer[0],rfbuffer[1],
rfbuffer[2],rfbuffer[3],rfbuffer[4],rfbuffer[5],rfbuffer[6],rfbuffer[7]);
lcd_gotoxy(1,2);
printf(lcd_putc,"%x%x%x%x",rfbuffer[8],rfbuffer[9],
rfbuffer[10],rfbuffer[11]);
delay_ms(3000);
rf_out = 0;
glRfIdBufferAvailable = 1; // RF data buffer is empty
glRfIdBufferDataReady = 0; // RF data buffer is empty
}
}
}


But I change the configuration using as shown below:
#BIT INTEDGE2=0xFF1.4
#BIT INT2IF=0xFF0.1

INTEDGE2=0;
INT2IF=0;
enable_interrupts(int_ext2); // external interrupt 2
enable_interrupts(GLOBAL); // Global interrupt

Can anybody in this community could explain why? the first one using STRUCT will not do any good. I try the code from Ttelmah for INTCON2 and INTCON3 register initialization... and it work?

Thnx
Ttelmah
Guest







PostPosted: Fri Oct 31, 2003 3:45 am     Reply with quote

ritchie wrote:
Mabuhay!

Thank u for the comments, tips and support.

BTW, I've use this code for my #INT_EXT2 but the data receive is corrupted.


#use rs232(baud=9600,parity=N,rcv=PIN_B2,bits=8,stream=RFidCom)

unsigned char INTCON2;
#locate INTCON2=0x0FF1

struct {
unsigned char RBIP:1;
unsigned char TMR0IP:1;
unsigned char INTEDG2:1;
unsigned char INTEDG1:1;
unsigned char INTEDG0:1;
unsigned char RBPU:1;
} INTCON2bits ;
#locate INTCON2bits=0x0FF1
<snip>



But I change the configuration using as shown below:
#BIT INTEDGE2=0xFF1.4
#BIT INT2IF=0xFF0.1

INTEDGE2=0;
INT2IF=0;
enable_interrupts(int_ext2); // external interrupt 2
enable_interrupts(GLOBAL); // Global interrupt

Can anybody in this community could explain why? the first one using STRUCT will not do any good. I try the code from Ttelmah for INTCON2 and INTCON3 register initialization... and it work?

Thnx

The reason is simple. Bits are allocated when using bit fields in a char, from the LSB first, and uses the bits in sequence. So your structure, sets RBIP to be bit 0, and INTEDG2, to be bit 2. You need two 'dummy' entries for the two unused bits to make everything line up properly. So, something like:
struct {
unsigned char RBIP:1;
unsigned char NU1:1;
unsigned char TMR0IP:1;
unsigned char NU2:1;
unsigned char INTEDG2:1;
unsigned char INTEDG1:1;
unsigned char INTEDG0:1;
unsigned char RBPU:1;
} INTCON2bits ;

and obviously the same 'fillers' for any other unused bits. The compiler has no idea at all that the register has bits that are not used...

Best Wishes
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
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