0 / 0 / 2
Регистрация: 24.04.2018
Сообщений: 61
1

Stm32 hcsr04 Ультразвуковой датчик

09.06.2019, 21:10. Показов 1715. Ответов 8

День добрый! Может кто сможет помоч? Никак не могу получить значения расстояния! Использую STM32F303 и HC-SR04. На форуме есть похожая тема, но она мне никак не помогла. Мне кажеться я что то с таймерами не так делаю, именно захват не работает. импульс в 10 мс идет, эхо есть, тоесть на осцилографе видно изменение при смене растояния!

Настройки для датчика
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/*
 * stm32f30x_HC-SR04.c
 *
 *  Created on: 02.06.2019
 *      Author: schweigert
 */
 
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_spi.h"
#include "stm32f30x_exti.h"
#include "stm32f30x_tim.h"
 
#include "HC-SR04.h"
#include "max7219.h"
 
void Delay_us(uint32_t us);
 
volatile uint8_t capture_is_first = 1, capture_is_ready = 0;
 
void HC_Init(void) {
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4, ENABLE);
 
    GPIO_InitTypeDef Init_PORT;
    // Eingang PB6 TIM4  (Echo_Pin)
    Init_PORT.GPIO_Pin = GPIO_Pin_6;
    Init_PORT.GPIO_Speed = GPIO_Speed_10MHz;
    Init_PORT.GPIO_Mode = GPIO_Mode_AF;
    Init_PORT.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOA, &Init_PORT);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource6, GPIO_AF_10);
 
    // Ausgang PB7  (Trig_Pin)
    Init_PORT.GPIO_Pin = GPIO_Pin_7;
    Init_PORT.GPIO_Speed = GPIO_Speed_10MHz;
    Init_PORT.GPIO_Mode = GPIO_Mode_OUT;
    Init_PORT.GPIO_OType = GPIO_OType_PP;
    Init_PORT.GPIO_PuPd = GPIO_PuPd_DOWN;
    GPIO_Init(GPIOB, &Init_PORT);
 
    RCC_ClocksTypeDef RCC_ClocksStatus;
    RCC_GetClocksFreq(&RCC_ClocksStatus); // 1 tick = 1 mcs
    uint16_t prescaler = RCC_ClocksStatus.SYSCLK_Frequency / 1000000 - 1;
 
    //
 
    TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct;
    TIM_TimeBaseInitStruct.TIM_Prescaler = prescaler;
    TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;
    TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);
 
    //Chanel 1 TIM4
    TIM_ICInitTypeDef TIM_ICInitStruct;
    TIM_ICInitStruct.TIM_Channel = TIM_Channel_1;
    TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
    TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_ICInitStruct.TIM_ICFilter = 0;
    TIM_ICInit(TIM4, &TIM_ICInitStruct);
    TIM_ITConfig(TIM4, TIM_IT_CC1, ENABLE);
 
}
 
void Delay_us(uint32_t us) {
    volatile uint32_t nCount;
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);
    nCount = (RCC_Clocks.HCLK_Frequency / 100000) * us;
    for (; nCount != 0; nCount--)
        ;
}
 
 
uint16_t GetDistance() {
 
    uint16_t anfang = 0, ende = 0;
    NVIC_EnableIRQ(TIM4_IRQn);
    TIM_Cmd(TIM4, ENABLE);
 
    GPIO_SetBits(GPIOB, GPIO_Pin_7);
    Delay_us(90); // 10 мс ждем
    GPIO_ResetBits(GPIOB, GPIO_Pin_7);
 
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
        anfang = TIM_GetCapture1(TIM4); // первое значение
 
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    }
 
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
        ende = TIM_GetCapture1(TIM4); // второе значение
 
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    }
 
    TIM_Cmd(TIM4, DISABLE);
 
return ((ende-anfang)/58); // возвращаем расстояние в см
}

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
 ******************************************************************************
 * @file    main.c
 * @author  Ac6
 * @version V1.0
 * @date    01-December-2013
 * @brief   Default main function.
 ******************************************************************************
 */
 
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_spi.h"
#include "stm32f30x_exti.h"
 
#include "max7219.h"
#include "HC-SR04.h"
 
