Forum: Mikrocontroller und Digitale Elektronik sharp gp2d02 mit STM32F303 programieren


von Ramazan T. (laptoprepair)


Lesenswert?

Hallo

Wir haben ein Projekt und müssen es bis Montag fertig machen.Bitte hilft 
uns.Wir müssen einen Sharp GP2d02 mit STM32F303 programmieren.Wir haben 
es fast fertig aber haben immer noch probleme.Das Program funtioniert 
zur Zeit nur bei einem bestimmten Distanz.Bitte Bitte helft uns

von Christopher J. (christopher_j23)


Lesenswert?

Ramazan T. schrieb:
> Wir müssen einen Sharp GP2d02 mit STM32F303 programmieren.Wir haben
> es fast fertig aber haben immer noch probleme.Das Program funtioniert
> zur Zeit nur bei einem bestimmten Distanz.

Soll das eine Infrarotfernsteuerung werden oder was? Wie soll man denn 
jemandem helfen, der nicht einmal genau sagt bei was er Hilfe benötigt?

von Ramazan T. (laptoprepair)


Lesenswert?

GP2D02 ist ein Infarotsensor.Wir sollen es mit STM32 programmieren.Also 
je nach Abstand sollen wir einen Tonintervall ausgeben lassen und 
gleichzeit einen LED mittels PWM ansteuern.

von Christopher J. (christopher_j23)


Lesenswert?

Und wo ist jetzt das Problem?

von Ramazan T. (laptoprepair)


Angehängte Dateien:

Lesenswert?

Aufgabenstellung

Es soll Abstandswarner mit Multicolor Warnlicht und Tonausgabe 
entwickelt werden.

Dabei gelten folgende Beziehungen zwischen Farbgebung/Toninterval

Habe Bilder hochgelanden

von Dr. Sommer (Gast)


Lesenswert?

Was genau erwartest du jetzt von uns?
1. Dass wir dir eine komplette Lösung geben?
2. Dass wir die ersten Punkte implementieren?
3. Dass wir dir sagen dass du deine Hausaufgaben selbst machen sollst?
4. Dass wir dir jede Information einzeln aus der Nase ziehen sollen um 
zu erfahren wo genau das Problem liegt?

von Christopher J. (christopher_j23)


Lesenswert?

Ok, jetzt hast du die Aufgabenstellung geschildert und man weiß um was 
es geht aber wo genau es jetzt hängt, das hast du nicht verraten.

von Ramazan T. (laptoprepair)


Lesenswert?

Das Problem ist ,z.B steht im array 0101000 (also 80 in dezimal),aber 
laut Datenblatt müsste ich dafür etwa 100-120cm entfernt sein,ich habe 
aber genau davor gesessen.Also die Auswertung ist leider falsch.

von Ramazan T. (laptoprepair)


Lesenswert?

Das ist unser Code



#include "stm32f3xx.h"
//T=0.5ms; ein Impuls=350*T 
Impulsfunktion=500+16,66*x(=abstand)~500+17*x
//Sensor Enfernung~1500/X, X=Augabewert des Sensors
//LEDS an Pins A15, B4 und B6; SharpIn an Pin C1 SharpOut an Pin F0, 
Trigger fürs messen ist Pin A1
//Funktion für LED 10|70|130+-1,66*abstand~10|70|130+-2*abstand; 
Lautstrecher an Pin A0
//Sensor im interrtupt: laufvariable, die bei unter 70ms den pin auf 
low,bei 70 ms anfängt zu toggeln und nach 71,6ms Pin auf high setzt
//Probleme: Ansteuerung fehlerhaft | Zusatzaufgaben?
int abstand=65; //licht
int anfang=0;
int entfernung=0;
int timer=0;
char Sharp[8];
int test=70; //zurzeit die entferung in cm für ton
int tonzahl=0;
int zusatz=0;

void delay(void);
void ArrayLeer(void){
  for(int i=0;i<7;i++){
     Sharp[i]=0;
  }
}
void zahlLesen(void){
  for(int i=8;i>1;i--){
    entfernung+=(2^i)*Sharp[i-1];      //konvertierung von binär zu 
dezimal
  }
}
void licht(int *zahl){
      if(*zahl<11){
      TIM3->CCR1 = 60;
      GPIOB->ODR |= GPIO_ODR_4;
      }
      else if(*zahl>10 && *zahl<71){
      TIM3->CCR1 = (70-*zahl);
      TIM4->CCR1 = (*zahl-11);
      TIM2->CCR1 = 0;
      }else if(*zahl>70 && *zahl<131){
        TIM3->CCR1= 0;
        TIM4->CCR1 = 130-(*zahl);
        TIM2->CCR1 = (*zahl-70);
      }
          else if (*zahl>130){
            TIM3->CCR1 = 0;
             TIM4->CCR1 = 0;
            TIM2->CCR1 = 60;
      }
}
void sensor(int *zeit){
  if(*zeit<1){
     GPIOC->ODR |= GPIO_ODR_1;
  }
  else if(*zeit<1400 && *zeit>0){
     GPIOC->ODR &= ~(GPIO_ODR_1);
  }
  else if (*zeit>1400){

         switch(*zeit){
       case 1401:
       case 1405:
       case 1409:
       case 1413:
       case 1417:
       case 1421:
       case 1425:
       case 1429:
         GPIOC->ODR |= GPIO_ODR_1;

         break;
      default :
         GPIOC->ODR &= ~(GPIO_ODR_1);

       }}
         else if(*zeit>1430 &&*zeit<1450){
           GPIOC->ODR |= GPIO_ODR_1;

         }
         else if(*zeit>1500){
                  *zeit=0;
                }
}
void ton(int *der, int *die){ //abstand, tonzahl
  if(*die<(850+ *der+ *der+ *der+ *der+ *der+ *der+ *der+ *der+ *der+ 
*der + *der+ *der+ *der+ *der+ *der+ *der+ *der)){
        GPIOA->ODR ^= GPIO_ODR_0; //toggeln für den Lautsprecher
      }
    else {
      *die=0;
    }

}

