PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : opel TID mit atmega 8



Mac Gyver
25.12.2007, 16:03
hi

ich war mir nicht sicher wo ich das hier hinstellen soll- es sit elektronisch aer auch avr hard und software...... naja ich stell es mal hier hin sollte es falsch sein bitte verschieben.


also folgendes problem:

ich habe einen opel corsa b mit einem sogenannten tid (tripple info display)
einige infos gibt es hier:
http://www.eelkevisser.nl/display.htm
http://www.carluccio.de/index.php?page=pro-tid

statt der radioinfos (das radio gibt es nicht mehr) möchte ich mir gerne einige andere infos von einem avr anzeigen lassen.

ich binnun soweit dass ich mir einen kleinen code geschrieben habe der auf dem hardware twi modul des avr und der lib von peter fleury basiert

das problem ist dass ich es noch nicht wirklich zum fliegen bekomme.

hat einer von euch das schonmal geschafft?

eine konkrete frage zum avr noch: kann ich den pegel an den twi pins auch bei aktiviertem twi über das pin register auslesen?

mfg
macgyver

Mac Gyver
27.12.2007, 19:21
keiner ne idee?

mittlerweile hab ich mir alle routinen zur ansteuerung selbst geschrieben aber nicht wirklich zum laufen gebracht-das programm läuft durch aber das display bleibt leer.

sourcecode lade ich hoch wenn sich jemand damit beschäftigen will.

kann man eigentlich asm files in c projekte einbinden? ich hab nämlich ne fertige asm-routine dafür gefunden aber das sind für mich hiroglyphen

mfg

Slein
27.12.2007, 20:01
Hi!

Zeig doch mal deinen Code, in deinen links steht ja eigentlich so gut wie alles drin, wo man braucht.
Deine Schaltung am besten auch gleich :)

Hab noch nen Mega8 hier und fahr ständig so ein Display spazieren.

MfG
S.

Mac Gyver
27.12.2007, 20:37
#include <TID.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <util/delay.h>
#include <string.h>

#define _PORT PORTD
#define _DDR DDRD
#define _PIN PIND
#define _SCL_out 0
#define _SCL_in 1
#define _MRQ_out 2
#define _MRQ_in 3
#define _SDA_out 4
#define _SDA_in 5
#define _AA 6

#define _address 0x4A


#define _step 128

char string[9] = "TEST ";
volatile char symbol[2], buffer[10];
volatile uint8_t state, mark, bitToSend, ByteToSend, cyclesRem;

void MRQ_high(void){
_PORT &= ~(1<<_MRQ_out);
}

void MRQ_low(void){
_PORT |= (1<<_MRQ_out);
}

void SCL_high(void){
_PORT &= ~(1<<_SCL_out);
}

void SCL_low(void){
_PORT |= (1<<_SCL_out);
}

void SDA_high(void){
_PORT &= ~(1<<_SDA_out);
}

void SDA_low(void){
_PORT |= (1<<_SDA_out);
}


uint8_t get_MRQ(void){
return (_PIN & (1<< _MRQ_in));
}

uint8_t get_SCL(void){
return (_PIN & (1<< _SCL_in));
}

uint8_t get_SDA(void){
return (_PIN & (1<< _SDA_in));
}

void init_DDR(void){
_DDR = (0<< _MRQ_in | 1<< _MRQ_out | 0<< _SCL_in | 1<< _SCL_out | 0<< _SDA_in |1<< _SDA_out | 1<<_AA);
}

void init_timer(void){
TCCR2 = (0<<FOC2 | 0<<WGM20 | 0<<COM21 | 0<<COM20 | 0<<WGM21 | 1<<CS22 | 1<<CS21 | 1<<CS20); //normal operation, prescaler 1024
TIMSK &= ~(1<<TOIE2 | 1<<OCIE2); //timer2 overflow/output compare interrupt disabled
}

void enable_timer_int(void){
TIMSK |= (1<<TOIE2); //timer2 overflow interrupt enabled
}

void disable_timer_int(void){
TIMSK &= ~(1<<TOIE2); //timer2 overflow interrupt disabled
}


void start_timer_ns(uint16_t ns){
uint16_t steps = (ns/_step);
cyclesRem=steps/256;
TCNT2=(steps-(cyclesRem*256));
enable_timer_int();
}

void start_timer_us(uint16_t us){
uint16_t steps = (1000*(us/_step));
cyclesRem=steps/256;
TCNT2=(steps-(cyclesRem*256));
enable_timer_int();
}

void delay_50us(uint8_t i){
for(;i>0;i--){
_delay_us(50);
}
}

void TID_on(void){
_PORT |= (1 << _AA); //set bit

for(uint8_t i=0; i<100;i++){ //warte 1sec
_delay_ms(10);
}

state=1;
}

void TID_off(void){
_PORT &= ~(1<< _AA); //clear bit
state=0;
}

void TID_init(void){
init_DDR();
init_timer();

SDA_high();
SCL_high();
MRQ_high();

sei();
}

void send_start(void){
PORTC=1;

MRQ_low();
while(get_SDA()); //warte bis SDA low
delay_50us(2);
MRQ_high();
PORTC=2;

while(!get_SDA()); //warte bis SDA high
delay_50us(2);

SDA_low();
delay_50us(3);

SCL_low();
delay_50us(3);

PORTC=3;
}

void send_stop(void){

SDA_low();
delay_50us(2);
MRQ_high();
delay_50us(2);
SCL_high();
delay_50us(2);
SDA_high();
delay_50us(2);

}

void send_bit(uint8_t bit){

if(bit){ //put bit on bus
SDA_high();
}else{
SDA_low();
}
_delay_us(5);

SCL_high(); //set bit valid
while(!get_SCL()); //wait for slave
delay_50us(1); //wait
SCL_low();

_delay_us(50);

}

uint8_t end_Byte(void){
uint8_t ack;

SDA_high();
delay_50us(1);
SCL_high();

while(!get_SCL());

ack=get_SDA();
delay_50us(1);
SDA_low();

while(!get_SDA());
delay_50us(2);

return ack;
}

void send_Byte(char Byte){
uint8_t parity=1;

for(uint8_t i=6; i>0; i--){
if((Byte & ~(1<<i))){
parity = !parity;
}

send_bit((Byte & ~(1<<i)));
}

send_bit(parity);

PORTC=end_Byte();
}

void TID_update(void){


TID_init();

TID_on();

symbol[0]=0x10;
symbol[1]=0x01;

send_start();
send_Byte(_address);
delay_50us(2);
MRQ_low();
delay_50us(2);



for(uint8_t i=0; i<2;i++){
send_Byte(symbol[i]);
}

for(uint8_t i=0; i<8;i++){
send_Byte(string[i]);
}

send_stop();

}




hier ist er

schaltung ist einfach immer ein ausgang um mit einem transistor die jeweilige leitung auf gnd zu ziehen und ein eingang um den pegel abzugreifen.

es müsste uach durch umschalten des ddr gehen aber das hab ich noch nicht implementiert

mfg

Mac Gyver
27.12.2007, 21:36
achja das ganze mit portc war nur dass ich sehe ob sich das prog irgendwo aufhängt

da hängen nur leds dran

mfg

Slein
27.12.2007, 22:57
Nur ein paar Ideen auf die Schnelle:

In den verlinkten Texten is die Rede von nem Power on Test, den find ich nich im code.

Ehrlich gesagt weiß ich grad nicht genau, was der c compiler aus funktionen ohne return macht. Bei ASM täte er ausführn was halt grade im Speicher kommt. Aber in c?

Sonst is mir auf die Schnelle nix weiter aufgefallen, aber ich glaub ich reiß morgen mal das Display ausm Autowagen :)

Mac Gyver
27.12.2007, 23:15
was sollte er aus funktionen ohne return machen? sind doch alles void rückgaben also keine?
was asm tut weis ich nicht ich kann das nichtmal lesen.

der power on test ist angeblich nicht nötig-die startbedingung geht auch problemlos durch und da muss das tid schon drauf reagieren sonst bleibt das prog hängen.

ich glaube dass ich einen fehler bei den paritäten habe-oder zumindest in der nähe.

mfg

Slein
28.12.2007, 08:08
Ich bekomm das Ganz nich compiled, von daher nur send_byte ein wenig abgeändert in nem kurzen Test für Windows. Änderungen in Byte & (1<<i) und bei den Randbedingungen für i im for:

#include <stdio.h>
#include <stdlib.h>

void send_Byte(char Byte){
char parity=1, i=0;

for(i=5; i>=0; i--){
if((Byte & (1<<i))){
parity = !parity;
}
printf ("i=%02i, parity = %02x, bit2send = %02x\n", i, parity, (Byte & (1<<i)));
}
}

int main(int argc, char *argv[]) {

send_Byte(0x0f);
system("PAUSE");
return 0;
}