int main() {
    uint16_t dist = 0;
    Init_SPI(); // настройка SPI для отправки на 7 сегм. индикатор
    Init_7219(); // настройка передачи
    HC_Init(); // настройка для датчика
 
    while (1) {
        dist = GetDistance(); // получили дистанцию
 
        int dist1 = dist % 10; // разбили на 3 цифры
        int dist2 = dist % 100 / 10;
        int dist3 = dist % 1000 / 100;
 
        Send_7219(1, dist1); // отправили каждую цифру в свой сегмент
        Send_7219(2, dist2);
        Send_7219(3, dist3);
        Delay_us(600);
 
    }
}

Тут все работает!!
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "max7219.h"
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_spi.h"
 
#define cs_ON() GPIO_ResetBits(GPIOD, GPIO_Pin_2);
#define cs_OFF() GPIO_SetBits(GPIOD, GPIO_Pin_2);
 
char dg = 8;
 
void Init_SPI(void) {
 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
 
    GPIO_InitTypeDef PORT;
    PORT.GPIO_Pin = GPIO_Pin_10; //10:SCK->CLK
    PORT.GPIO_Speed = GPIO_Speed_Level_1;
    PORT.GPIO_Mode = GPIO_Mode_AF;
    PORT.GPIO_OType = GPIO_OType_PP;
    PORT.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &PORT);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_6);
 
    PORT.GPIO_Pin = GPIO_Pin_12; // 12:MOSI->DIN
    PORT.GPIO_Speed = GPIO_Speed_Level_1;
    PORT.GPIO_Mode = GPIO_Mode_AF;
    PORT.GPIO_OType = GPIO_OType_PP;
    PORT.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &PORT);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_6);
 
    PORT.GPIO_Pin = GPIO_Pin_2; // SS->CS
    PORT.GPIO_Speed = GPIO_Speed_Level_1;
    PORT.GPIO_Mode = GPIO_Mode_OUT;
    PORT.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOD, &PORT);
    GPIO_SetBits(GPIOD, GPIO_Pin_2);
 
    PORT.GPIO_Pin = GPIO_Pin_5; // SS->CS
    PORT.GPIO_Speed = GPIO_Speed_Level_1;
    PORT.GPIO_Mode = GPIO_Mode_OUT;
    //PORT.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOA, &PORT);
 
 
    SPI_InitTypeDef SPIConf;
    SPIConf.SPI_Direction = SPI_Direction_1Line_Tx;
    SPIConf.SPI_Mode = SPI_Mode_Master;
    SPIConf.SPI_DataSize = SPI_DataSize_16b;
    //SPIConf.SPI_CRCPolynomial = 7;
    SPIConf.SPI_CPOL = SPI_CPOL_Low;
    SPIConf.SPI_CPHA = SPI_CPHA_1Edge;
    SPIConf.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
    SPIConf.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    SPIConf.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_Init(SPI3, &SPIConf);
    SPI_Cmd(SPI3, ENABLE);
    SPI_NSSInternalSoftwareConfig(SPI3, SPI_NSS_Soft);
}
 
//------------------------------------------------------
 
void Send_7219(uint8_t rg, uint8_t dt) {
    cs_ON()
    ;
    while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
        ;
    SPI_I2S_SendData16(SPI3, (((uint16_t) rg << 8) + dt));
    while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) == SET)
        ;
    cs_OFF()
    ;
}
 
void Clear_7219(void) {
 
    Send_7219(0x01, 0x00);
    Send_7219(0x02, 0x00);
    Send_7219(0x03, 0x00);
    Send_7219(0x04, 0x00);
}
 
void Number_7219(volatile long n) {
    uint8_t ng = 0;
    if (n < 0) {
        ng = 1;
        n *= -1;
    }
    uint8_t i = 0;
    do {
        Send_7219(++i, n % 10);
        n /= 10;
    } while (n);
    if (ng) {
        Send_7219(i + 1, 0x0A);
    }
}
 
void Init_7219(void) {
    Send_7219(0x0F, 0x00);
    Send_7219(0x0C, 0x01);
    Send_7219(0x0B, 0x03);
    Send_7219(0x0A, 0x0A);
    Send_7219(0x09, 0xFF);
    Clear_7219();
}
 
