Gameboy Camera READ Problem

Gast #4081443
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
}
Gast #4081466
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
Gast #4081507
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
}
Gast #4081537
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.
Persönliche Seite #4081559
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.
Gast #4081564
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?
Gast #4081583
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
Gast #4081614
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;!
Gast #4081619
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.
Persönliche Seite #4082915
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!

;)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren