Перейти к содержанию
    

Приветствую!

Устройство на базе 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, когда был подключен датчик и конвертер, наблюдалось характерное мерцание светодиода.

Заранее благодарен за советы!

Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если в процедуре инициализации убрать задание скорости, но оставить включение CAN контроллера, то датчик не подвешивается.

Так вы либо скорость неправильно задаете, в итоге CAN128 может портить посылки кода выдает на линию например ошибки...

либо проблемы со схемой (с драйвtром CAN)

может быть и с шиной проблемы - шина не должна быть звездой и с короткими стабами и терминаторами 120 ом по краям...

Да и еще проверить не перевернута ли шина...

 

Можно попробовать в listen only режиме пакеты принимать...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так вы либо скорость неправильно задаете, в итоге 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. Есть ли какие стандартные значения?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Была задача сделать мост 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                    ; 
;----------------------;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если я правильно понял, то сама по себе инициализация CAN контроллера не должна вызывать влияния на линию?

Как это не должна?

если CAN проиничен не в listen only mode, скорость задана - CAN обязан выдавать на линию сигналы АСК в случае приема корректного фрейма или ошибки... (настройки фильтров и мейлбокосов на это не влияют!)

 

 

А это самая нудная часть CAN. Есть ли какие стандартные значения?

Там - все просто, надо только внимательно прочитать как формируются биты!

И учесть что в регистрах хранится значение на 1 меньше...

 

Например здесь все хорошо расписано

http://www.nxp.com/files/microcontrollers/...note/AN1798.pdf

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

Получилось добиться работы с одним прибором в режиме 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

Изменено пользователем IgorKossak
[codebox] для длинного кода. [code]-для короткого!!!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, что ответили!

Для начала мне хотелось бы разобраться с технологией CAN. В моём случае имеющиеся у меня устройства постоянно сыпят посылки в линию. Независимо от того, надо оно кому-то, или нет. В этом и заключается главное отличие CAN от других интерфейсов, где всё строится по принципу запрос-ответ. Из этого вытекает вопрос - какой надо выбрать режим при инициализации MailBox?

 

– 00 - disable.

– 01 - enable transmission.

– 10 - enable reception.

– 11 - enable frame buffer reception

 

И далее инициализация CAN. Какие разрешить прерывания?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Настроили 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 анализатор, очень пригодится, если планируешь работать с шиной.

Ато читаю что сообщения друг другу посылаются хаотично - уши заворачиваются.... :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Пересмотрел все примеры программ, которые мне удалось найти. Кое-что "надёргал" и повставлял в мою программу. А результат прежний - работает только в 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 бит. Как мне представляется, то если этот параметр задан некорректно, то работать не должно. У меня задача с тремя неизвестными. Сомнительных код, сомнительных контроллер, сомнительный датчик. Может быть посоветуете какой-то копеечный датчик, например автомобильный, который можно использовать, как тестовый. Если есть заведомо проверенный софт, под какой-то конкретный датчик, не откажите в любезности. Если у Вас есть контроллер и датчик, которые стыковались друг с другом, я у Вас их приобрёл бы.

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приниматься будут все сообщения 11 и 29 бит.

Мы можем их фильтровать только. Флаг IDE проверили, далее решили как считать MID.

Для начала начинать надо передавать сообщения корректно.

Ловить вторым устройством.

Может банально неправильно Baud настроен, я с 250к не работал, такое только в BMW и газелях встречается.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здравствуйте!

Спасибо за ответ! Не понял на счет 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 и всё подружилось, то буду премного благодарен за код.

post-4185-1482483068_thumb.jpg

post-4185-1482483077_thumb.jpg

post-4185-1482483085_thumb.jpg

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Датчиков с 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го байта.

Изменено пользователем IgorKossak
форматировать разучились или никогда и не умели?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, попробовал!

Результат прежний - работает только в 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
}

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Прочитайте даташит ВНИМАТЕЛЬНО, и желательно начиная с 19. Controller Area Network - CAN

Я дал пример инициализации для работы в нормальном режиме.

Нет же, надо принудительно включить LISTEN и все...

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...