void delay(uint32_t us) {
    volatile uint32_t nCount;
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);
    nCount = (RCC_Clocks.HCLK_Frequency / 7200) * us;
    for (; nCount != 0; nCount--)
        ;
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.06.2019, 21:10
Ответы с готовыми решениями:

stm32 + hc-sr04 Ультразвуковой датчик расстояния [решение]
&quot;Спойлер&quot;Особо не пинайте, первая попытка преподнести народу полезную информацию. Если есть...

STM32F030F4 и ультразвуковой датчик HC-SR4
Всем добрый день, пересмотрел разный код по этому датчику. Вроде всё достаточно просто. Написал код...

Ультразвуковой микрофон для STM32
Здравствуйте, помогите пожалуйста выбрать Ультразвуковой (УЗ) микрофон для STM32. Более подробно:...

Ёмкостный датчик касаний на STM32
емкостной сенсор на базе stm32f103vet Конечная цель - что-то похожее на разработку Виктора...

8
866 / 527 / 174
Регистрация: 30.07.2015
Сообщений: 1,727
09.06.2019, 22:36 2
Schweigert, какая то каша. Что должно происходить тут?
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    GPIO_SetBits(GPIOB, GPIO_Pin_7);
    Delay_us(90); // 10 мс ждем
    GPIO_ResetBits(GPIOB, GPIO_Pin_7);
 
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
        anfang = TIM_GetCapture1(TIM4); // первое значение
 
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    }
 
    if (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
        ende = TIM_GetCapture1(TIM4); // второе значение
 
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
    }
вы включили прерывания, при этом у вас нет обработчика прерываний. Потом вы как я понял хотите ждать флаг переполнения - но вы не ждете а один раз проверяете ифом. При этом в режиме захвата надо жать не события переполнения, а непосредственно события захвата.

В Вашем случае надо настроить таймер чтобы он работал постоянно с некой частотой дискретизации. После подачи импульса включить прерывания по событию TIM_IT_CC1. В обработчике прерывания забрать значение таймера когда произошел захват - время номер один, дальше ждем второго события - забираем время номер два. По их разнице получаем время в тиках таймера, умножаем на период дискретизации получаем время импульса.
0
0 / 0 / 2
Регистрация: 24.04.2018
Сообщений: 61
14.06.2019, 01:41  [ТС] 3
Добрый день. Немного изменил свой код. На этот раз работает ШИМ с шириной импульса 10 мс и период 80, но возникли новые проблемы. Я не уверен , что правильно настроил захват. Как мне из обработчика прерываний передать значение времени в main?

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
/**
 ******************************************************************************
 * @file    main.c
 * @author  Ac6
 * @version V1.0
 * @date    01-December-2013
 * @brief   Default main function.
 ******************************************************************************
 */
 
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_syscfg.h"
#include "stm32f30x_exti.h"
#include "HC_SR04.h"
#include "max7219.h"
 
 
 
void PORT_Init();
 
 
 
volatile uint16_t capture1 = 0, capture2 = 0;
 
 
 
void PORT_Init(void) {
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
    GPIO_InitTypeDef PIN;
    PIN.GPIO_Pin = GPIO_Pin_0; // PWM
    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);
 
    PIN.GPIO_Pin = GPIO_Pin_1; // вход для Echo
    PIN.GPIO_Mode = GPIO_Mode_IN;
    PIN.GPIO_PuPd = GPIO_PuPd_DOWN;
    PIN.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_Init(GPIOA, &PIN);
 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_1);
 
    TIM_TimeBaseInitTypeDef TIM;
    TIM.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM.TIM_CounterMode = TIM_CounterMode_Up;
    TIM.TIM_Prescaler = 7999;
    TIM.TIM_Period = 799; // 80 ms
    TIM_TimeBaseInit(TIM2, &TIM);
 
    TIM_OCInitTypeDef TIM_OC;
    TIM_OCStructInit(&TIM_OC);
    TIM_OC.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OC.TIM_OCNPolarity = TIM_OCPolarity_High;
    TIM_OC.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OC.TIM_Pulse = 100; // Impuls 10 ms
    TIM_OC1Init(TIM2, &TIM_OC);
    TIM_Cmd(TIM2, ENABLE);
 
    TIM_ICInitTypeDef TIM_IC; 
    TIM_IC.TIM_Channel = TIM_Channel_1; //Канал 1  для захвата сигнала и определения времени
    TIM_IC.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
    TIM_IC.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_IC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_IC.TIM_ICFilter = 0;
    TIM_ICInit(TIM2, &TIM_IC);
 
    TIM_ITConfig(TIM2, TIM_IT_CC1, ENABLE);
    NVIC_EnableIRQ(TIM2_IRQn);
 
}
 
