Д_М 0 29 июня, 2016 Опубликовано 29 июня, 2016 (изменено) · Жалоба Приветствую! Устройство на базе AT90CAN128 новое и нет 100% уверенности, что в нём отсутствуют аппаратные ошибки. При тщательном изучении аппаратных ошибок не выявлено. Имеется заведомо работающий датчик с CAN, который постоянно сыпет в линию CAN своё значение. Имеется конвертер, который получает то, что кидает датчик и тупо передаёт по RS232. Цифры осмысленные, расшифровке поддаются. Коечная цель сделать так, чтобы устройство на базе AT90CAN128 воспринимало то, что кидает в линию датчик. На текущий момент получается так, что устройство на базе AT90CAN128 "подвешивает" датчик после инициализации CAN контроллера в устройстве на базе AT90CAN128. Да так подвешивает, что датчик возобновляет нормальную работу только после передёргивания питания. Специально сделал задержку инициализации CAN на 10 секунд. Когда на линии CAN сидят три устройства - датчик, конвертер, контроллер вижу, как сыпятся посылки от датчика. Прошло 10 секунд, произошла инициализация датчика, посылки прекратились. Методом исключения было установлено, что контроллер вешает датчик, когда в инициализации делается только сброс контроллера, задание скорости, включение CAN контроллера. Если в процедуре инициализации убрать задание скорости, но оставить включение 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; */ CANBT1 = 0x0E; CANBT2 = 0x04; CANBT3 = 0x13; CANGCON |= 0x02; //Разрешить контроллер CAN } Значение CANBT взяты из мануала AT90CAN128. Пробовал оба значения для данного кварца. Результат один. Конечно можно предположить, что датчик неправильный. Но ведь другое CAN устройство с этим датчиком подружилось. Пробовал делать передачу на моём контроллере, используя вот этот пример http://forum.cxem.net/index.php?app=core&a...ttach_id=137917 Смущает, что светодиод, подключенный на линию CAN горит ровным свечением, без мерцания. Когда я цеплял тот же светодиод на линию CAN, когда был подключен датчик и конвертер, наблюдалось характерное мерцание светодиода. Заранее благодарен за советы! Изменено 29 июня, 2016 пользователем IgorKossak [codebox] для длинного кода. [code]-для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 29 июня, 2016 Опубликовано 29 июня, 2016 · Жалоба Если в процедуре инициализации убрать задание скорости, но оставить включение CAN контроллера, то датчик не подвешивается. Так вы либо скорость неправильно задаете, в итоге CAN128 может портить посылки кода выдает на линию например ошибки... либо проблемы со схемой (с драйвtром CAN) может быть и с шиной проблемы - шина не должна быть звездой и с короткими стабами и терминаторами 120 ом по краям... Да и еще проверить не перевернута ли шина... Можно попробовать в listen only режиме пакеты принимать... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 29 июня, 2016 Опубликовано 29 июня, 2016 · Жалоба Так вы либо скорость неправильно задаете, в итоге CAN128 может портить посылки кода выдает на линию например ошибки... либо проблемы со схемой (с драйвtром CAN) может быть и с шиной проблемы - шина не должна быть звездой и с короткими стабами и терминаторами 120 ом по краям... Да и еще проверить не перевернута ли шина... Можно попробовать в listen only режиме пакеты принимать... Суммарная длина линии CAN не более метра. На такой длине звезда не может быть источником проблем. Установлен один терминатор 120 Ом. Без него не работало бы. Интереса ради пробовал менять полярность на контроллере. Если неправильно, то он не мешает жить другим. Если я правильно понял, то сама по себе инициализация CAN контроллера не должна вызывать влияния на линию? Однако на практике не совсем так. Попробовал включить Чтение. В этом режиме контроллер не завешивает датчик. Даже срабатывает обработчик прерывания. Чувствует наличие / отсутствие CAN. Пробовал менять полярность. При иной полярности нет прерывания CAN. Пробовал оба значения CANBT, предлагаемые мануалом, для данного кварца. В обоих случаях значение регистра прерывания CAN CANGIT одно и тоже 0xB8. Bit 3 – SERG: Stuff Error General 1 - stuff error interrupt: detection of more than 5 consecutive bits with the same polarity. То есть временные параметры заданы неверно. А это самая нудная часть CAN. Есть ли какие стандартные значения? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavel-pervomaysk 0 29 июня, 2016 Опубликовано 29 июня, 2016 · Жалоба Была задача сделать мост UART 500k <-> CAN 125 kBps. Долго извращался я с такой-же проблемой, но нужно внимательно "курнуть" даташит на английском. Русская версия мне была понятной но сути в ней не описано. В итоге сделал так: Настраиваем фильтр на каждый приемный MAILBOX, выбираем RX/TX Mailboxes, полная инициализация CAN модуля. Прием только по прерыванию, приняли CAN сообщение, обработали и в UART его. Аналогичто все обратно. Инициализация модуля. Это пример для M16M1, отличие только в количестве Mailbox 0...5, у CAN32/64/128 их 15 штук. ;----------------------; can_init: ; Initialization CAN module ;---- CANGCON ---------; ; ABRQ OVRQ TTC SYNTTC LISTEN TEST ENA/STB SWRES ldi tmp,0b00000010 ; 02 - enabled! sts CANGCON,tmp ; Can General Control Register ;---- CANGIT-----------; ; CANIT BOFFIT OVRTIM BXOK SERG CERG FERG AERG ldi tmp,0b00000000 ; andi tmp,0x7F ; 7-th bit read only! sts CANGIT,tmp ; Can General Interrupt Register ;---- CANGIE ----------; ; ENIT ENBOFF ENRX ENTX ENERR ENBX ENERG ENOVRT ldi tmp,0b10100000 ; TX & RX interrupt! было 1011 0000 sts CANGIE,tmp ; Can General Interrupt Enable Register ;------------------------------------------------------------------------------- ; Interrupt Enable & Disable for Mob 5...0 ;Mob 5,4,3,2,1,0 ; IEMOB5 IEMOB4 IEMOB3 IEMOB2 IEMOB1 IEMOB0 ldi tmp,0b100000 ; Mob5,0 in interrupt mode! andi tmp,0x3F ; sts CANIE2,tmp ; Can Enable Interrupt MOb Register sts CANIE1,zero ; Can Enable Interrupt MOb Register ;-------------------------------------------------------------------------------- ; Read only! ; - OVRG - TXBSY RXBSY ENFG BOFF ERRP ;ldi tmp,0b00000000 ; ;andi tmp,0x5F ; bits 7,5 not used! ;sts CANGSTA,tmp ; Can General Status Register ; Enable or Disable Mob 5...0 ; ; Read only! 0 - Disabled; 1 - Enabled; ; bit provides the availability of the MOb. ;Mob 5,4,3,2,1,0 ; ENMOB5 ENMOB4 ENMOB3 ENMOB2 ENMOB1 ENMOB0; CANEN2 ;lds tmp,CANEN2 ; Can Enable MOb Register ; CAN Status Interrupt MOb Registers ; read only! ; - - SIT5 SIT4 SIT3 SIT2 SIT1 SIT0 ;lds tmp,CANSIT2 ; rcall baud_500k ; CAN speed baudrate 500k! ;----------------------; ; CAN Timer Clock Period: 0,500 us ; TPRSC7 TPRSC6 TPRSC5 TPRSC4 TPRSC3 TPRSC2 TRPSC1 TPRSC0 ; 16 mhz timer timer ovf interrypt! ; (255 = (255*32.7ms)) = 8338ms ldi tmp,30 ; 30 make ~ 1s timer interrupt sts CANTCON,tmp ; Can Timer Control Register ;----------------------; ; CANTIM7 CANTIM6 CANTIM5 CANTIM4 CANTIM3 CANTIM2 CANTIM1 CANTIM0 ldi tmp,0b00000000 ; sts CANTIML,tmp ; Can Bit Timer RegisterL ; CANTIM15 CANTIM14 CANTIM13 CANTIM12 CANTIM11 CANTIM10 CANTIM9 CANTIM8 ldi tmp,0b00000000 ; sts CANTIMH,tmp ; Can Bit Timer RegisterH ;----------------------; ; TIMTTC7 TIMTTC6 TIMTTC5 TIMTTC4 TIMTTC3 TIMTTC2 TIMTTC1 TIMTTC0 ldi tmp,0b00000000 ; sts CANTTCL,tmp ; Can TCC Timer RegisterL ; TIMTTC15 TIMTTC14 TIMTTC13 TIMTTC12 TIMTTC11 TIMTTC10 TIMTTC9 TIMTTC8 ldi tmp,0b00000000 ; sts CANTTCH,tmp ; Can TCC Timer RegisterH ;----------------------; ; TEC7 TEC6 TEC5 TEC4 TEC3 TEC2 TEC1 TEC0 ldi tmp,0b00000000 ; sts CANTEC,tmp ; Can Transmit Error Counter Register ; REC7 REC6 REC5 REC4 REC3 REC2 REC1 REC0 ldi tmp,0b00000000 ; sts CANREC,tmp ; Can Receive Error Counter Register ;----------------------; ; HPMOB3 HPMOB2 HPMOB1 HPMOB0 CGP3 CGP2 CGP1 CGP0 ldi tmp,0b01010000 ; MOB5 - RX sts CANHPMOB,tmp ; Can Highest Priority MOb Register ;----------------------; ; статус временной ометки CAN 0 ... 65535 ; TIMSTM7 TIMSTM6 TIMSTM5 TIMSTM4 TIMSTM3 TIMSTM2 TIMSTM1 TIMSTM0 ldi tmp,0x00 ; sts CANSTML,tmp ; Can Time Stamp RegisterL ; TIMSTM15 TIMSTM14 TIMSTM13 TIMSTM12 TIMSTM11 TIMSTM10 TIMSTM9 TIMSTM8 ldi tmp,0x00 ; sts CANSTMH,tmp ; Can Time Stamp RegisterH ;----------------------; rcall clear_all_mobs ; Clear all mobs buffer! clr flags ; ret ; Настройка скоростей, я использую 16МГц кварц. ;----------------------; ; CAN Bit Timing Registers 1,2,3 ; CAN 8 bit 50.000 Kbps 16 MHz ; Sample Point at 75% baud_50k: ldi tmp,0x26 ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x0C ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x37 ; sts CANBT3,tmp ; Can Bit Timming Register ret ;----------------------; ; CAN 8 bit 75.000 Kbps 16 MHz ; Sample Point at 75% baud_75k: ldi tmp,0x1C ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x0C ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x37 ; sts CANBT3,tmp ; Can Bit Timming Register ret ;----------------------; ; CAN 8 bit 83.333 Kbps 16 MHz ( 16 0C 37 old ) ; Sample Point at xx.x% baud_83k: ldi tmp,0x16 ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x0C ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x37 ; sts CANBT3,tmp ; Can Bit Timming Register ret ;----------------------; ; CAN 8 bit 100 Kbps 16 MHz ; Sample Point at 75% baud_100k: ; ldi tmp,0x12 ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x0C ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x37 ; sts CANBT3,tmp ; Can Bit Timming Register ret ;----------------------; ; CAN 8 bit 125 Kbps 16 MHz ; Sample Point at 75% baud_125k: ; ldi tmp,0x0E ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x0C ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x37 ; sts CANBT3,tmp ; Can Bit Timming Register ret ; ;----------------------; ; CAN 8 bit 200 Kbps 16 MHz ; Sample Point at 75% baud_200k: ; ldi tmp,0x08 ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x0C ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x37 ; sts CANBT3,tmp ; Can Bit Timming Register ret ; ;----------------------; ; CAN 8 bit 250 Kbps 16 MHz ; Sample Point at 75% baud_250k: ; ldi tmp,0x0E ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x04 ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x13 ; sts CANBT3,tmp ; Can Bit Timming Register ret ; ;----------------------; ; CAN 8 bit 500 Kbps 16 MHz ; Sample Point at 75% baud_500k: ; ldi tmp,0x02 ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x0C ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x37 ; sts CANBT3,tmp ; Can Bit Timming Register ret ; ;----------------------; ; CAN 8 bit 1000 Kbps 16 MHz ; Sample Point at 75% baud_1m: ; ldi tmp,0x02 ; sts CANBT1,tmp ; Can Bit Timming Register ldi tmp,0x04 ; sts CANBT2,tmp ; Can Bit Timming Register ldi tmp,0x13 ; sts CANBT3,tmp ; Can Bit Timming Register ret ; ;----------------------; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
KRS 1 30 июня, 2016 Опубликовано 30 июня, 2016 · Жалоба Если я правильно понял, то сама по себе инициализация CAN контроллера не должна вызывать влияния на линию? Как это не должна? если CAN проиничен не в listen only mode, скорость задана - CAN обязан выдавать на линию сигналы АСК в случае приема корректного фрейма или ошибки... (настройки фильтров и мейлбокосов на это не влияют!) А это самая нудная часть CAN. Есть ли какие стандартные значения? Там - все просто, надо только внимательно прочитать как формируются биты! И учесть что в регистрах хранится значение на 1 меньше... Например здесь все хорошо расписано http://www.nxp.com/files/microcontrollers/...note/AN1798.pdf Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 4 декабря, 2016 Опубликовано 4 декабря, 2016 (изменено) · Жалоба Приветствую! Получилось добиться работы с одним прибором в режиме listening. Прибор постоянно сыпет в линию данные. Принятые данные ожидаемые и корректные. Проблема в том, что не получается работать не в listening. Вытекающая проблема – не получается идентифицировать устройства, если их более одного. В регистрах CANIDT1 и CANIDT2 одно и тоже значение, не зависящее от сетевого адреса. В регистрах CANIDT3 и CANIDT4 бессистемный мусор. Приятно, что прерывание происходит именно от Mob0. Если не разрешать это прерывание, то ничего не работает. Прошу разъяснить определения. Чем отличается reception от frame buffer reception. Банальная эрудиция подсказывает, что в моём случае надо выбрать второй вариант. Но если разрешить прерывание Frame Buffer, зависает весь контроллер. 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); //Разрешить прерывание по приему } Во вложении полный файл. Заранее благодарен! CAN.rar Изменено 5 декабря, 2016 пользователем IgorKossak [codebox] для длинного кода. [code]-для короткого!!! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavel-pervomaysk 0 7 декабря, 2016 Опубликовано 7 декабря, 2016 · Жалоба CAN контроллер у AT90CAN очень таки неплох, если с ним разобраться... 15 маилбоксов. Внимательно почитать надо про CANPAGE. Рулится все через него. Очень хотелось бы чтобы было как в нормальных процессорах типа NEC, своя отдельная область с произвольным доступом, но нет тут такого. Я настравиваю 1 на передачу Следующими настраиваю фильтр для каждого принимающего маилбокса! Прием работает по прерыванию. Сработало прерывание, проверил забрал данные с маилбокса. ;----------------------; can_handler: ; CAN Transfer Complete or Error push tmp ; in tmp,SREG ; push tmp ; out TCNT0,zero ; Clean TCNT0 lds temp,CANPAGE ; Store CANPAGE ;----------------------; lds tmp,CANSIT2 ; MOB1 RX interrupt! sbrc tmp,SIT5 ; skip if SIT5 =0 rcall _crxi ; SIT5?1{MOB5_interrupt} ;----------------------; sts CANPAGE,temp ; Restore CANPAGE pop tmp ; out SREG,tmp ; pop tmp ; reti ; return from interrupt ;----------------------; _crxi: ; CAN RX MOB in interrupt mode! inc mode ; sbi canlp,crxl ; Can RX Led ON; ldi tmp,mob5 ; Select MOB5 sts _rmob,tmp ; sts CANPAGE,tmp ; SET MOB5 sts CANSTMOB,zero ; clear status register rcall read_mobx ; READ MOB5, save in RAM! lds tmp,CANCDMOB ; Load register ori tmp,RXmes ; SET RX flag! sts CANCDMOB,tmp ; save register ;cbi canlp,crxl ; Can RX Led OFF; ret ; return ;----------------------; ;--- Read MOB 8 bytes ; ; save in RAM (_CRXA) ; read_mobx: ; read data from MOB area and save in RAM push tmp ; Save tmp in STACK push loop2 ; Save Loop2 in STACK push yl ; Save YL in STACK push yh ; Save YH in STACK ;----------------------; clr loop2 ; ldi yl,low (_CRXA) ; Load address ldi yh,high(_CRXA) ; can_rx Array space in RAM ldi loop,8 ; data bytes length ;----------------------; rmc: ; Read_mob_cycle <----| lds tmp,_rmob ; | or loop2,tmp ; Mob number (0...5) | sts CANPAGE,loop2 ; 0...7 | lds tmp,CANMSG ; tmp=CANMSG with pointer loop2 | st y+,tmp ; save in SDRAM with pointer Y tmp | inc loop2 ; loop2 = +1 | dec loop ; loop=-1 | brne rmc ; -----------------------------------| ;----------------------; pop yh ; pop yl ; pop loop2 ; pop tmp ; ret ; return ;----------------------; ;----------------------; Что можно сделать на этом проце не напрягаясь: Принимаит 14 различных "отфильтрованных" ID в прерывании, обрабатывать их, отвечать на них. Больше 16 ID стречается только в приборных панелях автомобилей 32-64. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 8 декабря, 2016 Опубликовано 8 декабря, 2016 · Жалоба Спасибо, что ответили! Для начала мне хотелось бы разобраться с технологией CAN. В моём случае имеющиеся у меня устройства постоянно сыпят посылки в линию. Независимо от того, надо оно кому-то, или нет. В этом и заключается главное отличие CAN от других интерфейсов, где всё строится по принципу запрос-ответ. Из этого вытекает вопрос - какой надо выбрать режим при инициализации MailBox? – 00 - disable. – 01 - enable transmission. – 10 - enable reception. – 11 - enable frame buffer reception И далее инициализация CAN. Какие разрешить прерывания? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavel-pervomaysk 0 9 декабря, 2016 Опубликовано 9 декабря, 2016 · Жалоба Настроили CAN модуль. 19.11.2 CAN MOb Control and DLC Register - CANCDMOB CONMOB1 CONMOB0 RPLV IDE DLC3 DLC2 DLC1 DLC0 Bits 7;6; 00 - disable; 01 - enable transmission. Отправляем подготовленный маилбокс ;ID11 ldi tmp,0x48 ; High nibble (4-11bit);(5-29bit); low nibble&7(DLC) ;ID29 ldi tmp,0x58 ; High nibble (4-11bit);(5-29bit); low nibble&7(DLC) и ждем пока установится TXOK в регистре CANSTMOB 10 - перезапись при приеме сообщений маилбокса 11 - приняли сообщение, и пока его не обработаем, оно там будет сидеть. Посоветую еще купить CAN анализатор, очень пригодится, если планируешь работать с шиной. Ато читаю что сообщения друг другу посылаются хаотично - уши заворачиваются.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 18 декабря, 2016 Опубликовано 18 декабря, 2016 (изменено) · Жалоба Пересмотрел все примеры программ, которые мне удалось найти. Кое-что "надёргал" и повставлял в мою программу. А результат прежний - работает только в listening. Ниже инициализация и обработчик прерывания. void CAN_Init(unsigned char set_brp, unsigned char set_prs, unsigned char set_phs1, unsigned char set_phs2) { unsigned char num_channel, num_data; TxCAN_DDR = 0; RxCAN_DDR = 0; TxCAN = 1; CANGCON |= MSK_CANGCON_GRES; // reset CAN CANGIT = CANGIT; // reset all flags // reset all mailboxes for(num_channel = 0; num_channel < 15; num_channel++) { CANPAGE = num_channel << 4; CANCDMOB = CH_DISABLE; CANSTMOB = 0; CANIDT1 = 0; CANIDT2 = 0; CANIDT3 = 0; CANIDT4 = 0; CANIDM1 = 0; CANIDM2 = 0; CANIDM3 = 0; CANIDM4 = 0; for(num_data = 0; num_data < 8; num_data++) CANMSG = 0; } // setup bit timing at 250k with 16 MHz crystal CANBT1 = 0x06; CANBT2 = 0x0C; CANBT3 = 0x37; //CANGCON |= MSK_CANGCON_ENA; // Разрешить контроллер CAN CANGCON |= 0x0A; // Разрешить контроллер CAN + Listening Mode // Channel 0 init CANPAGE = (0 << 4); // CHNB=0x00; select channel 0 CANSTMOB = 0x00; // reset channel status CANCDMOB = CH_DISABLE; // reset control and dlc register CANIDT4 = 0x00; CANIDT3 = 0x00; CANIDT2 = 0x00; CANIDT1 = 0x00; CANIDM4 = 0x00; // Принудительный положительный результат сравнени CANIDM3 = 0x00; // Принудительный положительный результат сравнени CANIDM2 = 0x00; // Принудительный положительный результат сравнени CANIDM1 = 0x00; // Принудительный положительный результат сравнени // Channel 0 configuration CANIDT4 &=~0x04; // clear bit rtr in CANIDT4. CANCDMOB |= DLC_MAX; // Reception 8 bytes.*/ CANCDMOB |= CH_RxENA; // Reception enabled without buffer. CANCDMOB |= CH_ID29BIT; // CAN standard rev 2.0 B (identifiers length = 29 bits). CANEN2 |= (1 << 0); // channel 0 enable CANIE2 = 1; // channel 0 interrupt enable CANGIE = ((1<<ENRX)|(1<<ENIT)); // Can_Rx & IT enable //CANGIE = 0x84;// CAN General Interrupt Enable Register Bit 2 – ENBX: Enable Frame Buffer Interrupt } #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; //CANGIE &= (~(1<<ENRX)); // Запретить прерывание по приему Buttons.Left.reg = CANGSTA; Buttons.Right.reg = CANGIT; flag = CANSIT2; // чтение регистра состояния прерываний(того где Mob0 и Mob1) if(flag & (1<<0)) //Если прерывание по Mob0 { CANPAGE = 0<<4; //Выбор Mob0 for(i = 0; i < 8; i++) { *ptr++ = CANMSG; //Считать регистр данных сообщения 8 раз } CANSTMOB &= ~(1<<RXOK); //сбросить влаг удачного завершения приема } ptr = &Buttons.Right.reg + 2; tmp.lo = CANIDT1; tmp.hi = CANIDT2; if(tmp.si == 18466) { Joystik_X = (signed char)(~*ptr++); Joystik_Y = (signed char)(~*ptr++); } if(tmp.si == 18467) { Src_NWA_r = (signed char)(~*ptr++); Trg_NWA_r = (signed char)(~*ptr++); } CANPAGE = (0 << 4); CANSTMOB=0x00; // reset channel 0 status CANEN2 |= (1 << 0); // channel 0 enable CANCDMOB = DLC_MAX; // receive 8 bytes CANCDMOB |= CH_RxENA; // Reception enabled without buffer. CANCDMOB |= CH_ID29BIT; // CAN standard rev 2.0 B (identifiers length = 29 bits). CANGIT = CANGIT; // reset all flags //CANGIE |= (1<<ENRX); //Разрешить прерывание по приему } Непонятно, почему программа одинаково работает как в 11 бит, так и в 29 бит. Как мне представляется, то если этот параметр задан некорректно, то работать не должно. У меня задача с тремя неизвестными. Сомнительных код, сомнительных контроллер, сомнительный датчик. Может быть посоветуете какой-то копеечный датчик, например автомобильный, который можно использовать, как тестовый. Если есть заведомо проверенный софт, под какой-то конкретный датчик, не откажите в любезности. Если у Вас есть контроллер и датчик, которые стыковались друг с другом, я у Вас их приобрёл бы. Изменено 18 декабря, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavel-pervomaysk 0 22 декабря, 2016 Опубликовано 22 декабря, 2016 · Жалоба Приниматься будут все сообщения 11 и 29 бит. Мы можем их фильтровать только. Флаг IDE проверили, далее решили как считать MID. Для начала начинать надо передавать сообщения корректно. Ловить вторым устройством. Может банально неправильно Baud настроен, я с 250к не работал, такое только в BMW и газелях встречается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 23 декабря, 2016 Опубликовано 23 декабря, 2016 · Жалоба Здравствуйте! Спасибо за ответ! Не понял на счет MID - что это за флаг, или регистр? В документации не нашёл. Интереса ради пробовал менять Baud rate на 200. Не работает даже в Listening. Попробовал сделать на 250, с другими битовыми параметрами, согласно документации. Работает, но тоже только в Listening. Протестировал CAN драйвер, реализовав программно импульсы на выходе TxCAN. Установлен терминатор 100 Ом, другой нагрузки нет. Там, где два графика, измерения относительно Gnd, соответственно H и L. Там, где один график, между H и L. Везде 1 Вольт на клетку. Вот и получается, что амплитуда каждого канала 1 вольт. Дифференциальная амплитуда 2 вольта. Это нормально? На мой взгляд маловато. Из графика следует, что дифференциальное напряжение (между H и L) в рецессивном состоянии должно быть меньше 0,5 вольта. А на графике видно, что оно явно больше 0,5 Вольта. Про датчик BMW даже и не спрашиваю. Наверняка он стоит баснословных денег. А датчик на Газель, определённо доступен по цене. Можете сказать, что это за датчик? Либо посоветовать какой-то другой недорогой датчик, с которым Вы имели дело. Если Вы ещё этот датчик подключали к AT90CAN128 и всё подружилось, то буду премного благодарен за код. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavel-pervomaysk 0 24 декабря, 2016 Опубликовано 24 декабря, 2016 (изменено) · Жалоба Датчиков с CAN я не встречал. Датчики обрабатывает зачастую МК. Для HIGH SPEED CAN напряжение между CANH CANL 2-2.5V это нормально. Настраиваем прием Mailbox 14 для сообщений с адресом 777H CANGCON=2 ; CANGSTA=0 ; CANGIT=0 ; CANGIE=0b00000000 ; ;------------------------------------------------------------------------------- ; Interrupt Enable & Disable for Mob 14...0 ;Mob 14,13,12,11,10,9,8; - IEMOB14 IEMOB13 IEMOB12 IEMOB11 IEMOB10 IEMOB9 IEMOB8 ldi tmp,0b01000000 ; Mailbox 14 - interrupt mode! sts CANIE1,tmp ; Can Enable Interrupt MOb Register BAUD 250 000 ; CAN 8 bit 250 Kbps 16 MHz ; Sample Point at 75% CANBT1=0x0E CANBT2=4 CANBT3=13H ;------------------------- CANTCON=0 CANTIML=0 CANTIMH=0 CANTTCL=0 CANTTCH=0 CANTEC=0 CANREC=0 CANHPMOB=0 CANSTMOB=0 CANSTML=0 CANSTMH=0 Инициализируем: CANPAGE=E0H; MailBox 14; CANMESSAGE 0-7; E0 - High nibble Mailbox index; E0-CANMSG[0]; E1-CANMSG[1]; E2-CANMSG[2]; E3-CANMSG[3]; E4-CANMSG[4]; E5-CANMSG[5]; E6-CANMSG[6]; E7-CANMSG[7]; Устанавливаем MID: Message ID. Читаем даташит. CANIDT4 CANIDT3 CANIDT2 CANIDT1 = (777H << 21); Устанавливаем маску (фильтр диапазона принимаемых сообщений): Опять читаем даташит. CANIDM4 CANIDM3 CANIDM2 CANIDM1 = (7FFH << 21); Фильтр указанного ID Full filtering: to accept only ID = 0x317 in part A. - ID MSK = 111 1111 1111 b - ID TAG = 011 0001 0111 b Диапазон работы фильтра Partiel filtering: to accept ID from 0x310 up to 0x317 in part A. - ID MSK = 111 1111 1000 b - ID TAG = 011 0001 0xxx b Без фильтра No filtering: to accept all ID’s from 0x000 up to 0x7FF in part A. - ID MSK = 000 0000 0000 b - ID TAG = xxx xxxx xxxx b Затем обрабатываем прерывание Смотрим lds tmp,CANSIT1 проверяем бит 6, если он, достаем сообщение, обрабатываем, отвечаем. Все. Получаем сообщение CANPAGE=E0H; MailBox 14; CAN0=CANMSG[0]; CANPAGE=E1H; MailBox 14; CAN1=CANMSG[1]; и так до 8го байта. Изменено 25 декабря, 2016 пользователем IgorKossak форматировать разучились или никогда и не умели? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Д_М 0 26 декабря, 2016 Опубликовано 26 декабря, 2016 (изменено) · Жалоба Спасибо, попробовал! Результат прежний - работает только в Listening. Есть подозрение, что у меня какая-то аппаратная проблема. Вы использовали какое-то серийное устройство на базе AT90CAN128? Это устройство можно приобрести? Сделал вот так: #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; flag = CANSIT1; // чтение регистра состояния прерываний(того где Mob0 и Mob1) if(flag & (1<< 6)) //Если прерывание по Mob14 { CANPAGE = 0xE0; //Выбор Mob14 for(i = 0; i < 8; i++) *ptr++ = CANMSG; //Считать регистр данных сообщения 8 раз // CANSTMOB &= ~(1<<RXOK); //сбросить влаг удачного завершения приема } ptr = &Buttons.Right.reg + 2; tmp.lo = CANIDT1; tmp.hi = CANIDT2; Trg_NWA_r = tmp.si; Joystik_X = (signed char)(~*ptr++); Joystik_Y = (signed char)(~*ptr++); CANPAGE = 0xE0; CANSTMOB=0x00; // reset channel 14 status CANEN1 = 0x40; // channel 14 enable CANCDMOB = 0x88; // receive 8 bytes CANGIT = CANGIT; // reset all flags } void CAN_Init(unsigned char set_brp, unsigned char set_prs, unsigned char set_phs1, unsigned char set_phs2) { CANGCON = 0x0A; // Разрешить контроллер CAN CANGSTA = 0; CANGIT = 0; CANGIE = 0; CANIE1 = 0x40; CANEN1 = 0x40; CANBT1 = 0x06; CANBT2 = 0x0C; CANBT3 = 0x37; CANTCON = 0; CANTIML = 0; CANTIMH = 0; CANTTCL = 0; CANTTCH = 0; CANTEC = 0; CANREC = 0; CANHPMOB = 0; CANSTMOB = 0; CANSTML = 0; CANSTMH = 0; CANPAGE = 0xE0; // MailBox 14 // setup bit timing at 250k with 16 MHz crystal CANBT1 = 0x06; CANBT2 = 0x0C; CANBT3 = 0x37; CANPAGE = 0xE0; // MailBox 14 CANSTMOB = 0; // reset channel status CANCDMOB = 0; // reset control and dlc register CANIDT4 = 0x00; CANIDT3 = 0x00; CANIDT2 = 0x00; CANIDT1 = 0x00; CANIDM4 = 0x00; // Принудительный положительный результат сравнени CANIDM3 = 0x00; // Принудительный положительный результат сравнени CANIDM2 = 0x00; // Принудительный положительный результат сравнени CANIDM1 = 0x00; // Принудительный положительный результат сравнени // Channel 14 configuration CANCDMOB = 0x88; // Reception 8 bytes.*/ CANGIE = ((1<<ENRX)|(1<<ENIT)); // Can_Rx & IT enable } Изменено 26 декабря, 2016 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
pavel-pervomaysk 0 27 декабря, 2016 Опубликовано 27 декабря, 2016 · Жалоба Прочитайте даташит ВНИМАТЕЛЬНО, и желательно начиная с 19. Controller Area Network - CAN Я дал пример инициализации для работы в нормальном режиме. Нет же, надо принудительно включить LISTEN и все... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться