Forum: Compiler & IDEs Gameboy Camera READ Problem


von Nicole F. (Gast)


Lesenswert?

Hallo,

Mit folgendem Code versuche ich ein Bild aus der GameBoy Camera zu 
holen, leider vergeblichst. Denn der READ Pin wird von der Kamera nich 
hochgezogen.
1
while(!(PIND&(1<<CAM_READ)))
2
  {
3
    
4
    CLK_LOW();
5
    camStepDelay();
6
    CLK_HIGH();
7
    camStepDelay();
8
  }


Vielleicht hat jemand eine Idee woran es liegen könnte.

1
#define CAM_START  2
2
#define CAM_SIN    3
3
#define CAM_LOAD  4
4
#define CAM_RESET  5
5
#define CAM_CLK    6
6
#define CAM_READ  7
7
8
#define START_HIGH()  PORTD|=(1<<CAM_START)
9
#define SIN_HIGH()    PORTD|=(1<<CAM_SIN)
10
#define LOAD_HIGH()    PORTD|=(1<<CAM_LOAD)
11
#define RESET_HIGH()  PORTD|=(1<<CAM_RESET)
12
#define CLK_HIGH()    PORTD|=(1<<CAM_CLK)
13
#define READ_HIGH()    PORTD|=(1<<CAM_READ)
14
15
16
#define START_LOW()    PORTD&=~(1<<CAM_START)
17
#define SIN_LOW()    PORTD&=~(1<<CAM_SIN)
18
#define LOAD_LOW()    PORTD&=~(1<<CAM_LOAD)
19
#define RESET_LOW()    PORTD&=~(1<<CAM_RESET)
20
#define CLK_LOW()    PORTD&=~(1<<CAM_CLK)
21
#define READ_LOW()    PORTD&=~(1<<CAM_READ)



1
void cam_reset(void)
2
{
3
  RESET_LOW();
4
  CLK_LOW();
5
  camStepDelay();
6
  CLK_HIGH();
7
  camStepDelay();
8
  CLK_LOW();
9
  RESET_HIGH();
10
  camStepDelay();
11
  RESET_LOW();
12
13
}
14
15
void cam_write(unsigned char reg, unsigned char data){
16
  char i;
17
18
19
  for(i=0;i<3;i++)
20
  {
21
    CLK_LOW();
22
    
23
    if((reg & 0x04 ) > 0)
24
    SIN_HIGH();
25
    else
26
    SIN_LOW();
27
    reg = (reg<<1);
28
    camStepDelay();
29
    CLK_HIGH();
30
    camStepDelay();
31
    
32
  }
33
34
35
  for(i=0;i<8;i++)
36
  {
37
    CLK_LOW();
38
39
    if((data & 0x04 ) > 0)
40
    SIN_HIGH();
41
    else
42
    SIN_LOW();
43
    data = (data<<1);
44
45
    
46
    camStepDelay();
47
    CLK_HIGH();
48
    camStepDelay();
49
  }
50
  LOAD_HIGH();
51
  camStepDelay();
52
  CLK_LOW();
53
  camStepDelay();
54
  LOAD_LOW();
55
  SIN_LOW();
56
  
57
}
58
59
void cam_getphoto(void)
60
{
61
  cam_reset();
62
63
  cam_write(0,0x80);
64
  cam_write(1,0x0E);
65
  cam_write(2,0x06);
66
  cam_write(3,0x00);
67
  cam_write(4,0x01);
68
  cam_write(5,0x00);
69
  cam_write(6,0x01);
70
  cam_write(7,0x07);
71
72
  cam_start();
73
  
74
  cam_readsend();
75
}
76
77
void cam_start(void)
78
{
79
  
80
  
81
  START_HIGH();
82
  camStepDelay();
83
  CLK_HIGH();
84
  camStepDelay();
85
  START_HIGH();
86
  CLK_LOW();
87
  
88
  
89
  
90
  while(!(PIND&(1<<CAM_READ)))
91
  {
92
    
93
    CLK_LOW();
94
    camStepDelay();
95
    CLK_HIGH();
96
    camStepDelay();
97
  }
98
  
99
}
100
101
102
void cam_readsend(void){
103
  uint8_t pixel,line,value;
104
  
105
106
  for(line=0;line<123;line++)
107
  {
108
    for(pixel=1;pixel<129;pixel++)
109
    {
110
      CLK_LOW();
111
      
112
      //value = ADC_Read(5);
113
      char Buffer[7];
114
      itoa(ADC_Read(0),Buffer,10);
115
      uart_puts(Buffer);
116
      uart_putc(';');
117
      
118
      camStepDelay();
119
      CLK_HIGH();
120
      camStepDelay();
121
      
122
      
123
    }
124
  }
125
  uart_putc('!');
126
}

1
int main(void)
2
{
3
  
4
5
  DDRD |= (1<<CAM_START);
6
  DDRD |= (1<<CAM_SIN);
7
  DDRD |= (1<<CAM_LOAD);
8
  DDRD |= (1<<CAM_RESET);
9
  DDRD |= (1<<CAM_CLK);
10
  DDRD &= ~(1<<CAM_READ);
11
12
13
  
14
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) );
15
  ADC_Init();
16
  sei();
17
  
18
  //sendData(2);
19
  
20
  cam_getphoto();
21
  
22
  while(1)
23
  {
24
    //TODO:: Please write your application code
25
  }
26
}

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

[OT]
Vorbildlich kommentierter Code...
[/OT]

von Peter II (Gast)


Lesenswert?

Magnus M. schrieb:
> Vorbildlich kommentierter Code...

und ziemlich unvollständig. Viele Funktionen Fehler und auch die 
globalen Variablen.

von Nicole F. (Gast)


Lesenswert?

Peter II schrieb:
> Magnus M. schrieb:
>> Vorbildlich kommentierter Code...
>
> und ziemlich unvollständig. Viele Funktionen Fehler und auch die
> globalen Variablen.

Was fehlt denn?

OK, das hier hätte noch reinmüssen
1
unsigned char camClockSpeed = 0x0A;
2
3
4
5
void camStepDelay(){
6
  unsigned char u=camClockSpeed;
7
  while(u--) {__asm__ __volatile__ ("nop");}
8
}

Der Mega32 wird mit 16MHz getaktet

von Peter II (Gast)


Lesenswert?

Nicole F. schrieb:
> Was fehlt denn?

ADC_Read

von Nicole F. (Gast)


Lesenswert?

Peter II schrieb:
> Nicole F. schrieb:
>> Was fehlt denn?
>
> ADC_Read

Da liegt aber nicht das Problem. Mein Problem ist schon weit vorher. Die 
Kamera signalisiert mir nicht, das ich was zum lesen habe.
Also ist das jetzt erstmal unwichtig.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Nicole F. schrieb:
> void cam_reset(void)
> {
>   RESET_LOW();
>   CLK_LOW();
>   camStepDelay();
>   CLK_HIGH();
>   camStepDelay();
>   CLK_LOW();
>   RESET_HIGH();
>   camStepDelay();
>   RESET_LOW();
>
> }

Dir ist aber schon klar, dass der RESET low-active ist?

von Nicole F. (Gast)


Lesenswert?

Magnus M. schrieb:
> Dir ist aber schon klar, dass der RESET low-active ist?

Stimmt, steht auf Seite 2 im Datenblatt. Das hatte ich ja total 
übersehen.
DANKE!
1
void cam_reset(void)
2
{
3
  RESET_LOW();
4
  CLK_LOW();
5
  camStepDelay();
6
  CLK_HIGH();
7
  camStepDelay();
8
  CLK_LOW();
9
  RESET_HIGH();
10
  
11
12
}

Jetzt komme ich auch aus der While Schleife raus.
Aber irgendwie habe ich nur Müll als Ergbenis.

@ Peter. Jetzt sind wir beim ADC_READ angelangt
1
uint16_t ADC_Read( uint8_t channel )
2
{
3
  
4
  ADMUX = (ADMUX & ~(0x1F)) | (channel & 0x1F);
5
  //ADMUX = channel;
6
  
7
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
8
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
9
  };
10
  return ADCW;                    // ADC auslesen und zurückgeben
11
}

von Nicole F. (Gast)


Lesenswert?

Ich glaube meine cam_write Funktion  ist fehlerhaft

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Nicole F. schrieb:
> @ Peter. Jetzt sind wir beim ADC_READ angelangt

Und wo ist ADC_Init()?

von Peter II (Gast)


Lesenswert?

1
  for(i=0;i<8;i++)
2
  {
3
    CLK_LOW();
4
5
    if((data & 0x04 ) > 0)
6
    SIN_HIGH();
7
    else
8
    SIN_LOW();
9
    data = (data<<1);
10
11
    
12
    camStepDelay();
13
    CLK_HIGH();
14
    camStepDelay();
15
  }
