|
|
View previous topic :: View next topic |
Author |
Message |
aldina
Joined: 09 Oct 2009 Posts: 26
|
CAN BUS beginning |
Posted: Thu Jul 25, 2019 11:04 am |
|
|
Hello everyone,
I'm a beginner with CAN BUS communication. I'm using a PIC18F2480 and MCP2551 to know the tachograph vehicle speed.
By default the speed switch receives message TC01 which contains vehicle speed represented as a 16 bit (bytes 7-8).
So I need to know the speed (km/h) and use it to command (High or LOW) outputs C0 and C1.
Can you give me your opinion about my code:
Code: |
#include <18F2480.h>
#fuses HS,NOPROTECT,NOLVP,NOWDT,NOPUT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#include <can-18F4580.c>
#define SET_SPEED_ID_TC01 0xFE6C //ask for ID info from CAN port
#int_timer2
void isr_timer2(void)
{
delay_ms(1000); //keep a running timer that increments every milli-second
}
void main()
{
//recv message
struct rx_stat rxstat;
int32 rx_id;
int in_data[16];
int rx_len;
int i;
int16 speed = 0;
int16 speed_set_point = 0x1051;
//setup_timer_2(T2_DIV_BY_4,79,16); //setup up timer2 to interrupt every 1ms if using 20Mhz clock
can_init();
enable_interrupts(INT_TIMER2); //enable timer2 interrupt
enable_interrupts(GLOBAL); //enable all interrupts (else timer2 wont happen)
while(TRUE)
{
if ( can_kbhit() ) //if data is waiting in buffer...
{
if(can_getd(rx_id, &in_data[0], rx_len, rxstat))
{ //...then get data from buffer
//printf("\r\nGOT: BUFF=%U ID=%LU LEN=%U OVF=%U ", rxstat.buffer, rx_id, rx_len, rxstat.err_ovfl);
//printf("FILT=%U RTR=%U EXT=%U INV=%U", rxstat.filthit, rxstat.rtr, rxstat.ext, rxstat.inv);
//printf("\r\n DATA = ");
for (i=0;i<rx_len;i++)
{
printf("%X ",in_data[i]);
}
//printf("\r\n");
// ********** Filter CAN messages: TC01 ********** //
if(rx_id == SET_SPEED_ID_TC01) // PGN 65132
{
//printf("\r\nTC01 Tachograph speed\r\n");
//speed max: 250.996 km/h ---> 0xFFFF ---> 65535 (Dec)
//speed_set_point: 16km/h ---> 0x1051 ---> 4177 (Dec)
speed = getchar();
if(speed < speed_set_point)
{
output_high(pin_C0);
output_high(pin_C1);
}
}
}
else
{
printf("\r\nFAIL on GETD\r\n");
}
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 25, 2019 12:50 pm |
|
|
Quote: | #int_timer2
void isr_timer2(void)
{
delay_ms(1000); //keep a running timer that increments every milli-second
} |
Don't put delays in your timer isr. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19535
|
|
Posted: Thu Jul 25, 2019 12:52 pm |
|
|
The delay_ms in the timer interrupt will hang the chip for ever.
Interrupt handler should always be as fast as possible. Delays in
interrupt handlers are a 'no no' in general (except possibly for a very
few instruction cycles in a device driver). I'm not sure what you actually
think this is going to achieve.
You have remmed out the timer setup, presumably having found the
chip hangs if you set it up.
A 1mSec setup, would be:
setup_timer_2(T2_DIV_BY_4,49,5);
5*50*4 = 1000.
The clock feeding the oscillator is Fosc/4, so this gives 1000Hz.
I doubt if your chip will be able to synchronise with any normal CAN
bus from a 4MHz clock. There is no sign of the clock settings needed
for the CAN peripheral. CAN requires you to configure all the timings.
Use the timing calculator on the Microchip site or one of the third party
ones to generate all the settings needed. |
|
|
|
|
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
|