Zum ansehn am Besten kurz mit Dev-C++ (www.bloodshed.net).

Mac Gyver
28.12.2007, 17:38
aja stimmt das file hat keine main funktion-daher gehts nicht allein zu compilieren.

hast dus so zum funktionieren gebracht??

meiner meinung nach hat die for schleife schon gepasst mit init i=6

mfg

Slein
28.12.2007, 18:36
Ne, paßt halt net mit 6.
Mit dem i=6; i>0; fängt er bei 6 an zu zählen und hört bei 1 auf.
Eigentlich ok, aber du adressierst die einzelnen Bits später mit i von 0 an (1<<i).

Die Tilde vor dem (1<<i) muß auch weg, wills ja nur genau ein bit mit dem & rausmaskieren für die Vergleiche danach.

Als Beispiel (mit den Änderungen) 0x0f gesendet:
i=05, parity = 01, bit2send = 00
i=04, parity = 01, bit2send = 00
i=03, parity = 00, bit2send = 08
i=02, parity = 01, bit2send = 04
i=01, parity = 00, bit2send = 02
i=00, parity = 01, bit2send = 01

edit:
Nein, es läuft noch nicht. Bin grad fertig mitm löten.
Werd aber selber was in ASM dafür schreiben, ich brauch später besseres timing als in c :)

Mac Gyver
28.12.2007, 18:52
hi

du sendest so aber nur 6 bit. es sollten doch 7+parity sein oder?

hast du das disp schon explantiert?
wenn du das in asm schreibst kann man das dann in ein c projekt einbinden?
mfg

Slein
28.12.2007, 19:37
Das mit den 6 bit isn Punkt, muß wohl doch ne 6 hin, aber um das >= kommst net drumrum, sonst geht er nich bis zum lsb runter.

Ja, habs schon draußen. strahlt mich grad mit ner komischen uhrzeit an. Hab mit der Software angefangen.

Gute Frage mit dem Einbinden. Ich werd das mit nem Puffer machen der dann in einem Rutsch rausgeschrieben wird, also die ersten 2 bytes für die Symbole und dann den Text.
Eigentlich müßte mann nur den Puffer füllen und die Routine anspringen. Eigentlich...

Mac Gyver
28.12.2007, 20:14
hmm-stimmt wohl-die fortsetung (i--) wird erst am ende der schleife gemacht oder?

werde das mal probieren

wenn es nur daran gelegen hat dann spring ich erst mal n paar meter hoch

mfg

Mac Gyver
28.12.2007, 20:23
so ich habs schnell mal so durchlaufen lassen mit dem erfolg dass das programm hängen bleibt

weis auch schon warum-wenn die schleife mit 0 durchläuft und unten doch mal um eins dekrementiert wird steht 255 in i und damit ist es wieder grösser 0

mfg

Slein
29.12.2007, 09:37
Ich glaub nicht, daß das Programm deswegen hängen bleibt.
Probier die Schleife mal einzeln mit Dev-C++ unter Windows aus, das läuft sauber durch.

vorher:
i=06, parity = 00, bit2send = 0f
i=05, parity = 01, bit2send = 0f
i=04, parity = 00, bit2send = 0f
i=03, parity = 01, bit2send = 07
i=02, parity = 00, bit2send = 0b
i=01, parity = 01, bit2send = 0d

nacher:
i=06, parity = 01, bit2send = 00
i=05, parity = 01, bit2send = 00
i=04, parity = 01, bit2send = 00
i=03, parity = 00, bit2send = 08
i=02, parity = 01, bit2send = 04
i=01, parity = 00, bit2send = 02
i=00, parity = 01, bit2send = 01

Beidesmal mit 0x0f gefüttert. Einmal bis Bit1, einmal bis Bit0. Parity war falsch und das lsb brauchst du schon irgendwie. Beim Schreiben der einzelnen Bits schaust du nur, ob das komplette Byte gleich/ungleich 0 ist, mit Tilde ist immer ungleich 0 und parity ändert sich auch jedesmal. Wenns mit den Änderungen crasht, ist irgendwoanders nochn Fehler drin.

Bin mittlerweile genauso weit wie du: einschalten, geht nicht :/

Mac Gyver
29.12.2007, 22:12
ahh ich weis schon warum es sich bei mir aufgehängt hat- i ist bei mir ein uint-> 0-1=255 bei dir ein char ->0-1=-1


bin heut aber nicht zum testen gekommen-hoffe du hattest schon mehr erfolg.

mfg

Slein
30.12.2007, 12:27
Sch.... Display :-s

