Интерфейс подключения к CAN шине на скорости 500 кбит/с. Кварц 20 МГц. Скорость передачи по RS232 115200.
Схема стандартная на базе
PIC18F2480
,
MCP2551
и
FT232RL
.
Плюс программа Bootloader - загрузчик, который загружается в PIC программатором, а сама программа CanBusInterface загружается этим загрузчиком. Можно самостоятельно менять код и в последующем загружать бутлойдером.
В коде нельзя изменять скорость передачи и прерывания для USART. Не будет работать Bootloader. Если вы все таки измените программу и контроллер не сможет перегрузится из программы, тогда нужно будет переводить его в boot путем подачи массы на ножку сброса 1 MCLRE.
CanBusInterface принимает все сообщения с шины CAN. Отправить сообщение в шину CAN можно предав 12 байт в Virtual Com Port, например:
{codecitation}
private void butSendMessage_Click_1(object sender, EventArgs e)
{
byte[] msg = { 0xfc, 0x00, 0x08, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,0x00};
serialPort1.Write(msg, 0, 12);
}
{/codecitation}
Чтобы контроллер ушел в boot нужно передать ему 12 байт 0хFF:
{codecitation}
private void butReset_Click(object sender, EventArgs e)
{
byte[] msg = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
serialPort1.Write(msg, 0, 12);
}
{/codecitation}
{codecitation}
#include< p18cxxx.h>
#include
#include
#include
#pragma config OSC=HS //20 MHz
#pragma config FCMEN=OFF
#pragma config IESO=OFF
#pragma config PWRT=OFF
#pragma config BOREN=OFF
#pragma config BORV=3
#pragma config WDT=OFF
#pragma config WDTPS=32768
#pragma config PBADEN=OFF
#pragma config LPT1OSC=OFF
#pragma config MCLRE=ON
#pragma config STVREN=ON
#pragma config LVP=OFF
#pragma config BBSIZ=1024
#pragma config XINST=OFF
#pragma config CP0=OFF
#pragma config CP1=OFF
#pragma config CPB=OFF
#pragma config CPD=OFF
#pragma config WRT0=OFF
#pragma config WRT1=OFF
#pragma config WRTC=OFF
#pragma config WRTB=OFF
#pragma config WRTD=OFF
#pragma config EBTR0=OFF
#pragma config EBTR1=OFF
//**********************************************************
#pragma udata
char BufferFromPC[13];
char cntLED;
#pragma code
void MyHighInt(void);
#pragma interrupt MyHighInt
#pragma code high_vector=0x08
void high_vector(void){
_asm GOTO MyHighInt _endasm
}
#pragma code
void MyLowInt(void);
#pragma interrupt MyLowInt
#pragma code low_vector=0x18
void low_vector(void){
_asm GOTO MyLowInt _endasm
}
#pragma code
void SetInterrupt(void);
void InitUsart(void);
void InitLedFlasher(void);
void InitCAN(unsigned char CanSpeed);
void ClearBuffer(char *buf,int len);
char ParsingReset(char *buf,int len);
char TxCan(char*);
void main(void)
{
ADCON1=0x0f;
InitLedFlasher();
InitUsart();
InitCAN(1);
SetInterrupt();
ClearBuffer(BufferFromPC,13);
while(1)
{
}
}
//Работаем с COM портом по High прерыванию
void MyHighInt(void)
{
if(PIR1bits.RCIF)
{
getsUSART ( BufferFromPC, 12);
if(ParsingReset(BufferFromPC,12)){ Reset(); }
TxCan(BufferFromPC);
ClearBuffer(BufferFromPC,13);
}
//Мигаем светодиодом
else if(PIR1bits.TMR1IF)
{
PIR1bits.TMR1IF=0;
if(cntLED==18)
{
PORTCbits.RC3^=1;
cntLED=0;
}
cntLED++;
TMR1H=0x00;
TMR1L=0x00;
}
}
//Принимаем сообщения CAN по LOW прерыванию
void MyLowInt(void)
{
if(PIR3bits.RXB0IF)
{
if(RXB0CONbits.RXFUL)
{
while(!TXSTAbits.TRMT);
putcUSART(RXB0SIDH);
while(!TXSTAbits.TRMT);
putcUSART(RXB0SIDL);
while(!TXSTAbits.TRMT);
putcUSART(RXB0DLC);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D0);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D1);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D2);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D3);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D4);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D5);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D6);
while(!TXSTAbits.TRMT);
putcUSART(RXB0D7);
RXB0CONbits.RXFUL=0;
}
}
}
char TxCan(char* msg)
{
if(TXB0CONbits.TXREQ){
return 1;
}
TXB0SIDH=msg[0];
TXB0SIDL=msg[1];
TXB0DLC =msg[2];
TXB0D0 =msg[3];
TXB0D1 =msg[4];
TXB0D2 =msg[5];
TXB0D3 =msg[6];
TXB0D4 =msg[7];
TXB0D5 =msg[8];
TXB0D6 =msg[9];
TXB0D7 =msg[10];
TXB0CONbits.TXPRI0=0;
TXB0CONbits.TXPRI1=0;
TXB0CONbits.TXREQ=1;
//Если сообщение прошло мигаем светодиодом
PORTCbits.RC3^=1;
return 0;
}
char ParsingReset(char *buf,int len)
{
int i;
char b;
for(i=0;i