ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Пятница
26 апреля
718244
derischev (07.12.2016 16:48, просмотров: 1134)
CAN на AT90CAN128 Получилось добиться работы с одним прибором в режиме listening. Прибор постоянно сыпет в линию данные. Принятые данные ожидаемые и корректные. Проблема в том, что не получается работать не в listening. Вытекающая проблема – не получается идентифицировать устройства, если их более одного. В регистрах CANIDT1 и CANIDT2 одно и тоже значение, не зависящее от сетевого адреса. В регистрах CANIDT3 и CANIDT4 бессистемный мусор. Приятно, что прерывание происходит именно от Mob0. Если не разрешать это прерывание, то ничего не работает. Прошу разъяснить определения. Чем отличается reception от frame buffer reception. Банальная эрудиция подсказывает, что в моём случае надо выбрать второй вариант. Но если разрешить прерывание Frame Buffer, зависает весь контроллер, вероятно по причине того, что контроллер постоянно входит в прерывание CAN. void CAN_Init(unsigned char set_brp, unsigned char set_prs, unsigned char set_phs1, unsigned char set_phs2) { CAN_CONTROLLER_RESET; //сброс общего регистра управления CAN CANBT1 = 0x06; CANBT2 = 0x0C; CANBT3 = 0x37; ResetAllMailbox(); //сброс регистров //Настройка MOB0=RX на прием CANPAGE = 0x00; //Выбор номера Mob - в данном случае Mob0 CANSTMOB = 0x00; //Очистка регистра состояния Mob CANCDMOB = 0xD8; CANIDT4 = 0x00; CANIDT3 = 0x00; CANIDT2 = 0x00; CANIDT1 = 0x00; CANIDM4 = 0x00; //Принудительный положительный результат сравнени CANIDM3 = 0x00; //Принудительный положительный результат сравнени CANIDM2 = 0x00; //Принудительный положительный результат сравнени CANIDM1 = 0x00; //Принудительный положительный результат сравнени CANGIE=0xB0; //Разрешение прерываний по приему, по передаче, по общим ошибкам, по ошибкам Mob CANEN2=0xff; //Разрешить все Mob CANEN1=0xff; CANIE2=0x01; //Разрешить прерывания только по Mob0 CANIE1=0x00; CANHPMOB=0x00; //Установка высшего приоритета для MOb0 CANGCON |= 0x0A; //Разрешить контроллер CAN + Listening Mode } #pragma vector=CANIT_vect __interrupt void can_isr(void) { unsigned char *ptr = &Buttons.Right.reg + 2; union { signed int si; struct { unsigned char lo, hi; }; }tmp; / // Place your code here //unsigned char i, flag; LED1R_On CANGIE &= (~(1<<ENRX)); // Запретить прерывание по приему flag = CANSIT2; // чтение регистра состояния прерываний(того где Mob0 и Mob1) //----------------------------------------------------- if(flag & (1<<0)) //Если прерывание по Mob0 { CANPAGE = 0<<4; //Выбор Mob0 for(i = 0; i < 8; i++) { *ptr++ = CANMSG; //Считать регистр данных сообщения 8 раз } CANPAGE = 0<<4; //Выбор Mob0 CANSTMOB &= ~(1<<RXOK); //сбросить влаг удачного завершения приема CANCDMOB = 0x80; //Разрешить прием } ptr = &Buttons.Right.reg + 2; tmp.lo = CANIDT1; tmp.hi = CANIDT2; if(tmp.si == 18467) { Src_NWA_r = tmp.si; Joystik_X = (signed char)(~*ptr++); Joystik_Y = (signed char)(~*ptr++); tmp.lo = CANIDT3; tmp.hi = CANIDT4; Trg_NWA_r = tmp.si; } if(flag & (1<<1)) //Если прерывание по Mob1 { CANPAGE = 1<<4; //Выбор Mob1 CANSTMOB &= (~(1<<TXOK)); //Сбросить бит удачного завершения передачи } //------------------------------------------------------ CANGIE |= (1<<ENRX); //Разрешить прерывание по приему }