-
opel TID mit atmega 8
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
-
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
-
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.
-
Code:
#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
-
achja das ganze mit portc war nur dass ich sehe ob sich das prog irgendwo aufhängt
da hängen nur leds dran
mfg
-
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 :)
-
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
-
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).
-
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
-
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 :)