sharp gp2d02 mit STM32F303 programieren

OP #5284473
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
Gast #5284500
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?
OP #5284507
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;
  //  }
  }
}
#5284521
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))
(Firma: matzetronics) #5288232
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

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