Forum: Mikrocontroller und Digitale Elektronik STM32 HC-SR04 Ultraschallsensor


von Schweigert V. (schweigert_v)


Lesenswert?

Hallo! Diesmal versuche ich Ultraschallsensor einsteuern.
Pin A0 erzeugt PWM Signal mit Puls-breite 10 ms und Period ungefähr 80ms 
das ist Trigger für Sensor. Dann möchte ich mit TIM2_CH2 Echo Signal 
fangen und zwischen zwei Flanken Zeit messen. Wahrscheinlich könnt mir j 
helfen. herzlichen dank im voraus
1
/**
2
 ******************************************************************************
3
 * @file    main.c
4
 * @author  Ac6
5
 * @version V1.0
6
 * @date    01-December-2013
7
 * @brief   Default main function.
8
 ******************************************************************************
9
 */
10
11
#include "stm32f30x.h"
12
#include "stm32f30x_gpio.h"
13
#include "stm32f30x_rcc.h"
14
#include "stm32f30x_syscfg.h"
15
#include "stm32f30x_exti.h"
16
#include "HC_SR04.h"
17
#include "max7219.h"
18
19
void PORT_Init();
20
volatile uint16_t capture1 = 0, capture2 = 0;
21
22
void Delay_us(uint32_t us) {
23
  volatile uint32_t nCount;
24
  RCC_ClocksTypeDef RCC_Clocks;
25
  RCC_GetClocksFreq(&RCC_Clocks);
26
  nCount = (RCC_Clocks.HCLK_Frequency / 10000) * us;
27
  for (; nCount != 0; nCount--)
28
    ;
29
}
30
31
void PORT_Init(void) {
32
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
33
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
34
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
35
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
36
37
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
38
  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
39
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
40
41
  GPIO_InitTypeDef PIN;
42
  PIN.GPIO_Pin = GPIO_Pin_0; // PWM fuer Trigger
43
  PIN.GPIO_Mode = GPIO_Mode_AF;
44
  PIN.GPIO_OType = GPIO_OType_PP;
45
  PIN.GPIO_Speed = GPIO_Speed_Level_1;
46
  GPIO_Init(GPIOA, &PIN);
47
48
  PIN.GPIO_Pin = GPIO_Pin_5;
49
  PIN.GPIO_Mode = GPIO_Mode_AF;
50
  PIN.GPIO_OType = GPIO_OType_PP;
51
  PIN.GPIO_Speed = GPIO_Speed_Level_1;
52
  GPIO_Init(GPIOA, &PIN);
53
54
  PIN.GPIO_Pin = GPIO_Pin_1; // TIM2_CH2 Eingang
55
  PIN.GPIO_Mode = GPIO_Mode_IN;
56
  PIN.GPIO_PuPd = GPIO_PuPd_DOWN;
57
  PIN.GPIO_Speed = GPIO_Speed_Level_1;
58
  GPIO_Init(GPIOA, &PIN);
59
60
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_1);
61
  GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_1);
62
63
  TIM_TimeBaseInitTypeDef TIM;
64
  TIM.TIM_ClockDivision = TIM_CKD_DIV1;
65
  TIM.TIM_CounterMode = TIM_CounterMode_Up;
66
  TIM.TIM_Prescaler = 7999;
67
  TIM.TIM_Period = 799; // 80 ms
68
  TIM_TimeBaseInit(TIM2, &TIM);
69
70
        // PWM Einstellung
71
  TIM_OCInitTypeDef TIM_OC;
72
  TIM_OCStructInit(&TIM_OC);
73
  TIM_OC.TIM_OCMode = TIM_OCMode_PWM1;
74
  TIM_OC.TIM_OCNPolarity = TIM_OCPolarity_High;
75
  TIM_OC.TIM_OutputState = TIM_OutputState_Enable;
76
  TIM_OC.TIM_Pulse = 90; // Impuls 10 ms
77
  TIM_OC1Init(TIM2, &TIM_OC);
78
  TIM_Cmd(TIM2, ENABLE);
79
80
        // TIM2_CH2 Eingang Einstellung
81
  TIM_ICInitTypeDef TIM_IC;
82
  TIM_IC.TIM_Channel = TIM_Channel_2;
83
  TIM_IC.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
84
  TIM_IC.TIM_ICSelection = TIM_ICSelection_DirectTI;
85
  TIM_IC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
86
  TIM_IC.TIM_ICFilter = 0;
87
  TIM_ICInit(TIM2, &TIM_IC);
88
89
  TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
90
  NVIC_EnableIRQ(TIM2_IRQn);
91
92
}
93
94
95
void TIM2_IRQHandler() {
96
97
  while (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) {
98
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
99
    capture1 = TIM_GetCapture1(TIM2);
100
  }
101
102
  while (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) {
103
    TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
104
    capture2 = TIM_GetCapture1(TIM2);
105
  }
106
107
}
108
109
int main(void) {
110
111
  PORT_Init();
112
  Init_SPI();
113
  Init_7219();
114
  uint32_t dist = capture2 - capture1; // 
115
116
  while (1) {
117
118
    for (int i = 0; i <= 1000; i++) {
119
120
      int dist1 = dist % 10;
121
      int dist2 = dist % 100 / 10;
122
      int dist3 = dist % 1000 / 100;
123
124
      Send_7219(1, dist1);
125
      Send_7219(2, dist2);
126
      Send_7219(3, dist3);
127
      Delay_us(50);
128
    }
129
  }
130
}

von Wolfgang (Gast)


Lesenswert?

Sinnvollerweise solltest du Messung und Ausgabe synchronisieren.

von Schweigert V. (schweigert_v)


Lesenswert?

Und können Sie mir sagen wie?

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


Lesenswert?

Schweigert V. schrieb:
> void TIM2_IRQHandler() {
>
>   while (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) {
>     TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
>     capture1 = TIM_GetCapture1(TIM2);
>   }
>
>   while (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) {
>     TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
>     capture2 = TIM_GetCapture1(TIM2);
>   }
>
> }

Wie soll das funktionieren? Da ist keinerlei Unterschied zwischen den 
beiden Möglichkeiten und die ISR wird sich immer für Fall 1 entscheiden. 
Zwei Flanken können so nicht klappen.

Schweigert V. schrieb:
> PIN.GPIO_Pin = GPIO_Pin_0; // PWM fuer Trigger
>   PIN.GPIO_Mode = GPIO_Mode_AF;
>   PIN.GPIO_OType = GPIO_OType_PP;
>   PIN.GPIO_Speed = GPIO_Speed_Level_1;
>   GPIO_Init(GPIOA, &PIN);
>
>   PIN.GPIO_Pin = GPIO_Pin_5;
>   PIN.GPIO_Mode = GPIO_Mode_AF;
>   PIN.GPIO_OType = GPIO_OType_PP;
>   PIN.GPIO_Speed = GPIO_Speed_Level_1;
>   GPIO_Init(GPIOA, &PIN);

Noch ein Tip. Wenn mehr als ein Pin auf die gleiche Funktion gesetzt 
werden sollen, geht auch so etwas:
1
  PIN.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_5;
2
  PIN.GPIO_Mode = GPIO_Mode_AF;
3
  PIN.GPIO_OType = GPIO_OType_PP;
4
  PIN.GPIO_Speed = GPIO_Speed_Level_1;
5
  GPIO_Init(GPIOA, &PIN);

: Bearbeitet durch User
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.