void TIM2_IRQHandler() {
 
    uint16_t capture1,capture2;
 
    while (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
        capture1 = TIM_GetCapture1(TIM2);
    }
 
    while (TIM_GetITStatus(TIM2, TIM_IT_CC1) != RESET) {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC1);
        capture2 = TIM_GetCapture1(TIM2);
    }
 
}
 
 
int main(void) {
 
    PORT_Init();
    Init_SPI();
    Init_7219();
 
        while (1) {
 
    }
}
Добавлено через 10 минут
Добрый день. Немного изменил свой код. На этот раз работает ШИМ с шириной импульса 10 мс и период 80, но возникли новые проблемы. Я не уверен , что правильно настроил захват. В отладке программа перепрыгивает TIM2_IRQHandler() не останавливается на нем((

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
 ******************************************************************************
 * @file    main.c
 * @author  Ac6
 * @version V1.0
 * @date    01-December-2013
 * @brief   Default main function.
 ******************************************************************************
 */
 
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_syscfg.h"
#include "stm32f30x_exti.h"
#include "HC_SR04.h"
#include "max7219.h"
 
void PORT_Init();
volatile uint16_t capture1 = 0, capture2 = 0;
 
void PORT_Init(void) {
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
    GPIO_InitTypeDef PIN;
    PIN.GPIO_Pin = GPIO_Pin_0; // PWM
    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);
 
    PIN.GPIO_Pin = GPIO_Pin_1;
    PIN.GPIO_Mode = GPIO_Mode_IN;
    PIN.GPIO_PuPd = GPIO_PuPd_DOWN;
    PIN.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_Init(GPIOA, &PIN);
 
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource0, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOA, GPIO_PinSource5, GPIO_AF_1);
 
    TIM_TimeBaseInitTypeDef TIM;
    TIM.TIM_ClockDivision = TIM_CKD_DIV1;
    TIM.TIM_CounterMode = TIM_CounterMode_Up;
    TIM.TIM_Prescaler = 7999;
    TIM.TIM_Period = 799; // 80 ms
    TIM_TimeBaseInit(TIM2, &TIM);
 
    TIM_OCInitTypeDef TIM_OC;
    TIM_OCStructInit(&TIM_OC);
    TIM_OC.TIM_OCMode = TIM_OCMode_PWM1;
    TIM_OC.TIM_OCNPolarity = TIM_OCPolarity_High;
    TIM_OC.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OC.TIM_Pulse = 90; // Impuls 10 ms
    TIM_OC1Init(TIM2, &TIM_OC);
    TIM_Cmd(TIM2, ENABLE);
 
    TIM_ICInitTypeDef TIM_IC;
    TIM_IC.TIM_Channel = TIM_Channel_2;
    TIM_IC.TIM_ICPolarity = TIM_ICPolarity_BothEdge;
    TIM_IC.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_IC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_IC.TIM_ICFilter = 0;
    TIM_ICInit(TIM2, &TIM_IC);
 
    TIM_ITConfig(TIM2, TIM_IT_CC2, ENABLE);
    NVIC_EnableIRQ(TIM2_IRQn);
 
}
 
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);
    }
 
}
 
 
int main(void) {
 
    PORT_Init();
    Init_SPI();
    Init_7219();
    uint16_t dist = capture2 - capture1;
    int dist1 = dist % 10;
    int dist2 = dist % 100 / 10;
    int dist3 = dist % 1000 / 100;
 
    Send_7219(1, dist1);
    Send_7219(2, dist2);
    Send_7219(3, dist3);
 
    while (1) {
 
    }
}
0
866 / 527 / 174
Регистрация: 30.07.2015
Сообщений: 1,727
14.06.2019, 09:30 4
Schweigert, во первых, если весь период 80 то, чтобы импульс был 10 мс надо делать так
C
1
 TIM_OC.TIM_Pulse = 10-1; // Impuls 10 ms
