Установил прерывание на входящие пакеты по CAN.
-------------------------------
CODE
// CAN interrupt service routine
interrupt [CAN_IT] void can_isr(void)
{
// Place your code here
CANGIE = 0;
if((CANSIT2 & 1)!=0) // MOB0 сработал?
{
// for(i=0;i<8;i++) data[i]=CANMSG; // Прочитать сообщение целиком
can_in=1;
}
toggleLED1_on(); delay_ms(50); toggleLED1_off(); // Визуальный тест
}
interrupt [CAN_IT] void can_isr(void)
{
// Place your code here
CANGIE = 0;
if((CANSIT2 & 1)!=0) // MOB0 сработал?
{
// for(i=0;i<8;i++) data[i]=CANMSG; // Прочитать сообщение целиком
can_in=1;
}
toggleLED1_on(); delay_ms(50); toggleLED1_off(); // Визуальный тест
}
-----------------------------------------
В теле основной программы в while вставил
CODE
/****************************************************************/
/* CAN initialization */
/****************************************************************/
void can_init (unsigned char BT_1,unsigned char BT_2,unsigned char BT_3)
{
unsigned char i=0;
unsigned char j=0;
//reset CAN interface
CANGCON |= (1<<SWRES);
//reset all MObs
for (i=0; i<15; i++)
{
CANPAGE = (i<<4); //select MOb
CANCDMOB = 0; //disable MOb
CANSTMOB = 0; //clear status
CANIDT1 = 0; //clear ID
CANIDT2 = 0;
CANIDT3 = 0;
CANIDT4 = 0;
CANIDM1 = 0; //clear mask
CANIDM2 = 0;
CANIDM3 = 0;
CANIDM4 = 0;
for (j=0; j<8; j++)
CANMSG = 0; //clear data
}
// set CAN -> baudrate
// bit timing -> datasheet 264 (check table)
// 250Kbps 8MHz cpu-clk
CANBT1 = BT_1; // 0x00;
CANBT2 = BT_2; // 0x0C;
CANBT3 = BT_3; // 0x60;
//start CAN interface
//CANGCON = (1<<ENASTB);
// clear CAN interrupt registers
CANGIE = 0xA0; // none interrupts
CANIE1 = 0; // none interrupts on MObs
CANIE2 = 0x03;
CANEN2 = 0x03; // 0x03 = 2 mail // 0x01 = 1 mail
CANSIT1 = 0;
CANSIT2 = 0;
//start CAN interface
CANGCON = (1<<ENASTB);
//wait until module ready
while (!(CANGSTA & (1<<ENFG)));
}
/* CAN initialization */
/****************************************************************/
void can_init (unsigned char BT_1,unsigned char BT_2,unsigned char BT_3)
{
unsigned char i=0;
unsigned char j=0;
//reset CAN interface
CANGCON |= (1<<SWRES);
//reset all MObs
for (i=0; i<15; i++)
{
CANPAGE = (i<<4); //select MOb
CANCDMOB = 0; //disable MOb
CANSTMOB = 0; //clear status
CANIDT1 = 0; //clear ID
CANIDT2 = 0;
CANIDT3 = 0;
CANIDT4 = 0;
CANIDM1 = 0; //clear mask
CANIDM2 = 0;
CANIDM3 = 0;
CANIDM4 = 0;
for (j=0; j<8; j++)
CANMSG = 0; //clear data
}
// set CAN -> baudrate
// bit timing -> datasheet 264 (check table)
// 250Kbps 8MHz cpu-clk
CANBT1 = BT_1; // 0x00;
CANBT2 = BT_2; // 0x0C;
CANBT3 = BT_3; // 0x60;
//start CAN interface
//CANGCON = (1<<ENASTB);
// clear CAN interrupt registers
CANGIE = 0xA0; // none interrupts
CANIE1 = 0; // none interrupts on MObs
CANIE2 = 0x03;
CANEN2 = 0x03; // 0x03 = 2 mail // 0x01 = 1 mail
CANSIT1 = 0;
CANSIT2 = 0;
//start CAN interface
CANGCON = (1<<ENASTB);
//wait until module ready
while (!(CANGSTA & (1<<ENFG)));
}
--------------------------------------------
CODE
void my_can_rx_unlim_time_11 (unsigned long my_id, unsigned char MyIDfiltr_4, unsigned char MyIDfiltr_3,
unsigned char MyIDfiltr_2, unsigned char MyIDfiltr_1){
unsigned char i;
CANHPMOB=0;
//select MOb0
CANPAGE = 0x00; //select MOb0
//clear MOb flags
//CANSTMOB = 0;
my_id *= 2; // умножение на 2
CANIDT1 = (unsigned char) (my_id>>4);
CANIDT2 = (unsigned char) (my_id<<4);
// set mask in order to receive only the message with the ID
CANIDM4 = MyIDfiltr_4; //
CANIDM3 = MyIDfiltr_3; //
CANIDM2 = MyIDfiltr_2; //
CANIDM1 = MyIDfiltr_1; //
// enable extended ID
//CANIDM4 |= (1<<IDEMSK);
// enable reception and
CANCDMOB=(1<<CONMOB1) | (0<<IDE);
// wait until reception is complete
// while(!(CANSTMOB&(1<<RXOK)));
// reset flag
// CANSTMOB &= ~(1<<RXOK);
va=CANIDT1;
vb=CANIDT2;
return;
}
// Поехали..
main{
while(1){
// № 1 ################################################################################
#######################
// Здесь принимаем только один единственный ID 0x321.
my_can_rx_unlim_time_11(0x321,248,255,255,255);
// Если сработало прерывание CAN Rx
if((CANSTMOB&(1<<RXOK))){
// wait until reception is complete
//while(!(CANSTMOB&(1<<RXOK)));
// reset flag
CANSTMOB &= ~(1<<RXOK);
}
can_in=0; // Снимаем флаг прерывания.
CANGIE = 0xA0; // Разрешаем прерывание CAN Rx.
}
//################################################################################
#########################
}
}
unsigned char MyIDfiltr_2, unsigned char MyIDfiltr_1){
unsigned char i;
CANHPMOB=0;
//select MOb0
CANPAGE = 0x00; //select MOb0
//clear MOb flags
//CANSTMOB = 0;
my_id *= 2; // умножение на 2
CANIDT1 = (unsigned char) (my_id>>4);
CANIDT2 = (unsigned char) (my_id<<4);
// set mask in order to receive only the message with the ID
CANIDM4 = MyIDfiltr_4; //
CANIDM3 = MyIDfiltr_3; //
CANIDM2 = MyIDfiltr_2; //
CANIDM1 = MyIDfiltr_1; //
// enable extended ID
//CANIDM4 |= (1<<IDEMSK);
// enable reception and
CANCDMOB=(1<<CONMOB1) | (0<<IDE);
// wait until reception is complete
// while(!(CANSTMOB&(1<<RXOK)));
// reset flag
// CANSTMOB &= ~(1<<RXOK);
va=CANIDT1;
vb=CANIDT2;
return;
}
// Поехали..
main{
while(1){
// № 1 ################################################################################
#######################
// Здесь принимаем только один единственный ID 0x321.
my_can_rx_unlim_time_11(0x321,248,255,255,255);
// Если сработало прерывание CAN Rx
if((CANSTMOB&(1<<RXOK))){
// wait until reception is complete
//while(!(CANSTMOB&(1<<RXOK)));
// reset flag
CANSTMOB &= ~(1<<RXOK);
}
can_in=0; // Снимаем флаг прерывания.
CANGIE = 0xA0; // Разрешаем прерывание CAN Rx.
}
//################################################################################
#########################
}
}
-------------------------------------------------------
Вот это все работает, но если я функции while последовательно вставлю еще одну проверку на другой пакет:
CODE
// № 2 ################################################################################
#######################
// Здесь принимаем только один единственный ID 0x325.
my_can_rx_unlim_time_11(0x325,248,255,255,255);
// Если сработало прерывание CAN Rx
if((CANSTMOB&(1<<RXOK))){
// wait until reception is complete
//while(!(CANSTMOB&(1<<RXOK)));
// reset flag
CANSTMOB &= ~(1<<RXOK);
}
can_in=0; // Снимаем флаг прерывания.
CANGIE = 0xA0; // Разрешаем прерывание CAN Rx.
}
//################################################################################
#########################
#######################
// Здесь принимаем только один единственный ID 0x325.
my_can_rx_unlim_time_11(0x325,248,255,255,255);
// Если сработало прерывание CAN Rx
if((CANSTMOB&(1<<RXOK))){
// wait until reception is complete
//while(!(CANSTMOB&(1<<RXOK)));
// reset flag
CANSTMOB &= ~(1<<RXOK);
}
can_in=0; // Снимаем флаг прерывания.
CANGIE = 0xA0; // Разрешаем прерывание CAN Rx.
}
//################################################################################
#########################
То прерывание срабатывает только на этот последний ID Под номером 2, а код под номером 1 не срабатывает на прерывание. Я уже запарился, не могу проверить (выловить) разный ID.