Nach dem 2. rewrite und immer noch kein Text hab ich heut morgen nen logger zusammengebraten um zu sehen was aufm Bus los ist.
Mal schaun.

Idee dazu von http://www.eelkevisser.nl/display.htm.
Der 1. log ist auch von da, ein wenig vergrößert, der 2. ist von mir, der Plot an sich ist mit der demo von Funplot http://www.vanillaware.de/ gemacht.

Mac Gyver
30.12.2007, 14:00
hmm ich weis nicht ob ich jetzt ermutigt bin weil ich anscheinend nicht der einzige bin der das nciht gebacken kriegt oder eher demotiviert weil das disp anschienend schlauer als wir beide ist ;-)

naja ich hab jetzt mal die schleife richtig umgearbeitet und das prog läuft wieder durch aber daten gibts immer noch keine am disp.

wie siehts bei dir aus?

aja wie genau hast du den logger aufgebaut?

mfg

Slein
30.12.2007, 15:26
Zum Logger:
Einfach die 3 Leitungen über 3x 220 Ohm Widerstände (also rund 660 Ohm) an den LPT, direkt am Port mit jeweils 10kOhm gegen Masse gezogen. Benutzt werden nACK, Paper Out und Select, alles reine Eingänge. Am Port die Pins 10,12,13, 18-25 GND. Rest steht im Source.
Kurz und schmerzfrei :) is ja nicht auf dauer.

Mitgeschnitten mitm kurzen Programm. Quelle und Bin im Anhang.
Der Logger benötigt GiveIO Treiber um auf den Port zugreifen zu können, ist auch mit im Archiv.

Programm auf ner console starten, gibt 3 mit komma getrennte Zahlen aus. Leitung 1: 0/1, Leitung2: 2/3, Leitung3: 4/5 (-> ein Graph, 3 Kanäle).
Mit tidlog > test.txt landets in einer Textdatei, Funplot kanns direkt lesen.
Liest genau einen durchgang, wenn genug high auf allen 3 Leitungen zwischendurch anliegt -> alle 1 bis 2 sekunden nen Schreibvorgang versuchen.

Link zu FunPlot ist im letzten Post, Dev-C++ gibt bei www.bloodshet.net.

PS: Nein, es geht immer noch nicht :-s

Mac Gyver
30.12.2007, 15:45
mhm lpt.......... schon wida was was ich nicht habe..... ich glaube ich sollte mir mal irgendwo nen alten pc herschleppen für sowas....

mfg

ps: bei mir auch noch nciht-schön langsam gehn mir die ideen aus...

Slein
30.12.2007, 16:32
Wenn du kein lpt, tuts das hier bestimmt auch :)
http://www.pctestinstruments.com/

Ideen hab ich grad auch keine mehr...

Mac Gyver
30.12.2007, 17:30
sowas in die richtung wollt ich mir auch schon mal mit nem avr zusammenbraten hatte aber noch nicht wirklich die zeit/motivation dafür.

daher ist mein einziges hilfsmittel derzeit ein altes hameg oszi..... naja für schnittstellen mehr schätzeisen als sonst was...........


mfg

Mac Gyver
30.12.2007, 17:30
sowas in die richtung wollt ich mir auch schon mal mit nem avr zusammenbraten hatte aber noch nicht wirklich die zeit/motivation dafür.

daher ist mein einziges hilfsmittel derzeit ein altes hameg oszi..... naja für schnittstellen mehr schätzeisen als sonst was...........


mfg

Slein
30.12.2007, 18:43
Schau mal, was ich gefunden hab :)

http://www.asio.pl/?m=tid

Das tar.gz unter den Bildern

Mac Gyver
30.12.2007, 19:29
cool-das hab ich die ganze zeit gesucht-schade nur dass mein polnisch so eingerostet ist ;-) aber ich kenn da sogar jemanden.

hast dus schon implementiert?
funktionierts bei dir?

ich mach mich gleich ans werk!

mfg

Slein
30.12.2007, 19:41
Mein Display spricht mit mir :)
und gleich was unanständiges...

Bin die Routine zum byte senden in der lib mal parallel durchgegangen. Da hatte ich nochn Fehler am Ende drin.

Schön geschrieben, die lib :)

Mac Gyver
30.12.2007, 20:05
*gg*

meinen hauts noch auf die nase weil er die parity.h nicht findet die in tid.h deklariert ist... ka was das soll.

blöde frage-wie hängt man denn 2 arrays zusammen?

mfg