Во вторых, циклы в прерываниях не нужны и я бы сделал примерно так:
C
1
2
3
4
5
6
7
    TIM_ICInitTypeDef TIM_IC;
    TIM_IC.TIM_Channel = TIM_Channel_2;
    TIM_IC.TIM_ICPolarity = TIM_ICPolarity_Rising;
    TIM_IC.TIM_ICSelection = TIM_ICSelection_DirectTI;
    TIM_IC.TIM_ICPrescaler = TIM_ICPSC_DIV1;
    TIM_IC.TIM_ICFilter = 0;
    TIM_ICInit(TIM2, &TIM_IC);
Настроил бы на отлов фронта. По прерыванию от фронта захватил бы значение и перенастроил на спад. По спаду забрал значения таймера и посчитал разницу. И снова перенастроил на фронт. Так как настроив на оба, вы запутаетесь, где фронт где спад и можете посчитать разницу между спадом и фронтом и наоборот.

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
void TIM2_IRQHandler() {
 
    if (TIM_GetITStatus(TIM2, TIM_IT_CC2) != RESET) 
   {
        TIM_ClearITPendingBit(TIM2, TIM_IT_CC2);
        if(currentEdge == TIM_ICPolarity_Rising)
        {
              capture1 = TIM_GetCapture1(TIM2); 
              TIM2->CCER  |= TIM_CCER_CC2P;
              currentEdge = TIM_ICPolarity_Falling;
        }
        else
        {
              capture2 = TIM_GetCapture1(TIM2); 
              TIM2->CCER  &= ~TIM_CCER_CC2P;
              currentEdge = TIM_ICPolarity_Rising;
              result = capture2 - capture1;
        }
    } 
}
0
0 / 0 / 2
Регистрация: 24.04.2018
Сообщений: 61
14.06.2019, 09:44  [ТС] 5
Компилятор ругается на currentEdge, как что его обьявить?
0
Модератор
Эксперт по электронике
8517 / 6332 / 858
Регистрация: 14.02.2011
Сообщений: 22,020
14.06.2019, 09:51 6
Цитата Сообщение от _SayHello Посмотреть сообщение
Настроил бы на отлов фронта. По прерыванию от фронта захватил бы значение и перенастроил на спад. По спаду забрал значения таймера и посчитал разницу. И снова перенастроил на фронт.
у таймеров есть режим захвата, режим измерения ШИМ, и все это делается автоматически
я делал так
один канал для генерации стартового сигнала, режим одновибратора
два канала в режим измерения ШИМ
всего делов то было, запустить таймер, а потом считать значения
0
0 / 0 / 2
Регистрация: 24.04.2018
Сообщений: 61
14.06.2019, 09:54  [ТС] 7
Проблема в том, что при отладке компилятор пропускает обработчик void TIM2_IRQHandler(), он на него вообще не попадает!
0
0 / 0 / 2
Регистрация: 24.04.2018
Сообщений: 61
21.06.2019, 15:40  [ТС] 8
Наконец то у меня что то вышло и заработало! Но вот беда, показания датчика постоянно прыгают, +- 15%! Дело не в датчике, смотрел через отладку, иногда беруться значения с потолка! Датчик менял, аж три раза, все тоже самое! Может кто глянет и скажет где косяк!!

C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/**
 ******************************************************************************
 * @file    main.c
 * @author  Ac6
 * @version V1.0
 * @date    01-December-2013
 * @brief   Default main function.
 ******************************************************************************
 */
 
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_tim.h"
#include "stm32f30x_exti.h"
#include "max7219.h"
#include "stdio.h"
#include "ton.h"
 
void sonar_init();
unsigned int sonar_get();
uint32_t buff[5];
 
 
 
