|
Обмен данными по шине CAN
Программные примеры для микроконтроллеров PIC - MPLab IDE
(Обмен данными по шине CAN)
Рассмотренная ниже программа каждую секунду выдает в шину CAN восемь
последовательных чисел в диапазоне от 0 до 255. В то же время выполняется
"прослушивание" шины CAN на предмет принятых данных с их последующей передачей
на ПК через USART. В программе используется внешний файл canbus.с
с библиотечными функциями CAN от компании CCS.
Примечание: при компиляции проекта требуется добавить в проект следующие библиотеки: "canbus.h".
canbus.c
void can_init(void) {
can_set_mode(CAN_OP_CONFIG);
can_set_baud();
RXB0CON=0;
RXB0CON.rxm=CAN_RX_VALID;
RXB0CON.rxb0dben=CAN_USE_RX_DOUBLE_BUFFER;
RXB1CON=RXB0CON;
CIOCON.endrhi=CAN_ENABLE_DRIVE_HIGH;
CIOCON.cancap=CAN_ENABLE_CAN_CAPTURE;
can_set_id(&RXM0EIDL, CAN_MASK_ACCEPT_ALL, 0);
can_set_id(&RXF0EIDL, 0, 0);
can_set_id(&RXF1EIDL, 0, 0);
can_set_id(&RXM1EIDL, CAN_MASK_ACCEPT_ALL, 1);
can_set_id(&RXF2EIDL, 0, 1);
can_set_id(&RXF3EIDL, 0, 1);
can_set_id(&RXF4EIDL, 0, 1);
can_set_id(&RXF5EIDL, 0, 1);
set_tris_b((*0xF93 & 0xFB ) | 0x08);
can_set_mode(CAN_OP_NORMAL);
}
void can_set_baud(void) {
BRGCON1.brp=CAN_BRG_PRESCALAR;
BRGCON1.sjw=CAN_BRG_SYNCH_JUMP_WIDTH;
BRGCON2.prseg=CAN_BRG_PROPAGATION_TIME;
BRGCON2.seg1ph=CAN_BRG_PHASE_SEGMENT_1;
BRGCON2.sam=CAN_BRG_SAM;
BRGCON2.seg2phts=CAN_BRG_SEG_2_PHASE_TS;
BRGCON3.seg2ph=CAN_BRG_PHASE_SEGMENT_2;
BRGCON3.wakfil=CAN_BRG_WAKE_FILTER;
}
void can_set_mode(CAN_OP_MODE mode) {
CANCON.reqop=mode;
while( (CANSTAT.opmode) != mode );
}
void can_set_id(int* addr, long int id, int1 ext) {
int *ptr;
ptr=addr;
if (ext) {
*ptr=make8(id,0); //0:7
ptr--;
*ptr=make8(id,1); //8:15
ptr--;
*ptr=make8((int32)id,2) & 0x03;
*ptr|=(make8((int32)id,2) << 3) & 0xE0;
*ptr|=0x08;
ptr--;
*ptr=((make8((int32)id,2) >> 5) & 0x07 );
*ptr|=((make8((int32)id,3) << 3) & 0xF8);
}
else {
*ptr=0;
ptr--;
*ptr=0;
ptr--;
*ptr=(make8(id,0) << 5) & 0xE0;
ptr--;
*ptr=(make8(id,0) >> 3) & 0x1F;
*ptr|=(make8(id,1) << 5) & 0xE0;
}
}
long int can_get_id(int * addr, int1 ext) {
long int ret;
int * ptr;
ret=0;
ptr=addr;
if (ext) {
ret=*ptr;
ptr--;
ret|=((long int)*ptr << 8);
ptr--;
ret|=((long int)*ptr & 0x03) << 16;
ret|=((long int)*ptr & 0xE0) << 18;
ptr--;
ret|=((long int)*ptr << 21);
}
else {
ptr-=2;
ret=((long int)*ptr & 0xE0) >> 5;
ptr--;
ret|=((long int)*ptr << 3);
}
return(ret);
}
int can_putd(long int id, int * data, int len, int priority, int1 ext, int1 rtr) {
int i;
int * txd0;
int ret;
txd0=&TXRXBaD0;
if (!TXB0CON.txreq) {
CANCON.win=CAN_WIN_TX0;
ret=0;
}
else if (!TXB1CON.txreq) {
CANCON.win=CAN_WIN_TX1;
ret=1;
}
else if (!TXB2CON.txreq) {
CANCON.win=CAN_WIN_TX2;
ret=2;
}
else return(0xFF);
TXBaCON.txpri=priority;
can_set_id(&TXRXBaEIDL, id, ext);
TXBaDLC=len;
TXBaDLC.rtr=rtr;
for (i=0; i
|
Примечание: при компиляции проекта требуется добавить в проект следующие библиотеки: "18F458.h", "canbus.c".
CAN.c
#use delay(clock=10000000)
#fuses HS, BROWNOUT, WRT, NOWDT, WDT1
#use fast_io(B)
#use rs232(baud=19200,parity=N,xmit=PIN_C6,rcv=PIN_C7)
int ms;
struct rx_stat rxstat;
int32 rx_id;
int in_data[8];
int rx_len;
int out_data[8];
long int tx_id = 24;
char tx_rtr = 0;
char tx_ext = 0;
int tx_len = 8;
int tx_pri = 3;
#int_timer2
void isr_timer2(void)
{
ms++;
}
void main()
{
int i, j;
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_CLOCK_DIV_2);
setup_psp(PSP_DISABLED);
setup_spi(FALSE);
setup_wdt(WDT_OFF);
setup_timer_0(RTCC_INTERNAL);
setup_timer_1(T1_disabled);
setup_timer_3(T3_INTERNAL | T3_DIV_BY_1);
setup_ccp1(CCP_PWM);
setup_ccp2(CCP_PWM);
setup_comparator(FALSE);
for (i=0; i<8; i++)
{
out_data[i] = 0;
in_data[i] =0;
}
setup_timer_2(T2_DIV_BY_4, 79, 16);
can_init();
enable_interrupts(INT_TIMER2);
enable_interrupts(global);
while(1)
{
if (can_kbhit())
{
if (can_getd(rx_id, in_data, rx_len, rxstat))
{
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 500))
{
ms = 0;
for (i=0; i<8; i++) out_data[i] = j++;
i = can_putd(tx_id, out_data, tx_len, tx_pri, tx_ext, tx_rtr);
if (i != 0xFF)
{
printf("\r\nPut %U: ID=%LU Len=%U ", i, tx_id, tx_len);
printf("Pri=%U Ext=%U RTR=%U\r\n Data = ",
tx_pri, tx_ext, tx_rtr);
for (i=0; i 1000)
{
printf("\r\n\nCOMSTAT = %02X", COMSTATUS);
printf("\r\nTXB0CON = %02X", TXB0CONR);
printf("\r\nTXB1CON = %02X", TXB1CONR);
printf("\r\nTXB2CON = %02X", TXB2CONR);
printf("\r\nRXERRCNT = %U", RXERRCNT);
printf("\r\nTXERRCNT = %U", TXERRCNT);
ms = 0;
}
}
}
}
|
Файлы проекта можно скачать здесь:
|
|
|