Forum: Mikrocontroller und Digitale Elektronik SRF08 Ansteuerung funktioniert nicht


von Andreas S. (schunki)


Lesenswert?

Hallo zusammen!

Ich schreibe derzeit an meiner Studienarbeit und muss dabei mehrere 
Ultraschallsensoren über einem µC ansteuern und die Messwerte 
weiterverarbeiten.
Da ich in der Programmierung von µC noch nicht so fit bin, wollte ich 
zuerst mal nur einen Sensor ansteuern. Mein Ziel war es den auf ein 
STK500 Board gesteckten Atmega32 so zu programmieren, dass ich vorerst 
ein Byte mit einem bestimmten Bitmuster setzte (Low_Byte) dieses 
Bitmuster kann ich mir durch drücken eines Tasters (S5) auf den LED 
anzeigen lassen.
Nach betätigen des Tasters S0 soll nun die Messung ausgelöst werden. 
Kurz warten.... dann S1 betätigen welcher bewirken soll, dass der 
Messwert des Register 3 ausgelesen und in die Varriable Low_Byte 
geschrieben wird. Diese kann ich mir dann wieder über S5 neu auf den 
LEDs anzeigen lassen. Allerdings ist nach der Messung der Wert der Var 
Low_Byte=11111111, da keine LED mehr leuchtet.