16
[c]
17
18
ich habe keine Ahnung von der  Gameboy Camera, aber der code ist merkwürdig. Hier werden vermutlich 8 bit gesendet. Warum prüft man da auf
19
20
[c]
21
if((data & 0x04 ) > 0)

üblicherweise wird das erste oder letzte bit von data geprüft.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Peter II schrieb:
> ich habe keine Ahnung von der  Gameboy Camera, aber der code ist
> merkwürdig. Hier werden vermutlich 8 bit gesendet. Warum prüft man da
> auf
>
> if((data & 0x04 ) > 0)
>
> üblicherweise wird das erste oder letzte bit von data geprüft.

Das wollte ich auch gerade bemängeln. Sie(?) hat da wohl beim 
Programmieren wohl ein Copy&Paste aus der Registerschreibschleife ein 
paar zeilen darüber gemacht und vergessen die 0x04 nach 0x80 zu ändern. 
Dies sollte Sie natürlich spätestens jetzt nachholen!

Noch ein Tipp:
1
if((reg & 0x04 ) > 0)

Schreib das doch einfach als
1
if(reg & 0x04 )

Selbiges trifft natürlich auf die (data & 0x80) zu.

: Bearbeitet durch User
von Nicole F. (Gast)


Lesenswert?

Magnus M. schrieb:
> Das wollte ich auch gerade bemängeln. Sie(?) hat da wohl beim
> Programmieren wohl ein Copy&Paste aus der Registerschreibschleife ein
> paar zeilen darüber gemacht und vergessen die 0x04 nach 0x80 zu ändern.
> Dies sollte Sie natürlich spätestens jetzt nachholen!

Stimmt, das sollte aber 0x08 heißen, oder?

von Peter II (Gast)


Lesenswert?

Nicole F. schrieb:
> Stimmt, das sollte aber 0x08 heißen, oder?

warum? Du willst doch das höchste bit abfragen oder nicht?

also (1<<7) = 128 = 0x80

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Noch wat:
1
void cam_start(void)
2
{
3
  START_HIGH();
4
  camStepDelay();
5
  CLK_HIGH();
6
  camStepDelay();
7
  START_HIGH();      <-- Das sollte wohl mal ein START_LOW() werden?
8
  CLK_LOW();

von Nicole F. (Gast)


Lesenswert?

Peter II schrieb:
> Nicole F. schrieb:
>> Stimmt, das sollte aber 0x08 heißen, oder?
>
> warum? Du willst doch das höchste bit abfragen oder nicht?
>
> also (1<<7) = 128 = 0x80

:-) stimmt

von Nicole F. (Gast)


Lesenswert?

Hier noch die adc_init
1
void ADC_Init(void)
2
{
3
4
  
5
  ADMUX = (1<<REFS0);
6
  //ADMUX = (1<<REFS1) | (1<<REFS0);
7
  
8
  ADCSRA = (1<<ADPS1) | (1<<ADPS2) | (1<<ADPS0);     
9
  ADCSRA |= (1<<ADEN);                  
10
  
11
  
12
  ADCSRA |= (1<<ADSC);                  
13
  while (ADCSRA & (1<<ADSC) ) {         
14
  }
15
  
16
  (void) ADCW;
17
}
Bie 16MHz CPU Takt musste ich den größten Teiler nehmen

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Hast Du meinen anderen Beitrag auch gelesen und berücksichtigt?

Magnus M. schrieb:
> Noch wat:
(...)

von Nicole F. (Gast)


Lesenswert?

Magnus M. schrieb:
> Hast Du meinen anderen Beitrag auch gelesen und berücksichtigt?
>
> Magnus M. schrieb:
>> Noch wat:
> (...)

Ja, auch diesen Flüchtigkeitsfehler entfernt.

von Peter II (Gast)


Lesenswert?

Nicole F. schrieb:
> Ja, auch diesen Flüchtigkeitsfehler entfernt.

wie kann man nur so viel code schreiben ohne in stückchenweise zu testen 
und in betrieb zu nehmen?
Ich schreibe doch auch keine Betriebssystem und wundere mich an ende 
warum es nicht bootet.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Und wie steht es nach all Dem um die Funktion Deines Konstruktes?

von Nicole F. (Gast)


Lesenswert?

Magnus M. schrieb:
> Und wie steht es nach all Dem um die Funktion Deines Konstruktes?