int main(void)
{
  RCC->AHBENR |= RCC_AHBENR_GPIOAEN;
  RCC->AHBENR |= RCC_AHBENR_GPIOBEN;
  RCC->AHBENR |= RCC_AHBENR_GPIOCEN;
  RCC->AHBENR |= RCC_AHBENR_GPIOFEN;
  GPIOC->MODER |= GPIO_MODER_MODER2_0;
  GPIOA->MODER |= GPIO_MODER_MODER0_0;
  GPIOA->MODER |= GPIO_MODER_MODER15_1;
  GPIOB->MODER |= GPIO_MODER_MODER4_1;
  GPIOA->MODER |= GPIO_MODER_MODER6_1;
  GPIOB->MODER |= GPIO_MODER_MODER6_1;
  GPIOC->MODER |= GPIO_MODER_MODER1_0;
  GPIOF->PUPDR |= (1 << 3);  //PF1 ist down
  GPIOF->PUPDR |= 0b1;    //PF0 ist pulldown

  GPIOC->ODR |= GPIO_ODR_1;    //zum ansteuern braucht es ein kurzes 
high

  SYSCFG->EXTICR[0] = 0;      // PA1 an EXTI1
  EXTI->IMR |= EXTI_IMR_MR1;    // EXTI1 freigeben
  EXTI->RTSR |= EXTI_RTSR_TR1;    // EXTI1: steigende Flanke
  GPIOA->PUPDR |= (1 << 3);    // Pull-Down fuer PA1
  NVIC_EnableIRQ(EXTI1_IRQn);

  RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;
  GPIOA->AFR[1] |= (1<<28) ;  //Pin A15 als alternative Funktion 1
  TIM2->CCMR1 |= (11<<5);       //PWM mode 1
  TIM2->CCER = TIM_CCER_CC1E;      //Compare modus
  TIM2->PSC = 99;
  TIM2->ARR = 60;        // 0.75ms @ 8Mhz
  TIM2->CR1 = TIM_CR1_CEN;

  RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;
  GPIOB->AFR[0] |= (1<<25) ;  //Pin B6 als alternative Funktion 2
  TIM4->CCMR1 |= (11<<5);       //PWM mode 1
  TIM4->CCER = TIM_CCER_CC1E;      //Compare modus
  TIM4->PSC = 99;
  TIM4->ARR = 39;        // 0.5ms @ 8Mhz
  TIM4->CR1 = TIM_CR1_CEN;

  RCC->APB1ENR |= RCC_APB1ENR_TIM3EN;
  GPIOB->AFR[0] |= (1<<17) ;  //Pin B4 als alternative Funktion 2

  GPIOA->AFR[0] |= (1<<25) ;  //Pin A6 als alternative Funktion 2
  GPIOC->AFR[0] |= (1<<25) ;  //Pin C6 als alternative Funktion 2

    TIM3->CCMR1 |= (11<<5);       //PWM mode 1
    TIM3->CCER = TIM_CCER_CC1E;      //Compare modus
    TIM3->PSC = 99;
    TIM3->ARR = 60;        // 0.75ms @ 8Mhz
    TIM3->CR1 = TIM_CR1_CEN;

    RCC->APB2ENR |= RCC_APB2ENR_TIM16EN;
    TIM16->DIER = TIM_DIER_UIE;        // Update-Interrupt ein
    TIM16->PSC = 99;
    TIM16->ARR = 3;            //  0,05ms @ 8 MHz
    TIM16->CR1 = TIM_CR1_CEN;        // Timer ein

    NVIC_EnableIRQ(TIM1_UP_TIM16_IRQn);

    RCC->APB2ENR |= RCC_APB2ENR_TIM17EN;
    TIM17->DIER = TIM_DIER_UIE;        // Update-Interrupt ein
    TIM17->PSC = 7999;
    TIM17->ARR = 249;            // 0,25 s @ 8 MHz
    TIM17->CR1 = TIM_CR1_CEN;        // Timer ein

    NVIC_EnableIRQ(TIM1_TRG_COM_TIM17_IRQn);


    GPIOC->ODR &= ~(GPIO_ODR_1); //zum ansteuern des sensors wird nach 
dem start high ein low für min 70ms gebraucht
    delay();
  while(1){
    licht(&abstand);
    // sensor(&timer);
     zahlLesen();
     ton(&abstand, &tonzahl);
     //ton(&entfernung, &tonzahl);

     if(timer<1){
       GPIOC->ODR |= GPIO_ODR_2;
     }else if (timer>1 && timer<3){
       GPIOC->ODR &= ~(GPIO_ODR_2);
     }

     if (timer>1500)
       timer=0;

     __WFI();
}
  return 1;
}
void TIM16_IRQHandler(void)
{
  if(timer<1400){
     GPIOC->ODR &= ~(GPIO_ODR_1);
  }else if(timer>1400 && timer <1418){
     GPIOC->ODR ^= GPIO_ODR_1;
  }else if(timer>1455){
     GPIOC->ODR |= GPIO_ODR_1;
  }
  tonzahl++;
  timer++;
  if (tonzahl>100000){tonzahl=0;}
  TIM16->SR &= ~TIM_SR_UIF;
}

void TIM17_IRQHandler(void)
{
  abstand++;     // abstand inkrementieren
  TIM17->SR &= ~TIM_SR_UIF;
}

void EXTI1_IRQHandler(void){
  if(zusatz>8){
      zusatz=0;
      entfernung=0;
      ArrayLeer();
  }
  Sharp[zusatz]=GPIOF->IDR;
  zusatz++;

  EXTI->PR = EXTI_PR_PR1;              //trigger flag gelöscht
}

void delay(){
  //while(1){
    if(timer>160){
      timer=0;
      //tonzahl=0;
      //abstand=0;
    //  break;
  //  }
  }
}

von Christopher J. (christopher_j23)


Lesenswert?

Ohje, da weiß man garnicht wo man anfangen soll. Mal ein paar Tips:
1. Längeren Code im Forum in den Anhang packen und wenn schon dann in [ 
c ] statt in [ code ] tags packen.
2. Code vernünftig einrücken
3. Code nach Themen gruppieren, z.B. eine Funktion gpio_init() und eine 
Funktion timer_init()
4. Magische Zahlen vermeiden , also so etwas wie XYZ->ABC = 0x42;
5. Mit Aufgabe Nr.9 Anfangen
6. WTF?

