Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Sterowanie TID - Sterowanie wyświetlaczem tid przez atmega32 w jezyku C

piotreq17 13 Lip 2013 14:00 7116 32
  • #1 13 Lip 2013 14:00
    piotreq17
    Poziom 9  

    Witam wszystkich!
    Potrzebuje małej pomocy odnośnie sterowanie wyświetlaczem TID z Opla Vectry B, dużo się naczytałem tematów o tym i chciałbym się za takie coś zabrać. Znam się trochę na programowaniu atmegi i znam język C, ale wszystkie tematy opisują sposoby programowania procesorami attiny i w Bascomie. Z tego co się już dowiedziałem tym wyświetlaczem steruje się za pomocą magistrali I2C więc trochę o tym poczytałem i minimalnie wiem na czym to polega. Problem w tym, że chciałbym to zrobić właśnie atmegą i w C, a nie wiem za bardzo jak to ugryźć, jak ma wyglądać mniej więcej program pod takie sterowanie, czy mogę do tego zastosować atmege i czy wystarczy dawać na wyświetlacz 5v jako stan wysoki czy muszę to jakoś przetwarzać na 12v. Co do samego napisania programu w C to dam sobie radę tylko nie mogę w pełni zrozumieć jak ma wyglądać wysłanie informacji do wyświetlacza.

    0 29
  • #2 14 Lip 2013 13:07
    mkpl
    Poziom 37  

    O ile sam wyświetlacz nie ma rezystorów podciągających (wystarczy sprawdzić napięcia na liniach) to podciągasz opornikami np 1k albo 4.7k. Po stronie procesora- Baza przez rezystor do portu emiter na masę a kolektor do lini sygnałowej. Ot cały konwerter. Należy tylko pamiętać iż będziesz miał odwróconą logikę sterowania (1 na porcie - 0 na lini)

    0
  • #3 14 Lip 2013 21:57
    piotreq17
    Poziom 9  

    No super to już trochę wiem ale jeszcze takie pytanie mam np. atmege32 wyjścia jak na zdjęciu:
    Sterowanie TID - Sterowanie wyświetlaczem tid przez atmega32 w jezyku C
    a w aucie mam wejścia do tida oznaczone sda, scl, mrq i teraz troszkę łopatologicznie jak wygląda napisanie czegoś na tym wyświetlaczu, z tego co czytałem trzeba przestawić prace atmegi na inny tryb i podpiąć pod któreś dwa pierwsze piny sda i scl ale niestety z braku wiedzy elektronika nie mam calkowicie pomysłu jak przestawić tą atmege i jak napisać program który by wyświetlił powiedzmy cyfrę 1 na tym wyświetlaczu.

    0
  • #4 14 Lip 2013 22:08
    mkpl
    Poziom 37  

    Niestety Tid jest tak wolny, że wszyscy jego obsługę piszą na piechotę. MRQ to coś ala potwierdzenie i odblokowywanie transmisji. Popatrz po kodach z innych programów.

    Generalnie nie zrobisz tego na wbudowanym TWI trzeba to zrobić ręcznie. Przygotowujesz całą tablicę danych do wysłania i wysyłasz to za jednym razem. Ten wyświetlacz z tego co kojarzę nie ma adresowania pól znakowych.

    0
  • #5 14 Lip 2013 23:54
    piotreq17
    Poziom 9  

    No tak tylko, ze problem polega na tym, ze wszystko co znalazlem jest napisane w bascomie, a ja się na bascomie nie znam. Znam dość dobrze C++ więc z C nie mam większych problemów, wszystkie pętle i ustawianie wyjść jak programuje atmege też mam obcykane. Z tego co rozumiem to muszę zrobić funkcje np. wyslij która zasygnalizuje start do wyświetlacza(z tego co czytałem sda musi przejsc ze stanu wysokiego na niski gdy scl ma stan wysoki) i wtedy wysłać dane czyli kolejne stany bitów(czyli zmieniam scl w stan niski wtedy ustawiam sda w stan wysoki lub niski zalezy co chce wyslac i daje na scl stan wysoki i tak w kółko po jednym bicie) i tak do sygnału końca transmisji. Dobrze to rozumiem? Jeżeli tak to powiedzmy, ze chce wyswietlic na wyswietlaczu slowo "witaj" to jak to przekonwertować na te stany?

    0
  • #6 14 Lip 2013 23:56
    mkpl
    Poziom 37  

    Wrzuć tu ten kod w bascomie ;) ja go rozumiem to Ci rozpisze algorytm

    0
  • #7 15 Lip 2013 00:07
    piotreq17
    Poziom 9  

    Praktycznie kazdy program który znajduje używa biblioteki ice.lib mimo, ze nie znam bascoma to widze, ze jest deklarowana zmienna np. "tekst", a później uzywana funkcja z tej biblioteki pisz_tid {tekst} więc poniżej wstawiam to co jest w bibliotece.
    Hmm jak tak teraz patrze to widze, ze tu praktycznie assembler jest i nasuwa mi się pytanie, czy w winavr mogę dorzucać wstawki assemblerowe?

    Ostatecznie mógłbym to jednak napisać w bascomie bo nie jest jakiś mega skomplikowany i są gotowe programy ale jakoś wolałbym zrozumieć transmisje i spróbować napisać to w C, ponieważ mam większe pomysły jak uda mi się wyświetlić coś, a w C mi będzie o wiele łatwiej.


    Code:
    ;Versja 1.0   pierwsza i ostatnia
    
    ;aby uzywac tej biblioteki trzeba na poczštku wpisać dytektywe
    ;$lib "ice.lib" 'a pod spodem takie coœ
    ;$external Wait_sda
    ;$external Czekaj
    ;$external Takt
    ;$external I2c_start
    ;$external Tid_ende
    ;$external I2c_send
    ;$external Pisz_tid 'do wyswietlania uzywa się tylko tej procki ale pozostale sš potrzebne do działania tej
    ;Miłej zabawy: Darek R. s_ice 5.12.2004

    ;wykorzystywane porty
    ;Scl Alias P1.0
    ;Sda Alias P1.1
    ;Mrq Alias P1.2




    ;procedura opuzniajšca parametry podaje się w R0 i R1 (czas opuznienia)
    ;wywolanie
    ;mov r0,#255 : mov r1,#255 : lcall czekaj
    [CZEKAJ]
    Czekaj:
    Loop0:
    push r0
    Loop1:
    djnz r0,loop1
    pop r0
    djnz r1,loop0
    ret
    [END]




    ;PROCKI DO OBSLUGI LCD NA I2C OPLA ASTRY UWAGA SCL,SDA,MRQ SĽ PISANE NA STALE JEŒLI SIĘ COŒ ZMIENI TO W PROCEDURACH TERZ TRZEBA POZMIENIAĆ
    ;SCL=P1.0
    ;SDA=P1.1
    ;MRQ=P1.2
    [WAIT_SDA]

    Wait_sda:
    clr P1.2      ;mrq ustaw na 0
                  ;opuznij o 910us
    mov r0,#223   ;JAKBY NIE DZIALALO TO PRUBUJ Z #230
    mov r1,#2
    lcall Czekaj
    setb P1.2     ;mrq ustaw na 1
                  ;opuznij o 910us
    mov r0,#223
    mov r1,#2
    lcall Czekaj

    mov r0,#223   ;opuznij o 910us jak bedzie wiecej to chyba nie zaszkodzi a może polepszyc
    mov r1,#2
    lcall Czekaj


    ret
    [END]


    [TAKT]
    takt:
    ;jak czasy za krotkie to nic nie widac
    mov r0,#195      ;202us 95
    mov r1,#1
    lcall czekaj
    setb P1.0        ;scl=1
    mov r0,#145      ;102us 45
    mov r1,#1
    lcall czekaj
    clr P1.0         ;scl=0
    mov r0,#11       ;34us  11
    mov r1,#1
    lcall czekaj
    ret
    [END]


    [I2C_START]




    I2c_start:
    ;startuje ze stanów wysokich i potem i2c start
    ;to moze byc zbedne
    ;P1 = 7      od razu ustawia te bity 00000111b
    ;ustaw 0 na SDA gdy na scl jest 1 (warunek startu)
    clr P1.1         
    mov r0,#90        ;192us
    mov r1,#1
    lcall czekaj
    clr P1.0          ;SCL=0
    mov r0,#90        ;192us
    mov r1,#1
    lcall czekaj
    ret
    [END]

    [TID_ENDE]
    Tid_ende:
               ;opuznij o 71us
    mov r0,#90 ;72us
    mov r1,#1
    lcall czekaj
    setb P1.2 ;mrq=1
    mov r0,#60 ;132us
    mov r1,#1
    lcall czekaj
    setb P1.0 ;scl=1
    mov r0,#55 ;122us
    mov r1,#1
    lcall czekaj
    setb P1.1 ;sda=1
    ret
    [END]

    [I2C_SEND]
    ;R2 JEST PARAMETREM PROCEDURY I ZAWIERA ZNAK DO WYSLANIA
    I2c_send:
    ;mov r2,{znak}'wywolanie
    clr c        ;zeruj carry flag
    mov acc,r2   ;{znak}                                             ;zapisz liczbe do obrubki
    rlc acc                                                       ;przesun w lewo o jeden bit
    MOV C,{psw.0}                                                 ;ustaw carry flag tak jak bit parzystosci
    jc dalej1                                                  ;jesli carry jest = 1 znaczy że liczba jest nieparzysta wiec nic nie rob z ta liczba Wyswietlacz opla ma kontrole parzystosci nieparzystš
    setb acc.0                                                    ;ustawia bit aby byla nieparzysta liczba jedynek
    Dalej1:
                 ;acc zawiera danš do wyslania
    ;mov {znak},acc  ;przepisz z acc do znak

    mov b,#8 ;powtóż 8 razy wysylanie bitu

    Petla:
    push acc      ;zapisz acc
    push b        ;zapisz b

    ;przesuwanie bitow w celu wyodrebnienia jednego do wyslania
    djnz b,shifting
    sjmp noshifting
    Shifting:
    rrc a
    djnz b,shifting
    Noshifting:
    anl a,#00000001b

    ;wysylanie bitu
    jnz setsda
    clr P1.1 ;Sda=0
    sjmp opusc_ustawianie
    Setsda:
    setb P1.1 ;Sda=1
    Opusc_ustawianie:

    ;$end Asm : Decr B : Sda = Znak.b : Incr B : $asm              'ustaw bit na sda dlatego jest decr b bo petla w asm wylacza sie jak b=0 i ten bit opuszczal, wiec petla zlicza od osmiu ,ale numeracja bitów jest od 7 do 0 , i po to to jest [ZASTĽPIONE ASEMBLEREM PATRZ WYŻEJ TAM GDZIE WYSYLANIE 8BITÓW]
    pop b
    pop acc

    push b
    lcall takt
    pop b
    djnz b,petla
    clr P1.1 ;SDA=0 ack po wyslanym bajcie Sda i Mrq muszš byc na 0 inaczej nie bedzie dzialac
    lcall takt

    ;opuznij o 42us AMENDE
    mov r0,#15 ;52us
    mov r1,#1
    lcall czekaj
    ret
    [END]


    [PISZ_TID]
    ;R0 jest parametrem wywolanie [mov r0,#{tekst}] - adres do zmiennej tekst potem lcall pisz
    ; Zmienna Tekst To Dim Tekst As String * 8
    Pisz_TID:
    orl P1,#&B00000111 ;wszystkie linie na stan wysoki SCL,SDA i MRQ
    push r0            ;zapisz R0 z adresem do ciagu znakow
    lCall Wait_sda
    lCall I2c_start
    mov r2,#74
    lCall I2c_send     ;(74) w siedmiobitowym wychodzi 0x94 Adres wyswietlacza


    clr p1.2           ;Mrq = 0  tu na stale bylo zerowane SCL,MRQ i SDA Mrq jest ustawione na 1 tylko podczas wysylania adresu do LCD
    mov r0,#7          ;26us
    mov r1,#1
    lcall czekaj
    mov r2,#0          ;ikonki1
    lCall I2c_send
    mov r2,#0          ;ikonki2
    lCall I2c_send
     ; - - - - - - - - - - - - - - - - - - - - - - - - - -
    pop R0             ;odtwóż adres zmiennej
    mov R1,#0          ;flaga jesli 0 to wyzylaj znaki ciagu, jesli 1 to znak pusty (127)
    mov b,#8
    Wysylaj:
    mov a,@r0          ;czytaj znak z cišgu

    push b             ;trzeba zapisac bo i2csend zmienia B
    push r0            ;trzeba zapisac bo procka czekaj uzywa r0 i r1 jak by zmienic na r3 i r4 to nie trzeba bedzie zapisywac i kod mniej zajmie


    jz ustaw_flage     ;jesli (acc)znak=0 reszta cišgu ma mieć 127(pusty znak) skocz i ustaw flage
    sjmp dalej3        ;jesli nie to nie rob nic i skocz dalej
    Ustaw_flage:
    mov r1,#1
    Dalej3:


    cjne r1,#0,pusty_znak ;jesli r1<>0 to pisz pusty znak
    mov r2,a              ;znak cišgu
    sjmp dalej4
    Pusty_znak:
    mov r2,#127           ;pusty znak ,jak spacja, po to żeby œmieci nie zostawaly jak cišg jest krótszy
    Dalej4:

    push r1               ;zapisz flage
    lcall I2c_send
    pop r1                ;przywroc flage
    pop r0
    pop b
    inc r0
    djnz b,wysylaj

    lcall Tid_ende
    orl P1,#&B00000111    ;wszystkie linie na stan wysoki SCL,SDA i MRQ
    ret
    [END]

    0
  • #8 15 Lip 2013 11:09
    mkpl
    Poziom 37  

    No kolego to nie jest Bascom. To jest asembler ;) Możesz to sobie wstawić jako gotową wstawkę asemblerową. W chwili przerwy przy kawie rozrysuję Ci co i jak może się uda.

    0
  • #9 15 Lip 2013 11:32
    tronics
    Poziom 36  

    Tak, są w tym instrukcje ASM, ale '51, natomiast całość to biblioteka dyrektyw do obsługi wyświetlacza w BASCOMie. Zasadniczo chyba jedynie może przydać się jako podstawa do zrobienia własnej dla AVR, bo do niczego innego się tutaj nie przyda.

    0
  • #10 15 Lip 2013 13:26
    piotreq17
    Poziom 9  

    Dodatkowo znalazłem program w C do tida ale 8 znakowego (ja mam 10 znakowy) może coś rozjaśni.

    Code:


    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include "lib\delay.c"



    unsigned char dana,i, t,s,d,j ,cnt1, z1, p;
    unsigned int  liczba,b,a,cnt;                       //zmienne
    char wi;

    void puls_us(void)
    {
    delayus(400);
    }
    void startpuls(void) //czasy
    {
    delayus(200);
    }
    void sek(void)
    {
    delayms(1000);
    }

    void start(void)
    {
    DDRB = 0xFF;
    PORTB=0xFF;    //strat
     PORTB |=_BV(3); //mrq=0;
     puls_us();
     PORTB &=~_BV(3); //mrq=1;                      //bit startu na magistrali I2C  START
     PORTB &=~_BV(1); //sda=1;
     PORTB &=~_BV(2); //scl=1;
     startpuls();
    PORTB |=_BV(1); //sda=0;
     startpuls();
     PORTB |=_BV(2); //scl=0;
     startpuls();

    }
    void stop(void)  //STOP
    {

     PORTB &=~_BV(3); //mrq=1;
     PORTB &=~_BV(2); //scl=1;
     startpuls();
     PORTB &=~_BV(1); //sda=1;
     //portb=28;
     }

     void send(unsigned char dana)   // wysyłanie
    {

     for(i=0;i<8;i++)       //będzie 8 bitów
     {
      if(dana&0x80)         //badaj najstarszy bit wysyłanego znaku
      {
       PORTB &=~_BV(1); //sda=1;     //wyślij "1"
      }
      else
      {
      PORTB |=_BV(1); //sda=0;       //wyślij "0"
      }
      PORTB &=~_BV(2); //scl=1;
      puls_us();
      PORTB |=_BV(2); //scl=0;
      puls_us();
      dana<<=1;        //przygotuj następny bit do wysłania
      }
      PORTB &=~_BV(1); //sda=1;
      PORTB &=~_BV(2); //scl=1;
      puls_us();
      PORTB |=_BV(2); //scl=0;
     PORTB |=_BV(1); //sda=0;
      PORTB |=_BV(3); //mrq=0;
      puls_us();

     }

    char table[10]={0x61,0x62,0x64,0x67,0x68,0x6b,0x6d,0x6e,0x70,0x73};   //tablica cyf

     void powitanie(void)
    {
       for (p=0; p<10;p++) {
       start();
       startpuls();
       send(0x9B);
       startpuls();
       PORTB |=_BV(3); //mrq=0;
       startpuls();

       send(0x01);
       send(0x01);
       send(0x01);
       send(0x77);
       send(0x78);
       send(0x79);
       send(0x71);
       send(0x72);
       send(0x73);
       send(0x74);
       send(0x75);
       send(0x76);
       send(0x77);

       stop();
       delayms(100);
       }
       for (p=0;p<10;p++) {
       start();
       startpuls();
       send(0x9B);
       startpuls();
       PORTB |=_BV(3); //mrq=0;
       startpuls();
       send(0x01);
       send(0x01);
       send(0x01);
       send(0x77);
       send(0x78);
       send(0x79);
       send(0x71);
       send(0x72);
       send(0x73);
       send(0x74);
       send(0x75);
       send(0x76);
       send(0x77);

       stop();
       delayms(100);
       }
       wi++;
       }
     //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    void main () {         //główny program
    DDRB = 0xFF;
    PORTB=0xFF;


    while(1) //(wi<1)
      {
      powitanie();
      }
     
    }

    0
  • #11 15 Lip 2013 13:57
    mkpl
    Poziom 37  

    Tid 8 znaków i 10 znaków w komunikacji niczym się nie różni

    0
  • #12 15 Lip 2013 14:50
    piotreq17
    Poziom 9  

    Dlaczego trzeba 10 razy wysyłać to samo funkcją for

    Code:

    for (p=0;p<10;p++) {
       start();
       startpuls();
       send(0x9B);
       startpuls();
       PORTB |=_BV(3); //mrq=0;
       startpuls();
       send(0x01);
       send(0x01);
       send(0x01);
       send(0x77);
       send(0x78);
       send(0x79);
       send(0x71);
       send(0x72);
       send(0x73);
       send(0x74);
       send(0x75);
       send(0x76);
       send(0x77);

       stop();
       delayms(100);
       }


    i co robi ten send
    Code:

       send(0x9B);
       startpuls();
       PORTB |=_BV(3); //mrq=0;
       startpuls();

    bo widzę, ze później wysyłany jest tekst, a ten pierwszy send jest przed zerowaniem mrq i tego nie rozumiem. Program juz w połowie napisałem jak skończę to go wrzucę :)

    0
  • #13 15 Lip 2013 15:07
    mkpl
    Poziom 37  

    ten 0x9B to jest coś ala adresw wyświetlacza. Natomiast to pierwsze wygląda na jakieś przywitanie...

    Weź odpal w oryginale ten kod. Przerobienie go na inny procesor to nie problem a przy okazji modyfikując go rozpracujesz całość :)

    0
  • #14 15 Lip 2013 16:57
    piotreq17
    Poziom 9  

    Ok to najpierw spróbuje odpalić ten kod i zobaczymy, jeszcze mam jedno małe i w sumie śmieszne pytanko odnośnie podłączenia do atmegi

    Code:

    PORTB &=~_BV(3); //mrq=1;                   
     PORTB &=~_BV(1); //sda=1;
     PORTB &=~_BV(2); //scl=1;

    z tego wynika, ze sda powinno być pod PB0 czy PB1 bo z tego co czytałem to funkcja BV to jest po prostu przesunięcie ale nie mogę pojąć czy to przesuwa 1 bit czyli PB0 czy PB1?

    Dodano po 1 [godziny] 42 [minuty]:

    Odpiąłem radio wpiąłem się w miejsce radia w sda scl i mrq dalem zasilanie 5 v na atmege i wlaczylem zaplon zeby tid sie wlaczyl, i nic sie nie zmienilo wyswietlal date jak zawsze.

    0
  • Pomocny post
    #15 15 Lip 2013 18:05
    mkpl
    Poziom 37  

    Wyświetlacz w oplu ma dodatkowy przewód sygnałowy który jest podłączony pod wyjście sterujące radia. Podanie tam sygnału (zasilanie albo masa teraz nie pamiętam) przełącza LCD w tryb dadio albo data

    0
  • #16 15 Lip 2013 18:40
    piotreq17
    Poziom 9  

    No to już ogarnąłem i podłączyłem odpowiednio data znika ale nadal pustki, wydaje mi się, że to coś z adresem wyświetlacza i obecnie go szukam.

    0
  • #18 15 Lip 2013 21:12
    piotreq17
    Poziom 9  

    Już to wcześniej przeglądałem, ale dzięki temu, że znów zerknąłem wiem czemu wysłane jest w sumie 14 sendów: pierwszy to oczywiście adres, kolejne 3 to piktogramy na wyświetlaczu, a kolejne 10 to cyfry, znalazłem też na tej stronie Link adres wyświetlaczy 10 cyfrowych (4Dh) zaraz sprawdzę czy to zadziała.

    Dodano po 48 [minuty]:

    Niestety nadal nic szukam dalej.

    Dodano po 1 [godziny] 12 [minuty]:

    Próbowałem wszystkich adresów wyświetlacza jakie znalazłem i ciemność, dzisiaj już nic nie wymyślę muszę się z tym przespać :P jutro będę próbował dalej.

    0
  • #19 16 Lip 2013 13:19
    robiw
    Poziom 26  

    Kolego. W jednym z ostatnich numerów EP jest układ TIDex, gdzie opisany masz interesujący Cie protokół transmisji. Kiedyś też ukazał się projekt TID-sterownik, gdzie masz to samo. Robiw

    0
  • #20 16 Lip 2013 15:17
    piotreq17
    Poziom 9  

    Witaj robiw zdziwiłbyś się ile przeczytałem Twoich tematów:), możesz mi powiedzieć czy 0x9B to jest dobry adres tida od Vectry B 98r.? Już mniej więcej wiem jak wygląda protokół tylko nie wiem paru szczegółów odnośnie czasów, a dokładniej jak szybko muszę wysyłać odpowiednie bity, na razie będę próbował wysyłać od 100us do 400us bo nie mam innego pomysłu.

    0
  • Pomocny post
    #21 16 Lip 2013 15:36
    robiw
    Poziom 26  

    #define TIDaddr 0x4D //Adres 10-znakowego TIDa
    robiw

    0
  • #22 16 Lip 2013 15:36
    piotreq17
    Poziom 9  

    I czy w przypadku Tida z Vectry muszę czekać na odpowiedź wyświetlacza po wysłaniu adresu czy mogę się "wstrzelić" i wysyłać dane po określonym czasie?

    0
  • #23 16 Lip 2013 18:15
    robiw
    Poziom 26  

    Zawsze lepiej czekać na ACK od TIDa, ale można też pominąć ten krok. Ja, jeśli otrzymuję błąd transmisji to ponawiam ją kilkukrotnie aż będzie OK lub przekroczę maksymalna liczbę prób...Dokładnie już nie pamiętam bo to było jakiś czas temu, ale w sieci znajdziesz gotową bibliotekę w C...robiw

    Dodano po 2 [godziny] 30 [minuty]:

    Aha, jeszcze jedno. U mnie procedura wysyłania bajta do TIDa (czyli także adresu) rozpoczyna od MSB ale bitu nr 6 (dlatego, że przesyłamy 7 bitów bajta (6...0) plus bit kontroli parzystości jako ostatni) w związku z czym ten adres 0x4D przesunięty jest niejako o jedno miejsce w lewo co daje nam 0x9A bo 0x4D<<1=0x9A a w tym parzysta liczba jedynek :-)...robiw

    0
  • #24 16 Lip 2013 21:24
    piotreq17
    Poziom 9  

    Ooo to ja muszę się jeszcze dużo nauczyć :P zrobiłem na razie taki program ale teraz widzę, że to nie miało szans zadziałać z braku mojej wiedzy :P nie zwracałem uwagi na bit parzystości po prostu brałem adres zamieniałem go na binarny i wysyłałem 8 bajtów, czy takim sposobem mam szanse coś wyświetlić oczywiście jak poprawie to z parzystością bitów, adresem wyświetlacza i z oczekiwaniem na odpowiedź tida?

    Code:

    #include <avr/io.h>
    #include <avr/interrupt.h>
    #include <util/delay.h>

    void delay100us()
    {
       _delay_us(400);
       //_delay_ms(2000);
    }

    void start()
    {                                 //    MCD   01001101
       PORTB = 0X07;    //0000111
       delay100us();
       PORTB = 0X03;    //0000011
       delay100us();
       PORTB = 0X02;    //0000010
       PORTB = 0X06;    //0000110
       delay100us();
       PORTB = 0X04;    //0000100
       //WYSYLANIE ADRESU TIDA
       delay100us();
       PORTB = 0X05;    //0000101
       delay100us();
       PORTB = 0X06;    //0000110 WYSYLAMY STAN NISKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       PORTB = 0X07;    //0000111 WYSYLAMY STAN WYSOKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       PORTB = 0X06;    //0000110 WYSYLAMY STAN NISKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       PORTB = 0X06;    //0000110 WYSYLAMY STAN NISKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       PORTB = 0X07;    //0000111 WYSYLAMY STAN WYSOKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       PORTB = 0X07;    //0000111 WYSYLAMY STAN WYSOKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       PORTB = 0X06;    //0000110 WYSYLAMY STAN NISKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       PORTB = 0X07;    //0000111 WYSYLAMY STAN WYSOKI
       delay100us();
       PORTB = 0X04;    //0000100
       delay100us();
       
       PORTB = 0X01;    //0000001 zerujemy MRQ
       delay100us();
       
    }
    void tekst()
    {
       for(int i=0;i<3;i++)
       {
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X03;    //0000011 WYSYLAMY STAN WYSOKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
       
       
       }
       for(int i=0;i<10;i++) //wysylamy 10 liter p na próbę czyli 1110000
       {
          PORTB = 0X03;    //0000011 WYSYLAMY STAN WYSOKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X03;    //0000011 WYSYLAMY STAN WYSOKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X03;    //0000011 WYSYLAMY STAN WYSOKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
          PORTB = 0X02;    //0000010 WYSYLAMY STAN NISKI
          delay100us();
          PORTB = 0X01;    //0000001
          delay100us();
       
       
       
       }


    }

    void stop()
    {
       PORTB = 0X04;    //0000100 USTAWIAMY MRQ NA WYSOKI
       delay100us();   
       PORTB = 0X06;    //0000110
       delay100us();
       PORTB = 0X07;    //0000111 WYSYLANIE SYGNALU STOP
       delay100us();

    }


    int main(void)
    {
       DDRB = 0XFF;
       
       while(1)
       {
       start();
       tekst();
       stop();
       }

       
    }

    0
  • #25 16 Lip 2013 21:44
    robiw
    Poziom 26  

    Sorry, ale ten program jest masakrycznie nieczytelny i nawet trudno powiedzieć co się w nim dzieje. Poszukaj lepiej gotowca w sieci - jest napisany w C i działa wyśmienicie. W ogóle nie wziąłeś pod uwagę rysunków ramki transmisji jak mniemam (sygnał MRQ itd.)...robiw

    0
  • #26 16 Lip 2013 21:59
    piotreq17
    Poziom 9  

    Hehe wziąłem pod uwagę MRQ pisząc portb = 0x07 binarnie 0000111 ustawiam PB0,PB1,PB2 na 1 w moim przypadku PB0 = SDA, PB1 = SCL, PB2 = MRQ, i później po kolei zmieniam stany jakoś mi się to wydaje bardziej czytelne :), wszystko jest w komentarzu co się dzieje, poszukam jeszcze tego programu w C może znajdę bo do tej pory wszystko w bascomie oprócz tego co wkleiłem pare postów wyżej niestety też nie działa:/ Chyba, że spróbuję z tym adresem przesuniętym jeszcze to sprawdzę.

    0
  • Pomocny post
    #27 16 Lip 2013 22:08
    robiw
    Poziom 26  

    Na zachętę kod funkcji wysyłającej jeden znak do TIDa:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    robiw

    0
  • #28 16 Lip 2013 22:15
    piotreq17
    Poziom 9  

    Wielkie dzięki już rozkminiam i ogarniam :)

    Mam problem z tą częścią kodu:

    Code:
    SET_SDA; // Odczytujemy bit potwierdzenia ze strony TIDa - tzw. Ack
    
       _delay_us(50);
       SET_SCL;
       loop_until_bit_is_set(TID_PIN,TID_SCL); // Czekamy, aż TID zwolni ewentualnie sciaganą do masy linię SDA
     
       // Jesli SDA=1 (więc Ack=1) to brak potwierdzenia odbioru bajta danych ze strony TIDa
       if(( Ack = bit_is_set(TID_PIN,TID_SDA)) )  reportError(1);  // Brak Ack
     

    dokładniej to z odczytaniem odpowiedzi od TIDA widzę, że SET_SDA to po prostu wysłanie stanu wysokiego do wyświetlacza RESET_SDA to stan niski więc zrobiłem sobie dyrektywy
    Code:
    #define SET_SDA PORTB |= (1<<0)
    
    #define RESET_SDA PORTB &= 0x01
    #define SET_SCL PORTB |= (1<<1)
    #define RESET_SCL PORTB &= 0x02
    #define SET_MRQ PORTB |= (1<<2)
    #define RESET_MRQ PORTB &= 0x04


    powinny działać, a TID_SDA to jest odczyt odpowiedzi z TIDA więc wystarczy, że np. ustawie sobie PORTA na wejścia i zmostkuję PB0 z PA0 dodam dyrektywę to będzie działać? I nie mogę rozgryźć do czego jest TID_PIN.

    0
  • #29 05 Lis 2013 16:07
    aneuro
    Poziom 16  

    robiw napisał:
    U mnie procedura wysyłania bajta do TIDa (czyli także adresu) rozpoczyna od MSB ale bitu nr 6 (dlatego, że przesyłamy 7 bitów bajta (6...0) plus bit kontroli parzystości jako ostatni) w związku z czym ten adres 0x4D przesunięty jest niejako o jedno miejsce w lewo co daje nam 0x9A bo 0x4D<<1=0x9A a w tym parzysta liczba jedynek :-)

    Akurat w I2C ten bit najmniej znaczący w bajcie adresu oznacza: Read/Not(Write) a nie żadną kontrolę parzystości i trzeba uważać bo producenci podają czasami zamiast 7bitowego adresu ten 8bitowy z Write=0, czyli bajt jaki trzeba wysłać przez I2C aby pisać do urządzenia ;)
    Sterowanie TID - Sterowanie wyświetlaczem tid przez atmega32 w jezyku C

    mkpl napisał:
    O ile sam wyświetlacz nie ma rezystorów podciągających (wystarczy sprawdzić napięcia na liniach) to podciągasz opornikami np 1k albo 4.7k.

    A w tym TID ta szyna I2C w Oplu Corso na jakich napięciach działa?
    Nie potrzeba przypadkiem robić na mosfetach konwersji napięcia pomiedzy I2C 5V mikrokontrolera i tego wyświetlacza, jak opisane przez NXP tutaj?
    AN10441 Level shifting techniques in I2C-bus design NXP
    http://www.nxp.com/documents/application_note/AN10441.pdf‎

    Nie mam jak zmierzyć póki co, bo mam taki wyświetlacz z Opla Corso 1.2 1993 rok wymontowany:
    Sterowanie TID - Sterowanie wyświetlaczem tid przez atmega32 w jezyku C
    Zidentyfikowałem te standardowe kabelki do zasilania: czerwony (+12V na stałe), czarny (+12V od stacyjki), brązowy (masa zasilania), niebieski i niebieski z białym paskiem (NTC za zderzakiem z przodu przed chłodnicą po środku).
    Nie jestem pewien 3ech pozostałych:
    * szary z zielonym paskiem (podobno oświetlenie-mam to pod 12V podpinać?)
    * niebieski z czerwonym paskiem ??
    * szary z czarnym paskiem ???
    Nie widzę w ogóle wyprowadzonych tych SCL,MRQ,SDA czyli w tym styku to powino być (9,10,11), bo jakiś opis znalazłem w linkach z innych wątków na tym forum i kolory tych zidentyfikowanych kabelków pasują tylko brakuje wyprowadzenia tych od TID chyba.

    W ogóle jest szansa mikroprocesorem ten wyświetlacz sterować, bo się zastanawiam czy po prostu taka wtyczka w tym TID tylko włożona, bo tam nie miało się co przez TID z tym komunikować chyba (radio było zwykłe włożone nie podłączone do wyświetlacza), czy to jakiś wyświetlacz który nie można sterować programowo?
    Sterowanie TID - Sterowanie wyświetlaczem tid przez atmega32 w jezyku C

    Jak widać z tyłu jest po środku nazwa "Lucas" i jak był podłączony to pokazywał godzinę po lewej stronie i temperaturę po prawej....
    Dodam tylko że to będzie działać nie w samochodzie a pojeździe EV więc tylko kwestia, czy to I2C+MRQ jakoś dałoby się dorobić jak opisywane było już trochu na ten temat.
    Na AVR'rze poprzez soft I2C chcę się z tym wyświetlaczenm TID komunikować jak to w ogóle możliwe w tym modelu ...

    0
  • #30 05 Lis 2013 16:18
    mkpl
    Poziom 37  

    Tego nie da się sterować z procesora. Ma tylko godzinę i temperaturę

    0