Mac Gyver
30.12.2007, 20:20
ok parity hab ich erledigt- ist jetzt <util/parity.h>

aber er meckert im hauptprgramm immer undefinded reference to tid_init

gleiches mit tid_send

hmm
gibts doch nicht

mfg

Slein
30.12.2007, 20:35
tid.h includiert? tid.c mitgebaut?

Mac Gyver
30.12.2007, 20:41
#include <avr/io.h>
#include <util/delay.h>
#include <tid.h>

#include <avr/interrupt.h>
//#include <avr/pgmspace.h>
//#include <avr/sleep.h>
//#include <inttypes.h>

volatile char text[8]=">>TEST<<", symbol[2]={0x10,0x01};


int main (void) {

for(;;){
char buffer[10];
tid_send(buffer);
}

return 0;
}







# List C source files here. (C dependencies are automatically generated.)
SRC += $(TARGET).c
SRC += tid.c
#SRC += param.c



mit meiner selbstgepfuschten lib hat das ja auch hingehaun.....

mfg

Mac Gyver
30.12.2007, 20:49
so bevor ich hier ganz blöd werde-kannst du mir mal deine sourcen hochladen?


mfg

Slein
30.12.2007, 21:45
Im Archiv im Anhang ist das komplette Projekt.
Die ASM Datei, ne fertige Hex und alles was dazu gehört.
Is für AVR-Studio direkt von Atmel.

Den Mega8 auf 8 MHz internen Oszilator.
Belegung und so steht im Source ganz vorne als Kommentar :)

Ich behandel allerdings noch keine Fehler/Sendewiederholungen und sowas.
Erst mal schaun wie es so läuft...

Viel Glück noch in C!
Sonst bau doch die lib direkt Funktion für Funktion in deinen Code ein,
geht auch, dauert nur was. Und richtige Fehlerbehandlung is da auch drin.

Mac Gyver
01.01.2008, 15:28
zuerst mal: PROSIT NEUJAHR!

danke-hast du das jetzt alles in asm umgeschrieben?
hast du die lib eigentlich zum laufen bekommen? schreibst du immer alles in asm oder nur zeitkritisches?

ich bin jetzt erst mal 3 tage weg aber dann werf ich mich nochmal auf das tid.

das muss doch hinzukriegen sein....

mfg

Slein
02.01.2008, 23:40
Dir auch nen frohes Neues und ein glückliches 2008!

Ja, in der Ansteuerung des TID alles in asm. Mit der lib an sich hab ich nicht weiter gespielt, hatte nur die Routine beim byte senden mal angeschaut und Fehler bei mir gefunden. Am Ende der Bytes waren Fehler, im Log sahs vorher auch gut aus. Keine Ahnung ob ichs falsch verstanden hatte oder in den links was falsch/missverständlich beschrieben war...

Würd dir auch empfehlen speziell diesen Bereich nochmal durchzugehen (neben dem was ich schon geschrieben hatte).

Hab gestern im Datenblatt gesehen, daß der Mega8 2wire in Hardware kann, sollte eigentlich möglich sein MRQ irgendwo dazwischenzufrickeln, aber mir fehlt grad der Antrieb dazu. Die nächsten Probleme sind bei mir aufgetaucht als ich das alles in der Karre (liebevoll gemeint) mal probiert hab. Läuft einfach nicht auf Dauer (länger als ne Minute). Ohne Saft aufm AVR ziehn jetzt die Pullups im Display nur noch auf rund 2,5V, *grrrrrrr*.

Also die Hardware nochmal. Bis jetzt wollte ich den AVR nur ans Display flanschen, aber ich glaub der muß zwischen Radio und Display, zumindest müssen wohl die Datenleitungen vom Radio getrennt werden (sieht jedenfalls grad danach aus) und Kabel im Autowagen durchschneiden mag ich nicht, schon wegen dem Rückbau und außerdem brauch das Ding täglich.

Zu ASM bin ich über C gekommen, hatte damit damals angefangen da ich das schon (ein wenig) von anderen Plattformen kannte. Aber die Programme werden kleiner, es paßt mehr ins flash und fixer wirds auch. Ich mag einfach die Idee Bits durch die Gegend zu schuppsen, direkt auf der Hardware, ohne Datentypen als Abstraktion dazwischen. Zahlen, Strings, wenn kümmerts, eh alles nur Bits :) Blöder Vergleich, aber schneller als mit offener Drosselklappe gehts halt nicht und wenn das gegenüber nur X ms warten tut O:)