|
|
View previous topic :: View next topic |
Author |
Message |
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
CANBus ID filtering |
Posted: Thu Jan 18, 2007 12:14 pm |
|
|
Hello
I'm very new with CCS and I'm still testing it.
I ' m looking for Can Bus and 18F458.
I'm using this code:
//cut//
#define AA11 0x333
can_init();
printf("\r\nRunning...");
while(TRUE)
{
can_getd(rx_id, buffer, rx_len, rxstat);
if (rx_id == AA11) {
printf("\r\n ");
printf("##################################\r\n ");
printf("# TEST OK =>: %6.0w\r\n ",buffer);
}
}
//cut//
But I think There is a better way for filtering massage from a specific ID
can I have some example or help Please?
best wishes and Thanks
Luca
Last edited by ll.luca on Sat Jan 20, 2007 3:14 pm; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 19, 2007 1:24 pm |
|
|
You can use the hardware Acceptance Filters. These are setup with
the CCS function can_set_id(), which is in the CCS CAN driver files.
To learn more about Acceptance Filters, go to Google and use it to
search the Microchip website. Use this exact search string in Google:
"acceptance filters" site:microchip.com
From those results, you can find links to other helpful articles:
http://www.elecdesign.com/Articles/Print.cfm?AD=1&AD=1&ArticleID=10925 |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Fri Jan 19, 2007 2:54 pm |
|
|
Have a look at the can_init routine from the CAN drivers, can-18xxx8.c&h this routine gives you a pretty clear insight into how to set up the filters.
The eight can_set_id lines are very straight forward, just remember to use can_set_mode(CAN_OP_CONFIG) before and can_set_mode(CAN_OP_NORMAL) after.
Cheers Scott |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Sat Jan 20, 2007 3:12 pm |
|
|
Thanks for the reply,
But I need some more help please.
Can I write a Filter having different configuration like one in 18xxx8.h ?
Code: |
#define RX0FILTER0
#define RX0FILTER1
#define RX1FILTER2
#define RX1FILTER3
|
E. G.
#define MYFILTER 0x333
And about this code :
Code: |
can_set_mode(CAN_OP_CONFIG);
can_set_id(MYFILTER, 0,0); //0=CAN_USE_standard messages??
//can_set_id(FiLter, buffer_ID, extended_ID);
can_getd(rx_id, dato_filtrato, rx_len, rxstat);
can_set_mode(CAN_OP_NORMAL);
|
where Is the best place for it ?
(for example just after can_init() )
printf("# TEST OK =>: %6.0w\r\n ",dato_filtrato);
by this code I receive all data
but DO not filtering the massage having ID == 0x333
Am I on the wrong track?
Or there is something to save?
thank you very much
Luca |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Sat Jan 20, 2007 3:32 pm |
|
|
The code you want is something like this,
Do not alter the first argument to the can_set_id function, these are hardware locations. The second argument is what you should alter. The last argument is whether the ID is 27bit (one) or 11 bit (zero).
This, I think, (not compiled or tested) is what you want: call it immediately after can_init.
I've assumed standard 11bit IDs.
The 0x7FF forces a match of the first 11 (all) bits.
Code: |
void set_my_can_filters(void) {
can_set_mode(CAN_OP_CONFIG);
can_set_id(RX0MASK, 0x7FF, 0); //set mask 0
can_set_id(RX0FILTER0, 0x333, 0); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 0x333, 0); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x7FF, 0); //set mask 1
can_set_id(RX1FILTER2, 0x333, 0); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 0x333, 0); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 0x333, 0); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 0x333, 0); //set filter 3 of mask 1
can_set_mode(CAN_OP_NORMAL);
}
|
You should recieve no other IDs but I'd run a test first with a statement "if wrong ID print message".
Cheers Scott |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Sun Jan 21, 2007 7:04 am |
|
|
Thank you very much,
The code you gave me works very well.
I have a new idea:
In your opinion, to improve the pic performance,
is it possible to trigger the pic when it recives a particolar ID?
for example 0x333 :-) (like wake on ...)
Thank you for your help
Luca |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Sun Jan 21, 2007 8:04 am |
|
|
Hi,
I've never needed the performance gains and just use the can_kbhit routine, but this is roughly what you'd need.
These are the two RX interupts. As I've never done this, I'm pretty sure you need both because you don't know which buffer the data will arrive in.
You'll need to set up some global variables to put the data into, so your main program can use it.
Code: |
#INT_CANRX0
void isr_canrx0()
{
// DO YOUR READ
}
#INT_CANRX1
void isr_canrx1()
{
// COPY OF ABOVE
}
|
You'll also need to enable interupts in your main program
Code: |
enable_interrupts( INT_CANRX0 );
enable_interrupts( INT_CANRX1 );
enable_interrupts( GLOBAL );
|
Hope that points you in the right direction.
Cheers Scott |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Tue Jan 23, 2007 11:03 am |
|
|
many thanks for the help you gave me,
and for a very fast replay
But By now I have an other question,
I thing the problem is about
Code: | struct rx_stat rxstat;
stat - structure holding some information (such as which buffer
// recieved it, ext or standard, etc)
|
Do you have more information about it?
for example,
- standard 11bit IDs,
- buffer
and more
thanks
Luca |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Tue Jan 23, 2007 2:21 pm |
|
|
Sorry, not at "my" PC at the moment therefore I can't give you any examples or even get function names correct.!.
For these two interrupts (okay it's not the most most efficient, but close and will save you a lot of time) you want to use exactly the same CAN_GET_DATA routines you used before in the "main", allow the CCS drivers to interogate the registers. Assume that CAN_KBHIT has just returned true.
The cleaner solution would be to have these two interrupts calling a subroutine, to save you coping the code.
Again, I'll point out I've never needed to do this therefore, I can't garenttee that it works, but everything tells me it should.
Cheers Scott |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Wed Jan 24, 2007 9:24 am |
|
|
Hi
if I change my mind and I want to use Extended Id
Code: | void set_my_can_filters(void) {
can_set_mode(CAN_OP_CONFIG);
can_set_id(RX0MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID); //set mask 0
can_set_id(RX0FILTER0, 0x0074, 1); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 0x0074, 1); //set filter 1 of mask 0
can_set_id(RX1MASK, CAN_MASK_ACCEPT_ALL, CAN_USE_EXTENDED_ID); //set mask 1
can_set_id(RX1FILTER2, 0x0074, 1); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 0x0074, 1); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 0x0074, 1); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 0x0074, 1); //set filter 3 of mask 1
can_set_mode(CAN_OP_NORMAL);
}
|
BUT
That DON�T work!!
Thanks so much
P.S.
What do you think about 18f4580 and his include can-18F4580.c |
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Thu Jan 25, 2007 4:29 am |
|
|
In what way does it not work?
If you mean that you are recieving all IDs, it because you're mask is transparent.
If you change the two masks to 0x07FFFFFFF (I think that's 27 bits) then you should only recieve 0x0074,
Cheers Scott |
|
|
sjbaxter
Joined: 26 Jan 2006 Posts: 141 Location: Cheshire, UK
|
|
Posted: Thu Jan 25, 2007 7:24 am |
|
|
Should that read 29bits and not 27 ? _________________ Regards,
Simon. |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Thu Jan 25, 2007 7:56 am |
|
|
on HyperTerminal I receive:
Code: |
FAIL ON CAN_GETD(): NO MESSAGE IN BUFFER
# TEST OK =>: 0.00
|
It mean I don't receive nothing!
without the filter I receive all perfectly
where is the mistake?
I allow myself to send the code :
Code: |
//cut//
void set_my_can_filters(void) {
can_set_mode(CAN_OP_CONFIG);
can_set_id(RX0MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 0
can_set_id(RX0FILTER0, 0x0074, 1); //set filter 0 of mask 0
can_set_id(RX0FILTER1, 0x0074, 1); //set filter 1 of mask 0
can_set_id(RX1MASK, 0x07FFFFFFF, CAN_USE_EXTENDED_ID); //set mask 1
can_set_id(RX1FILTER2, 0x0074, 1); //set filter 0 of mask 1
can_set_id(RX1FILTER3, 0x0074, 1); //set filter 1 of mask 1
can_set_id(RX1FILTER4, 0x0074, 1); //set filter 2 of mask 1
can_set_id(RX1FILTER5, 0x0074, 1); //set filter 3 of mask 1
can_set_mode(CAN_OP_NORMAL);
}
void main() {
struct rx_stat rxstat; //<= IS This corrected?/////////////////
int32 rx_id;
float dato_filtrato;
int rx_len;
while(TRUE){
can_init();
set_my_can_filters();
can_getd(rx_id, &dato_filtrato, rx_len, rxstat);
printf("# TEST OK =>: %3.2f\r\n ",dato_filtrato);
}
}
|
I do not know how to say thanks for your aid
Luca
Last edited by ll.luca on Thu Jan 25, 2007 8:17 am; edited 2 times in total |
|
|
ll.luca
Joined: 18 Jan 2007 Posts: 10 Location: Tuscany
|
|
Posted: Thu Jan 25, 2007 8:04 am |
|
|
for be compete the tx side is:
Code: | //cut//
while(TRUE)
{
can_putd(0x0074, &ppp, 8, 1, 1, 0);
delay_ms(200);
can_putd(0x0222, &ccc, 8, 1, 1, 0);
delay_ms(600);
} |
|
|
|
ferrumvir
Joined: 01 Feb 2006 Posts: 64 Location: England
|
|
Posted: Thu Jan 25, 2007 8:39 am |
|
|
You don't want to be continually resetting the CAN call the CAN_Init and set_my_can_filters outside the eternal loop.
use CAN_KBHit to check for message in buffer before getting the buffer and printing the message.
Code: |
void main() {
// YOUR DECLARATIONS
can_init();
set_my_can_filters();
while(TRUE)
{
if( can_kbhit() )
{
can_getd(rx_id, &dato_filtrato, rx_len, rxstat);
printf("# TEST OK =>: %3.2f\r\n ",dato_filtrato);
}
}
}
|
Cheers Scott |
|
|
|
|
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
|