Hier mal mein Code:
1
#ifndef   F_CPU        
2
#define   F_CPU 8000000UL
3
#endif
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
8
#define I2C_DDR      DDRC          // Register für die I2C Kommunikation
9
#define I2C_DDR_REG_BIT  DDC7          //
10
#define I2C_PORT    PORTC          // I2C Port definition
11
12
#define SCL        PC6            // Port C Pin 6
13
#define SDA        PC7            // Port C Pin 7
14
15
#define SDA_LESE_PIN   PINC
16
#define SDA_LESE_BIT   SDA
17
18
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
19
void sda_low()
20
{
21
  I2C_PORT     &=  ~(1<<SDA);          // internen Pull-Up aus
22
  I2C_DDR     |=   (1<<I2C_DDR_REG_BIT);  // Pin von SDA als Ausgang
23
24
}
25
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
26
void sda_high()
27
{
28
  I2C_DDR     &= ~(1<<I2C_DDR_REG_BIT);    // Pin von SDA als Eingang 
29
  I2C_PORT     |=  (1<<SDA);          // internen Pull-Up an 
30
} 
31
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
32
////////////////////////////////////////////////////////////////////////////////////////////
33
34
#define I2C_SCL_LOW    I2C_PORT &= ~(1 << SCL)  // Clock Low Output
35
#define I2C_SCL_HIGH  I2C_PORT |=  (1 << SCL)  // Clock High Output
36
37
#define I2C_SDA_LOW    sda_low()        // Daten Leitung Low
38
#define I2C_SDA_HIGH  sda_high()        // Daten Leitung High
39
40
#define  ACK        0            // Ack empfangen
41
#define  NACK      1            // Ack nicht empfangen
42
43
#define S_DELAY      _delay_loop_1(1);    // ca. 2.76µs H-Time
44
#define M_DELAY      _delay_us(1);
45
#define DELAY      _delay_ms(1);      
46
47
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
48
unsigned char i2c_try_scl(unsigned char start_trials)
49
{
50
  // 10 Mal kurz warten, wenn SCL auf LOW gehalten wird
51
  while((!SCL) && (start_trials <50))
52
  {
53
    start_trials++;
54
    S_DELAY;
55
  }
56
  if(!SCL) return 0 ; return 1;
57
}
58
59
void i2c_master_stop(void);
60
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
61
62
////////////////////////////////////////////////////////////////////////////////////////////
63
// I2C-Master Interface Standard Routinen
64
////////////////////////////////////////////////////////////////////////////////////////////
65
void i2c_master_init(void)
66
{
67
  I2C_DDR |=  (1<<SCL);              // SCL Leitung als Ausgang definieren
68
    S_DELAY;
69
  I2C_SCL_HIGH;                // Cockleitung auf H setzen
70
  I2C_SDA_HIGH;                // Datenleitung auf H setzen
71
    S_DELAY;                // kurz warten
72
  i2c_master_stop();
73
}
74
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
75
void i2c_master_clk_toggle(void)
76
{
77
  i2c_try_scl(0x0A);
78
79
  I2C_SCL_HIGH;
80
    S_DELAY;
81
    S_DELAY;
82
  I2C_SCL_LOW;
83
     S_DELAY;
84
}
85
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
86
void i2c_master_start(void){
87
  // Übergang von H->L auf SDA, wobei SCL H ist.
88
  i2c_try_scl(0x0A);
89
90
  I2C_SDA_HIGH;      // SDA vorsichtshalber auf HIGH ziehen
91
  //  S_DELAY;
92
  I2C_SCL_HIGH;      // SCL auf High  
93
    S_DELAY;
94
  I2C_SDA_LOW;      // SDA auf Low ziehen
95
    M_DELAY;
96
    M_DELAY;
97
    M_DELAY;
98
  I2C_SCL_LOW;      // SCL auf low
99
    S_DELAY;
100
}
101
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
102
void i2c_master_stop(void)    
103
{
104
  // Übergang von L->H auf SDA, wobei SCL H ist.
105
  i2c_try_scl(0x0A);
106
    S_DELAY;
107
  I2C_SDA_LOW;      // SDA vorsichtshalber auf LOW ziehen
108
    S_DELAY;      // Kurz abwarten
109
  I2C_SCL_HIGH;      // SCL auf High setzen
110
    S_DELAY;    
111
  I2C_SDA_HIGH;      // SDA von L auf H ziehen
112
    S_DELAY;
113
}
114
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
115
unsigned char i2c_master_write(unsigned char b)
116
{  
117
  char i=0;
118
  for(i=0;i<8;i++)
119
  {
120
    if (b & 0x80)              // Wenn höchstes Bit=1 
121
    {
122
      I2C_SDA_HIGH;
123
    }
124
    else                        // Wenn höchstes Bit=0
125
    {
126
      I2C_SDA_LOW;
127
    }
128
    b=b<<1;                     // Daten Linksshift
129
    S_DELAY;
130
    i2c_master_clk_toggle();
131
  }
132
  // Auf ACK vom Slave Prüfen   
133
  I2C_SDA_HIGH;
134
  i2c_master_clk_toggle();                                                                                                                       
135
  if(SDA==1)  
136
  {
137
    return 0;
138
  }
139
  else
140
  { 
141
    return 1;
142
  }  
143
}
144
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
145
unsigned char i2c_master_read(unsigned char a)
146
{  
147
  unsigned char i,c=0b00000000;
148
  I2C_SDA_HIGH;      
149
150
  for(i=0;i<8;i++)    
151
  {
152
    c=c<<1;        
153
154
    // Bitweise OR verknüpfen mit dem Eingang, MSB zuerst
155
    if(SDA_LESE_PIN & (1 << SDA_LESE_BIT)) c|=1;      
156
    i2c_master_clk_toggle();
157
  }
158
159
  // ACK oder NACK | ACK=0; NACK=1
160
  if(a==ACK)  {I2C_SDA_LOW;} else {I2C_SDA_HIGH;}  
161
  i2c_master_clk_toggle();
162
  return c;
163
}
164
165
166
int main(void)
167
{   DDRD=0b00000000;
168
  DDRB=0b11111111;
169
  uint8_t low_byte=0b00001000;
170
  
171
    while(1)
172
    {
173
    switch(PIND){
174
      case 0b11111110:
175
        PORTB=0b00000000;
176
        i2c_master_start();
177
        i2c_master_write(0xE0);
178
        i2c_master_write(0x00);
179
        i2c_master_write(0x51);
180
        i2c_master_stop();
181
        break;
182
      
183
      case 0b11111101:
184
        i2c_master_start();
185
        i2c_master_write(0xE0);
186
        i2c_master_write(0x03);
187
        i2c_master_stop();
188
        i2c_master_start();
189
        i2c_master_write(0xE1);
190
        low_byte=i2c_master_read(1);
191
        i2c_master_stop();
192
        break;
193
              
194
      case 0b11011111:
195
        PORTB=low_byte;
196
        break;
197
      
198
      default: 
199
        PORTB=0b11111111;
200
        
201
  
202
    }          
203
    }
204
  
205
}

Es wäre super, wenn mir mal jemand auf die Sprünge helfen könnte, da ich 
jetzt schon seit Tagen versuche, dass sich mein Sensor mit meinem µC 
unterhalten kann!

Vielen Dank schon mal im voraus!


Gruß
Andreas

: Verschoben durch User
von MWS (Gast)


Lesenswert?

Da würde ich zuerst mal schauen, ob die Soft-I2C überhaupt funktioniert, 
also die Version über Register 0 lesen. Wenn das klappt, die Messung 
selbständig mit einem Delay dazwischen ablaufen lassen. Was denkst Du 
wie schnell bei einem Tastendruck die entsprechende Sequenz in den 
Baustein ohne Rücksicht auf Verluste reingeprügelt wird ? Außerdem würde 
ich die Messung auslösen, wie im DB beschrieben auf Register 0 pollen 
und dann gleich das Ergebnis auslesen und anzeigen. Die im Modul 
eingebaute Led blitzt laut DB bei einem US-Burst auf, passiert das ?

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.