Ramazan T. schrieb:
> void ton(int *der, int *die){ //abstand, tonzahl
>   if(*die<(850+ *der+ *der+ *der+ *der+ *der+ *der+ *der+ *der+ *der+
> *der + *der+ *der+ *der+ *der+ *der+ *der+ *der))

von Ramazan T. (laptoprepair)


Angehängte Dateien:

Lesenswert?

Code habe ich jetzt als Anhang angehängt.Ja ich fange dann mal mit 
Aufgabe 9 an , hatte aber leider bissher kein Programmablaufplan 
erstellt.Also weiss ich leider nicht wie es geht bzw. nicht bei solchen 
komplizierten Programmcode

von Ramazan T. (laptoprepair)


Lesenswert?

Kann mir bitte jemand weiter helfen.Ich kriege diesen Programmablaufplan 
einfach nicht hin.Habe es bei so ein großen Programmcode nicht gemacht 
bzw.einen Code zur Ansteuerung von Mikrocontrollern.

von pegel (Gast)


Lesenswert?

Ramazan T. schrieb:
> steht im array 0101000 (also 80 in dezimal)

Da geht es schon los:

0101000 -> 0x28 -> 40

Ramazan T. schrieb:
> Bitte Bitte helft uns

Ramazan T. schrieb:
> weiss ich leider nicht wie es geht

Ramazan T. schrieb:
> Kann mir bitte jemand weiter helfen

Sieh es einfach ein:
Nicht jeder ist für jede Aufgabe geeignet.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Da ist viel zu viel hardcodierter Unsinn drin, und irgendwie habt ihr 
missverstanden, wie der Sharp nun sein Datum ausgibt.

1. VIn wird auf low gelegt, um den Messvorgang zu starten.
2. Nach etwa 70ms hebt Sharp Vout auf high, um das Ende der Messung 
anzuzeigen.
3.Nun wird VIn für höchstens 200µs gepulst, und mit ingesamt 8 Pulsen 
auf der steigenden Flanke das Datum auf VOut eingelesen , MSB zuerst.
4.Der letzte Puls fürs LSB auf VIn ist länger als 1500µs, Sharp 
antwortet daraufhin noch mal mit einem positiven Puls. Weitere kurze 
200µs Pulse auf Vin geben wiederholt das LSB aus.

5.Wenn man nun VIn auf high lässt, geht der Sensor wieder ins Powerdown.

Hier ein kurzes AVR-ASM Routinchen dafür:
1
;  make a single measurement
2
measure:
3
  cbi  PORTB,Vin  ; start sensor
4
  ldi  del,w70msec     ; wait 70ms
5
  rcall  wozwait
6
measa:  sbis  PINB,Vout  ; wait for a high 
7
  rjmp  measa
8
  sbi  PORTB,Vin         ; raise VIn
9
  rcall  w100            ; wait 100µs
10
  cbi  PORTB,Vin         ; lower it again 
11
  clr  result            ; zero out result
12
  ldi  counter,8         ; 8 bits to receive
13
measb:  rcall  w100
14
  sbic  PINB,Vout        ; read the data
15
  ori  result,0x01       ; shift a 1 into the result
16
  lsl  result
17
  sbi  PORTB,Vin         ; 
18
  rcall  w100
19
  cbi  PORTB,Vin
20
  dec  counter
21
  brne  measb
22
  rcall  w100
23
  sbi  PORTB,Vin
24
  ret

: Bearbeitet durch User
von pegel (Gast)


Lesenswert?

Matthias S. schrieb:
> Hier ein kurzes AVR-ASM Routinchen dafür:

In meiner Glaskugel sehe ich ein paar Köpfe explodieren ;)

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

pegel schrieb:
> In meiner Glaskugel sehe ich ein paar Köpfe explodieren ;)

Wird schon passiert sein, da die Jungs ja heute ihr Projekt abgeben 
mussten, was ihnen ja verdammt früh eingefallen ist.

Tja, in C hatte ichs gerade nicht da...

von Ramazan T. (laptoprepair)


Lesenswert?

Habe es schon hinbekommen ohne eure Hilfe hier.Sry aber es gibt hier 
echt arrogante Leute die denken die wären was besseres.

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.