int main(void) {
    Init_SPI();
    Init_7219();
    sonar_init();
 
    uint32_t dist;
    int dist1, dist2, dist3, dist4 = 0;
 
 
 
    while (1) {
 
        dist = sonar_get();
        pips(dist);
 
        dist1 = (int) dist % 100 / 10;
        dist2 = (int) dist % 1000 / 100;
        dist3 = (int) dist % 10000 / 1000;
        dist4 = (int) dist % 100000 / 10000;
 
        Send_7219(1, dist1);
        Send_7219(2, dist2);
        Send_7219(3, dist3);
        Send_7219(4, dist4);
 
    }
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * HC_SR04.c
 *
 *  Created on: 19.06.2019
 *      Author: schwe
 */
 
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_tim.h"
#include "stm32f30x_exti.h"
#include "ton.h"
 
volatile uint16_t oldCount,newCount;
char state = 0;
 
void sonar_init() {
 
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3 | RCC_APB1Periph_TIM4, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
 
    TIM_TimeBaseInitTypeDef TIM_3;
    TIM_TimeBaseStructInit(&TIM_3);
    TIM_3.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_3.TIM_Prescaler = 72;
    TIM_TimeBaseInit(TIM3, &TIM_3);
    TIM_Cmd(TIM3, ENABLE);
 
    TIM_TimeBaseInitTypeDef TIM_4;
    TIM_TimeBaseStructInit(&TIM_4);
    TIM_4.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_4.TIM_Prescaler = 7199;
    TIM_4.TIM_Period = 5000;
    TIM_TimeBaseInit(TIM4, &TIM_4);
    TIM_ITConfig(TIM4, TIM_IT_Update, ENABLE);
    TIM_Cmd(TIM4, ENABLE);
 
    GPIO_InitTypeDef PORT;
    GPIO_StructInit(&PORT);
    PORT.GPIO_Mode = GPIO_Mode_OUT;
    PORT.GPIO_Pin = GPIO_Pin_15; // TRIG
    GPIO_Init(GPIOB, &PORT);
 
    PORT.GPIO_Pin = GPIO_Pin_0; // ECHO
    PORT.GPIO_Mode = GPIO_Mode_IN;
    PORT.GPIO_OType = GPIO_OType_PP;
    PORT.GPIO_PuPd = GPIO_PuPd_DOWN;
    PORT.GPIO_Speed = GPIO_Speed_Level_2;
    GPIO_Init(GPIOB, &PORT);
    GPIO_ResetBits(GPIOB,GPIO_Pin_0);
 
    NVIC_InitTypeDef NVIC_EXTI;
    NVIC_EXTI.NVIC_IRQChannel = EXTI0_IRQn;
    NVIC_EXTI.NVIC_IRQChannelPreemptionPriority = 0x00;
    NVIC_EXTI.NVIC_IRQChannelSubPriority = 0x00;
    NVIC_EXTI.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_EXTI);
 
    NVIC_InitTypeDef NVIC_TIM_4;
    NVIC_TIM_4.NVIC_IRQChannel = TIM4_IRQn;
    NVIC_TIM_4.NVIC_IRQChannelPreemptionPriority = 0;
    NVIC_TIM_4.NVIC_IRQChannelSubPriority = 0;
    NVIC_TIM_4.NVIC_IRQChannelCmd = ENABLE;
    NVIC_Init(&NVIC_TIM_4);
 
    SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOB, EXTI_PinSource0);
 
    EXTI_InitTypeDef EXTI_PB0;
    EXTI_PB0.EXTI_Line = EXTI_Line0;
    EXTI_PB0.EXTI_LineCmd = ENABLE;
    EXTI_PB0.EXTI_Mode = EXTI_Mode_Interrupt;
    EXTI_PB0.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
    EXTI_Init(&EXTI_PB0);
 
}
 
void EXTI0_IRQHandler(void) {
 
 
while(EXTI_GetITStatus(EXTI_Line0) != RESET)
{
    if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 1)
    {
        oldCount = TIM_GetCounter(TIM3);
    }
    if (GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0) == 0)
    {
        newCount = TIM_GetCounter(TIM3);
    }
 
    EXTI_ClearITPendingBit(EXTI_Line0);
 
}
}
void sonar_start() {
    int i;
 
    GPIO_SetBits(GPIOB, GPIO_Pin_15);
    for (i = 0; i < 0x7200; i++)
        ;
    GPIO_ResetBits(GPIOB, GPIO_Pin_15);
 
}
 
