logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[ATMega8] [C] [uart] komunikacja ze sterownikiem samochodu

drago256 03 Sty 2011 16:21 2028 2
REKLAMA
  • #1 8951906
    drago256
    Poziom 11  
    Witam.

    Mam problem dotyczący komunikacji uk z ECU znajdującym się w Nissanie.

    Mianowicie posiadam protokół komunikacji według którego, ECU w samochodzie komunikuje się za pomocą UARTa. Transmisja 9600 baud, 8 bitow danych i 1 bit stopu. Komunikacja ze sterownikiem(odczytwanie parametrów) może nastąpić po wysłaniu ramki inicjalizacyjnej (0xff)(0xff)(0xef). Po wyslaniu tej ramki sterownik powinien odpowiedzieć : (0x10)

    Niestety po wysłaniu ramki inicjalizacyjnej nie mam żadnej odpowiedzi ze strony ECU. Ustawiłem przerwanie od Rx, więc wydaje mi się, że jeśli sterownik coś odpowie powinienem to widzieć.
    
     #include <avr/io.h>
    #include <inttypes.h>
    #include <util/delay.h>
    #include <avr/interrupt.h>
    
    #include "HD44780.h"
    
    #ifndef F_CPU
    #define F_CPU 4915200UL   // zegar
    #endif
    
    #define RS_BAUD 9600UL		// -------- transnisja 9600 ------------
    #define RS_UBRR 31UL	//	( (F_CPU/(16*RS_BAUD))-1 ) 
    
    
    volatile unsigned char i=0;
    
    
    
    //--------------------------- UART ------------------------------------
    
    void uart_init (unsigned int ubrr)
    {
    	UBRRH = (uint8_t)(ubrr >> 8);		// ustawienie predkoscitransmisji
    	UBRRL = (uint8_t)ubrr;
    
    	UCSRB = (1 << RXCIE) | (1 << RXEN) | (1 << TXEN); // wlaczenie nadajnika, odbiornika, przerwania od Rxc
    	UCSRC = (1 << URSEL) | (1 << UCSZ0) | (1 << UCSZ1);  // 8 bitow danych , 1stop, brak parzystosci
    	sei();			// odblokowanie przerwan
    }
    
    
    void uart_transmit(uint8_t data)
    {
    	while (!(UCSRA & (1 << UDRE))); // oczekiwanie na zakonczenie nadawania
    
    	UDR = data;
    }
    
    
    //-----------------------------------------  main----------------------------------------
    
    int main(void)
    
    {
    	uint8_t b,proby;
    	proby=0;
    
    	
    //	uint8_t inicjalka[]= {0xff, 0xff, 0xef}; // sekwencja startowa
    
    	
    	uart_init(RS_UBRR);   //  wlaczenie komunikacji szeregowej, 9600 baud, 8N1
    
    
    	LCD_Initalize();
    	LCD_Clear();
    	LCD_WriteText("pierwsza");
    	LCD_GoTo(0,1);
    	LCD_WriteText("druga");		// sprawdzenie wyswietlacza
    
    
    	_delay_ms(2000);
    	_delay_ms(2000);
    	_delay_ms(2000);
    
    
    
    	do
    	{
    		LCD_Clear();
    		LCD_GoTo(0,1);
    		LCD_WriteText("laczenie");
    		
    		_delay_ms(2000);		// odczekaj 2 sekundy miedzy kolejnymi probami
    
    		proby ++;
    
    		uart_transmit(0xff);
    
    		uart_transmit(0xff);
    
    		uart_transmit(0xef);	// ramki inicjalizacyjne
    		
    		
    
    		if (proby == 20)		// liczba prob polaczenia przekroczyla 20
    		{
    			LCD_Clear();
    			LCD_WriteText (" error ");
    
    			_delay_ms(2000);
    			_delay_ms(2000);
    			_delay_ms(2000);
    			
    		}
    
    		// probujemy ponownie
    	}
    	while (i == 0);	// odebrano cokolwiek - i - zostalo zmienione
    
    	LCD_Clear();
    	LCD_WriteText(" nawiazana");
    
    	_delay_ms(2000);
    	_delay_ms(2000);
    	_delay_ms(2000);	// poczekaj kilka sekund
    
    //------------------ komunikacja nawiazana-----------------
    
    	// tutaj, jesli komunikacja zostanie nawiazana wrzucam kolejne ramki (odczyt DTC itd.)
    
    //------------------------------ koniec--------------------------------------
    
    
    	return 0;
    }
    
    
    SIGNAL (SIG_UART_RECV)
    {
    	
    	i= UDR;
    
    }
    
    


    Sprzętowo wydaje się być wszystko ok. Transmisję sprawdzałem na oscyloskopie wysyłając jeden bajt w pętli i wyglądało to dobrze. Zresztą w moim układzie po zwarciu linii Tx z Rx wywoływane jest przerwanie od odbioru (wyświetla się napis "nawiazano" na LCD).

    Być może popełniam jakieś błędy w programie dlatego proszę o pomoc.

    Z góry dziękuję za odpowiedź.

    Pozdrawiam.
  • REKLAMA
  • #3 8953229
    drago256
    Poziom 11  
    Nie przez OBDII a przez OBDI które w Nissanach wyprodukowanych do 2000 roku komunikowały się według tego protokołu:

    http://www.plmsdevelopments.com/images_ms/Consult_Protocol_&_Commands_Issue_6.pdf

    Od razu zaznaczę, że zgodnie z tym protokołem puściłem zewnętrzny zegar na pin clk (sprawdzany wielokrotnie- działa na 100%).

    Układ do komunikacji taki sam jak w tym interfejsie:
    http://pinoutsguide.com/CarElectronics/nissan_consult_cable_pinout.shtml

    z tym,że zamiast max232 mam uk ATMega8 (Tx idzie na inwerter 12V, na Rx idzie sygnał z ECU zamieniony z 12V na 5V). Fejs sprawdzany z laptopem - działa bez problemu, dlatego wydaje mi się, że sprzętowo jest ok.

    Wydaje mi się, że albo coś źle odczytuje z protokołu, albo mam jakieś błędy w programie.
REKLAMA