Noch gefällt es mir nicht. Ich halte die Werte für zu nah beieinander.
1
999;1001;1000;998;998;998;998;999;999;999;1001;998;999;999;999;1001;998;999;999;999;1001;1000;998;998;998;998;999;999;999;1001;998;998;999;999;999;1001;1000;998;998;998;998;998;999;999;999;1001;998;999;999;999;1001;1000;998;998;998;998;998;999;999;999;1001;998;999;999;999;1001;1001;998;998;998;998;998;999;999;999;1001;998;999;999;999;1001;1001;999;998;998;998;998;999;999;999;1001;998;999;999;999;999;1001;998;999;999;999;1001;999;999;999;1001;998;999;999;999;1001;998;999;999;999;1001;1001;998;998;998;998;998;999;999;1001;998;998;999;999;1001;998;999;999;999;1001;1001;999;998;998;998;998;999;999;999;1001;998;999;999;999;1001;1000;998;998;998;998;998;999;999;1001;998;999;999;999;1001;998;999;999;999;1001;1001;998;998;998;998;998;999;999;1001;998;999;999;999;1001;998;999;999;999;1001;1001;999;998;998;998;998;999;999;999;1001;998;999;999;999;1001;1001;1000;998;999;1001;1001;999;998;998;998;998;998;999;999;999;1001;1001;998;998;998;998;998;999;999;999;1001;998;999;999;999;1001;1001;999;998;998;998;!

von Peter II (Gast)


Lesenswert?

Nicole F. schrieb:
> Noch gefällt es mir nicht. Ich halte die Werte für zu nah beieinander.

das ist einfach rauschen vom ADC.

Hast du mal ein Oszi an den Anschluss gehalten, ob sich dort überhaupt 
etwas tut?

Wenn nicht vorhanden, einfach mal eine Wechselspannung an den ADC 
anlegen, dann sollte das ja an den werten erkennbar sein.

von Nicole F. (Gast)


Lesenswert?

Der ADC funktioniert. Die CAM gibt aber nichts raus.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Nicole F. schrieb:
> Der ADC funktioniert. Die CAM gibt aber nichts raus.
1
  cam_write(1,0x0E);  <-- ergibt ein Gain von 45,5dB !

Woher hast du die Registerwerte?

Was gibt deine Kamera aus wenn du die Linse zuhältst?

von Nicole F. (Gast)


Lesenswert?

Es ändert sich nichts. Egal ob ich die Linse zuhalte, oder es gegen 
grelles Licht halte.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

1. Woher hast du eigentlich den ursprünglichen Code...?

2. Warte noch auf eine Antwort auf

Magnus M. schrieb:
> Nicole F. schrieb:
>> Der ADC funktioniert. Die CAM gibt aber nichts raus.
>   cam_write(1,0x0E);  <-- ergibt ein Gain von 45,5dB !
>
> Woher hast du die Registerwerte?

von Nicole F. (Gast)


Lesenswert?

Die Werte sind von hier
http://www.angelfire.com/de3/juliprograms/amr/gbcam.htm

Die erste Frage verstehe ich nicht ganz

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Nicole F. schrieb:
> Die erste Frage verstehe ich nicht ganz

Von wem hast du den Code, den du uns im ersten Posting serviert hast?

von Nicole F. (Gast)


Lesenswert?

Magnus M. schrieb:
> Von wem hast du den Code, den du uns im ersten Posting serviert hast?

Wie von wem habe ich den Code?
Das habe ich geschrieben. Ich hatte lediglich meine Register schreib 
funktion mit dem von ulrich radig's grafikkarten projekt inspirieren 
lassen.
Nachdem meins nicht richtig funktionierte.
Beitrag "Getaktete Übertragung"

von Nicole F. (Gast)


Lesenswert?

Alles gut. Nachdem ich die CLK Frequenz und die Register angepasst habe, 
klappt alles gut.

von Magnus M. (magnetus) Benutzerseite


Lesenswert?

Nicole F. schrieb:
> Wie von wem habe ich den Code?
> Das habe ich geschrieben.

Hmmm... Wenn ich mir den Code im folgenden Link ansehe, hat das Ganze 
einen leicht plagiatartigen Beigeschmack.

http://www.triplay.de/zeigeprojekt.php?id=17#ansteuerung

Nicole F. schrieb:
> Alles gut. Nachdem ich die CLK Frequenz und die Register angepasst
> habe, klappt alles gut.

Ende gut, alles gut.

Herzlichen Glühstrumpf!

;)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.