unsigned int sonar_get() {
    unsigned long Sonar;
    Sonar = (354 / 2) * (unsigned long) (newCount-oldCount) / (72000 / 72);
    if (Sonar > 4000)
        Sonar = 4000;
    if (Sonar < 20)
        Sonar = 20;
 
    return (unsigned int) Sonar;
}
 
void TIM4_IRQHandler(void) {
    while (TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
 
        sonar_start();
 
 
        TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
 
    }
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include "max7219.h"
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_spi.h"
 
#define cs_ON() GPIO_ResetBits(GPIOD, GPIO_Pin_2);
#define cs_OFF() GPIO_SetBits(GPIOD, GPIO_Pin_2);
 
char dg = 8;
 
void Init_SPI(void) {
 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
    RCC_AHBPeriphClockCmd( RCC_AHBPeriph_GPIOA, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI3, ENABLE);
 
 
 
 
 
 
    GPIO_InitTypeDef PORT;
    PORT.GPIO_Pin = GPIO_Pin_10; //10:SCK->CLK
    PORT.GPIO_Speed = GPIO_Speed_Level_1;
    PORT.GPIO_Mode = GPIO_Mode_AF;
    PORT.GPIO_OType = GPIO_OType_PP;
    PORT.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &PORT);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource10, GPIO_AF_6);
 
    PORT.GPIO_Pin = GPIO_Pin_12; // 12:MOSI->DIN
    PORT.GPIO_Speed = GPIO_Speed_Level_1;
    PORT.GPIO_Mode = GPIO_Mode_AF;
    PORT.GPIO_OType = GPIO_OType_PP;
    PORT.GPIO_PuPd = GPIO_PuPd_NOPULL;
    GPIO_Init(GPIOC, &PORT);
    GPIO_PinAFConfig(GPIOC, GPIO_PinSource12, GPIO_AF_6);
 
    PORT.GPIO_Pin = GPIO_Pin_2; // SS->CS
    PORT.GPIO_Speed = GPIO_Speed_Level_1;
    PORT.GPIO_Mode = GPIO_Mode_OUT;
    PORT.GPIO_OType = GPIO_OType_PP;
    GPIO_Init(GPIOD, &PORT);
    GPIO_SetBits(GPIOD, GPIO_Pin_2);
 
 
 
    GPIO_InitTypeDef port;
    port.GPIO_Mode = GPIO_Mode_OUT;
    port.GPIO_OType = GPIO_OType_PP;
    port.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_0;
    port.GPIO_PuPd = GPIO_PuPd_DOWN;
    port.GPIO_Speed = GPIO_Speed_Level_1;
    GPIO_Init(GPIOA, &port);
 
 
 
 
    SPI_InitTypeDef SPIConf;
    SPIConf.SPI_Direction = SPI_Direction_1Line_Tx;
    SPIConf.SPI_Mode = SPI_Mode_Master;
    SPIConf.SPI_DataSize = SPI_DataSize_16b;
    //SPIConf.SPI_CRCPolynomial = 7;
    SPIConf.SPI_CPOL = SPI_CPOL_Low;
    SPIConf.SPI_CPHA = SPI_CPHA_1Edge;
    SPIConf.SPI_NSS = SPI_NSS_Soft | SPI_NSSInternalSoft_Set;
    SPIConf.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;
    SPIConf.SPI_FirstBit = SPI_FirstBit_MSB;
    SPI_Init(SPI3, &SPIConf);
    SPI_Cmd(SPI3, ENABLE);
    SPI_NSSInternalSoftwareConfig(SPI3, SPI_NSS_Soft);
}
 
//------------------------------------------------------
 
void Send_7219(uint8_t rg, uint8_t dt) {
    cs_ON()
    ;
    while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_TXE) == RESET)
        ;
    SPI_I2S_SendData16(SPI3, (((uint16_t) rg << 8) + dt));
    while (SPI_I2S_GetFlagStatus(SPI3, SPI_I2S_FLAG_BSY) == SET)
        ;
    cs_OFF()
    ;
 
}
 
void Clear_7219(void) {
 
    Send_7219(0x01, 0x00);
    Send_7219(0x02, 0x00);
    Send_7219(0x03, 0x00);
    Send_7219(0x04, 0x00);
}
 
void Number_7219(volatile long n) {
    uint8_t ng = 0;
    if (n < 0) {
        ng = 1;
        n *= -1;
    }
    uint8_t i = 0;
    do {
        Send_7219(++i, n % 10);
        n /= 10;
    } while (n);
    if (ng) {
        Send_7219(i + 1, 0x0A);
    }
}
 
void Init_7219(void) {
    Send_7219(0x0F, 0x00);
    Send_7219(0x0C, 0x01);
    Send_7219(0x0B, 0x03);
    Send_7219(0x0A, 0x0A);
    Send_7219(0x09, 0xFF);
    Clear_7219();
}
 
void delay(uint32_t us) {
    volatile uint32_t nCount;
    RCC_ClocksTypeDef RCC_Clocks;
    RCC_GetClocksFreq(&RCC_Clocks);
    nCount = (RCC_Clocks.HCLK_Frequency / 7200) * us;
    for (; nCount != 0; nCount--)
        ;
}
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/*
 * ton.c
 *
 *  Created on: 20.06.2019
 *      Author: schwe
 */
 
#include "stm32f30x.h"
#include "stm32f30x_gpio.h"
#include "stm32f30x_rcc.h"
#include "stm32f30x_tim.h"
#include "stm32f30x_exti.h"
 
void pips(uint32_t abs) {
    uint32_t ton;
 
 
 
    if (abs > 1000) {
        ton = 0xFFFFF;
    } else if ((abs <= 1000) || (abs > 900)) {
        ton = 0xAFFFF;
    } else if ((abs <= 900) || (abs > 800)) {
        ton = 0x9FFFF;
    } else if ((abs <= 800) || (abs > 700)) {
        ton = 0x8FFFF;
    } else if ((abs <= 700) || (abs > 600)) {
        ton = 0x7FFFF;
    } else if ((abs <= 600) || (abs > 500)) {
        ton = 0x6FFFF;
    } else if ((abs <= 500) || (abs > 400)) {
        ton = 0x5FFFF;
    } else if ((abs <= 400) || (abs > 300)) {
        ton = 0xAFFF;
    } else if ((abs <= 300) || (abs > 200)) {
        ton = 0x4FFF;
    } else if ((abs <= 200) || (abs > 100)) {
        ton = 0x0FFF;
    } else if ((abs <= 100) || (abs > 10)) {
        ton = 0x2FFF;
    }
 
    for (uint32_t i = 0; i <= ton; i++) {
    }
    GPIO_SetBits(GPIOA, GPIO_Pin_5);
    for (uint32_t i = 0; i <= ton; i++) {
    }
    GPIO_ResetBits(GPIOA, GPIO_Pin_5);
 
}
Вложения
Тип файла: zip laborMK_2019.zip (6.22 Мб, 7 просмотров)
0
Модератор
Эксперт по электронике
8517 / 6332 / 858
Регистрация: 14.02.2011
Сообщений: 22,020
21.06.2019, 17:44 9
Цитата Сообщение от Schweigert Посмотреть сообщение
if ((abs <= 1000) || (abs > 900))
сработает ли это условие если abs будет допустим 2???
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
21.06.2019, 17:44

Stm32 датчик освещенности библиотека unix_time
Добрый день, есть проект датчика освещенности, которое перед прошивкой надо было все параметры...

STM8L-discovery + HCSR04
Нужна помощь в написании программы для платы STM8L-discovery (stm8l152c6) и HCSR04. Среда...

Чем связать STM32 + STM32 в одном корпусе?
Есть 2 платы: (1) - STM32 (Вывод на LCD + запись SD) и (2) - STM32F4 (обработка сигналов +...

Общение с барометром MS5540 на STM32 (Arduino to STM32)
Получил от китайца сей аппарат, пошел тут же гуглить что нибудь готовое, но не тут то было....


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.