Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
HC-SR4超声波传感器与STM32L1的接口_C_Embedded_Stm32_Stm32ldiscovery - Fatal编程技术网

HC-SR4超声波传感器与STM32L1的接口

HC-SR4超声波传感器与STM32L1的接口,c,embedded,stm32,stm32ldiscovery,C,Embedded,Stm32,Stm32ldiscovery,我试图控制这个HC-SR4超声波传感器,当检测到一个距离1米远的物体时,只需在一个LED上。 我使用TIM2作为触发信号(引脚PB10),使用TIM4接收回波信号(引脚PB6)。LED连接至引脚PB7。 当我加载下面的代码时,LED只会亮起,无论是否有对象,它都会亮起 知道我哪里出错了吗 #include <stdio.h> #include "stm32l1xx.h" // Keil::Device:Startup // switch fro

我试图控制这个HC-SR4超声波传感器,当检测到一个距离1米远的物体时,只需在一个LED上。 我使用TIM2作为触发信号(引脚PB10),使用TIM4接收回波信号(引脚PB6)。LED连接至引脚PB7。 当我加载下面的代码时,LED只会亮起,无论是否有对象,它都会亮起

知道我哪里出错了吗

 #include <stdio.h>
#include "stm32l1xx.h"                  // Keil::Device:Startup


// switch from HSE to HSI clock 16MHz
void HSI_config(){

RCC->CR |= RCC_CR_HSION; // Turn On HSI oscillator
RCC->CFGR |= RCC_CFGR_SW; // Select HSI clock
RCC->CFGR |= RCC_CFGR_SWS_HSI;
RCC->CR |= RCC_CR_HSIRDY; // wait for HSI stabilize
}

// Configure GPIO Port B
void GPIO_config(){

    RCC->AHBRSTR |= RCC_AHBRSTR_GPIOBRST;           // Reset GPIOB clock 
    RCC->AHBRSTR &= ~RCC_AHBRSTR_GPIOBRST;      // Clear Reset 
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;        // Enable GPIOB clock 

    //PB6 Echo Pin
    GPIOB->MODER   &=   ~(0x03 << (2*6));     // Clear bit 12 & 13 Alternate function mode 
    GPIOB->MODER   |=   0x02 << (2*6);              // set as Alternate function mode 
    GPIOB->OSPEEDR &=   ~(0x03<< (2*6));            // 40 MHz  speed 
    GPIOB->OSPEEDR |=   0x03<< (2*6);               // 40 MHz  speed 
    GPIOB->PUPDR &=         ~(1<<6);                            // NO PULL-UP PULL-DOWN 
    GPIOB->OTYPER &=        ~(1<<6);                            // PUSH-PULL 
    GPIOB->AFR[0] |=        0x2 << (4*6);                   // set PB pin 6 as AF2 (TIM4_CH1) 

    //PB10 Pluse Generating Pin
    GPIOB->MODER   &=   ~(0x03 << (2*10));    // Clear bit 12 & 13 Alternate function mode 
    GPIOB->MODER   |=   0x02 << (2*10);     // set as Alternate function mode 
    GPIOB->OSPEEDR &=   ~(0x03<< (2*10));           // 40 MHz  speed 
    GPIOB->OSPEEDR |=   0x03<< (2*10);              // 40 MHz  speed 
    GPIOB->PUPDR &=         ~(1<<10);                           // NO PULL-UP PULL-DOWN 
    GPIOB->OTYPER &=        ~(1<<10);                           // PUSH-PULL 
    GPIOB->AFR[1] |=        0x1 << (4*2);                   // set PB pin 10 as AF1 (TIM2_CH3) 

//PB7 LED ON/OFF
    GPIOB->MODER   |=   GPIO_MODER_MODER7_0;     // General purpose output mode
  GPIOB->OSPEEDR |=   GPIO_OSPEEDER_OSPEEDR7;  // Max High speed 50MHz       

}
// CONFIGURE TIM4 FOR RECEIVING INPUT SIGNAL
void TIM4_Enable(){
    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;                 // ENABLE TIM4 CLOCK
    TIM4->PSC = 15;                                                         // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK
    TIM4->ARR = 0XFFFF;                                                 // SET MAX PULSE WIDTH OF 65536us FOR 16-BIT TIMER
    TIM4->CCMR1 &= ~TIM_CCMR1_CC1S;                         // CLEAR CAPTURE/COMPARE REGISTER
    TIM4->CCMR1 |= 0X1;                                                 // SELECT CH1 INPUTE CAPTURE 
    TIM4->CCMR1 &= ~TIM_CCMR1_IC1F;                         // DISABLE DIGITAL FILTERING
    TIM4->CCER |= (1<<1 | 1<<3);                                // SELECT BOTH RISING AND FALLING EDGE DETECTION CC1P & CC1NP
    TIM4->CCMR1 &= ~(TIM_CCMR1_IC1PSC);                 // INPUT PRESCALER 0 TO CAPTURE EACH VALID EDGE
    TIM4->CCER |= TIM_CCER_CC1E;                                // ENABLE COUNTER CAPTURE
    TIM4->DIER |= TIM_DIER_CC1IE;                               // ENABLE CH1 CAPTURE/COMPARE INTERRUPT
    NVIC_SetPriority(TIM4_IRQn, 1);                         // SET PRIORITY TO 1
    NVIC_EnableIRQ(TIM4_IRQn);                                  //ENABLE TIM4 INTERRUPT IN NVIC
}

// CONFIGURE TIM2 FOR SENDING OUTPUT SIGNAL
void TIM2_Enable(){
    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;                 // ENABLE TIM2 CLOCK
    TIM2->PSC = 15;                                                         // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK
    TIM2->ARR = 0XFFFF;                                                 // SET MAX PULSE WIDTH OF 65536us FOR 16-BIT TIMER

    TIM2->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2; // 111: PWM mode 1 
    TIM2->CCMR2 |= TIM_CCMR2_OC3PE;                         // CH3 Output Preload Enable
    TIM2->CR1 |= TIM_CR1_ARPE;                                  // Auto-reload Prelaod Enable
    TIM2->CCER |= TIM_CCER_CC3E;                                // Enable Output for CH3
    TIM2->EGR |= TIM_EGR_UG;                                        // Force Update
    TIM2->SR &= ~TIM_SR_UIF;                                        // Clear the Update Flag
    TIM2->DIER |= TIM_DIER_UIE;                                 // Enable Interrupt on Update
    TIM2->CR1 |= TIM_CR1_DIR;                                       // Set downcounting counter direction
    TIM2->CR1 |= TIM_CR1_CEN;                                       // Enable Counter
}


    //Initialize the float variables.
    volatile uint8_t timespan = 0;                              // Total pulse width
    volatile uint8_t lastcounter = 0;                           // Timer counter value of the last event
    volatile uint8_t newcounter = 0;                            // Timer counter value of the current event
    volatile uint8_t overflow = 0;                              // Count the number of overflows
    volatile uint8_t PulseEnd = 0;                              // Declare end of pulse

void Echo_TIM4_IRQHandler(){

    if ((TIM4->SR & TIM_SR_UIF) != 0){                  // Check the update even flag
        overflow = overflow + 1;                                    // if UIF = 1, increment overflow counter
        TIM4->SR &= ~TIM_SR_UIF;                                    // clear UIF
    }
    if ((TIM4->SR & TIM_SR_CC1IF) != 0){                // Check capture event flag 
    newcounter = TIM4->CCR1;                                        // read capture value, store as newcounter
    timespan = (newcounter - lastcounter)+(65536 * overflow);   // calculate the total pulse width
    lastcounter = newcounter;                               // save the value of newcounter as lastcounter to be used for the next cycle
    overflow = 0;                                                       // clear overflow counter
    PulseEnd = 1;
}

}

void setSysTick(void){
    // ---------- SysTick timer (1ms) -------- //
    if (SysTick_Config(SystemCoreClock / 1000)) {
        // Capture error
        while (1){};
    }
}

    volatile uint32_t msTicks;      //counts 1ms timeTicks
void SysTick_Handler(void) {
    msTicks++;
}

static void Delay(__IO uint32_t dlyTicks){                                              
  uint32_t curTicks = msTicks;
  while ((msTicks - curTicks) < dlyTicks);
}



    int main(void){

            float Distance = 0.0f;                                              // actual distance in cm
            int Pulsesent = 0;

    HSI_config();
    setSysTick();
    GPIO_config();
    TIM4_Enable();
    Echo_TIM4_IRQHandler();

while(1){

if (Pulsesent == 0) {
    (Pulsesent = 1);
        TIM2_Enable();
}

if(Pulsesent && PulseEnd){
            Pulsesent = 0;

        if(overflow == 1){
                timespan = 0;
            }
            else {
                Distance = (timespan / 58) ;
            }
            Delay(1);
        }   
    if (Distance <= 100){

        GPIOB->BSRRL = (1<<7);
    }
        else {
            GPIOB->BSRRL = (0<<7);

        }   

    }   

}
#包括
#包括“stm32l1x.h”//Keil::设备:启动
//从HSE切换到HSI时钟16MHz
无效HSI_配置(){
RCC->CR |=RCC_CR_HSION;//打开HSI振荡器
RCC->CFGR |=RCC_CFGR_SW;//选择HSI时钟
RCC->CFGR |=RCC_CFGR_SWS_HSI;
RCC->CR |=RCC_CR_HSIRDY;//等待HSI稳定
}
//配置GPIO端口B
无效GPIO_配置(){
RCC->AHBRSTR |=RCC_AHBRSTR_GPIOBRST;//重置GPIOB时钟
RCC->AHBRSTR&=~RCC\u AHBRSTR\u GPIOBRST;//清除重置
RCC->AHBENR |=RCC_AHBENR_GPIOBEN;//启用GPIOB时钟
//PB6回音针
GPIOB->MODER&=~(0x03 MODER |=0x02 OSPEEDR&=~(0x03OSPEEDR |=0x03PUPDR&=~(1ARR=0XFFFF;//为16位计时器设置65536us的最大脉冲宽度
TIM4->CCMR1&=~TIM\u CCMR1\u CC1S;//清除捕获/比较寄存器
TIM4->CCMR1 |=0X1;//选择CH1输入捕获
TIM4->CCMR1&=~TIM\u CCMR1\u IC1F;//禁用数字滤波
TIM4->CCER |=(1APB1ENR |=RCC_APB1ENR| u TIM2EN;//启用TIM2时钟
TIM2->PSC=15;//设置适当的预分频器以降低时钟速度
TIM2->ARR=0XFFFF;//设置16位定时器的最大脉冲宽度为65536us
TIM2->CCMR2 |=TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;//111:PWM模式1
TIM2->CCMR2 |=TIM_CCMR2_OC3PE;//CH3输出预加载启用
TIM2->CR1 |=TIM_CR1_ARPE;//自动重新加载预加载启用
TIM2->CCER |=TIM_CCER_CC3E;//为CH3启用输出
TIM2->EGR |=TIM_EGR_UG;//强制更新
TIM2->SR&=~TIM\u SR\u UIF;//清除更新标志
TIM2->DIER |=TIM_DIER_UIE;//在更新时启用中断
TIM2->CR1 |=TIM_CR1_DIR;//设置下行计数计数器方向
TIM2->CR1 |=TIM_CR1_CEN;//启用计数器
}
//初始化浮点变量。
易失性uint8\u t timespan=0;//总脉冲宽度
volatile uint8\u t lastcounter=0;//上次事件的计时器计数器值
volatile uint8\u t newcounter=0;//当前事件的计时器计数器值
volatile uint8\u t overflow=0;//计算溢出的数量
volatile uint8\u t PulseEnd=0;//声明脉冲结束
void Echo_TIM4_IRQHandler(){
如果((TIM4->SR&TIM_SR_UIF)!=0){//请检查更新偶数标志
溢出=溢出+1;//如果UIF=1,则递增溢出计数器
TIM4->SR&=~TIM\U SR\U UIF;//清除UIF
}
如果((TIM4->SR&TIM_SR_CC1IF)!=0){//检查捕获事件标志
newcounter=TIM4->CCR1;//读取捕获值,存储为newcounter
timespan=(newcounter-lastcounter)+(65536*溢出);//计算总脉冲宽度
lastcounter=newcounter;//将newcounter的值另存为lastcounter以用于下一个周期
溢出=0;//清除溢出计数器
脉冲数=1;
}
}
void设置系统键(void){
//------系统时钟(1ms)--//
if(系统时钟配置(系统时钟/1000)){
//捕获错误
而(一){};;
}
}
volatile uint32\u t msTicks;//计算1ms时间刻度
void SysTick_处理器(void){
msTicks++;
}
静态无效延迟(uu IO uint32_t dlyTicks){
uint32_t curTicks=msTicks;
而((msTicks-curTicks)如果(距离BSRRL=(1你的代码是多么混乱,不仅仅是你的布局,“逻辑”你对全局变量的使用似乎完全是foobar。我认为你必须花一些精力来整理你的代码设计,从一位经验丰富的嵌入式软件工程师那里获得建议。想想:这是一个很小的代码,你无法让它工作,所以用你目前的开发方法,你怎么能得到一些呢复杂的工作-你需要改变你的方法

与您看到的症状直接相关的代码中至少有一个问题是,在
main()中,您的全局变量
PulseEnd
被设置为副作用
您直接调用TIM4中断处理程序-为什么?可能是为了初始化全局变量?不要这样做!-并且永远不会重置此代码中的任何地方

那么首先
#include <stdio.h>
#include "stm32l1xx.h"                  // Keil::Device:Startup

        //Initialize the timers variables.
    volatile int timespan = 0;                              // Total pulse width
    volatile int lastcounter = 0;                           // Timer counter value of the last event
    volatile int newcounter = 0;                            // Timer counter value of the current event
    volatile int overflow = 0;                              // Count the number of overflows


    void SysTick_Handler(void);
    void SetHSI(void);
    void LED_GPIO(void);    
    void TIM4_C1_Init(void);
    void TIM2_C3_Init(void);
    void TIM4_IRQHandler(void);
    void LED (void);

        void setSysTick(void){
    // ---------- SysTick timer (1ms) -------- //
    if (SysTick_Config(SystemCoreClock / 1000)) {
    while (1);  // Capture error
    }
}
    volatile uint32_t msTicks=0; //counts 1ms timeTicks 
    void SysTick_Handler(void) {
    msTicks++;
}

static void Delay(__IO uint32_t dlyTicks){ 
  uint32_t curTicks; 
    curTicks = msTicks;
    while ((msTicks - curTicks) < dlyTicks);
}

        int main(void){
          SysTick_Handler();
            setSysTick();
            SetHSI();                             
            LED_GPIO();

            TIM2_C3_Init();
            TIM4_C1_Init();
while(1){

    LED();

Delay(100);
    }
}

/*----------------------------------------------------------------------------
  set HSI as SystemCoreClock (HSE is not populated on STM32L-Discovery board)
 *----------------------------------------------------------------------------*/
void SetHSI(void) {

// Turn on HSI (16MHz)
RCC->CR |= RCC_CR_HSION;
// Wait until HSI is ready
while( (RCC->CR & RCC_CR_HSIRDY) == 0);
// Select HSI as system clock
RCC->CFGR &= ~RCC_CFGR_SW_HSI;
RCC->CFGR |= RCC_CFGR_SW_HSI;
while( (RCC->CFGR & RCC_CFGR_SWS)!=RCC_CFGR_SWS_HSI ); // Wait till HSI
}

// Configure GPIO Port B
void LED_GPIO(void){


    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;        // Enable GPIOB clock 

//PB7 LED ON/OFF
    GPIOB->MODER   |=   GPIO_MODER_MODER7_0;     // General purpose output mode
  GPIOB->OSPEEDR |=   GPIO_OSPEEDER_OSPEEDR7;  // Max High speed 50MHz


}

// CONFIGURE TIM2 FOR SENDING OUTPUT SIGNAL
void TIM2_C3_Init(void){

    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;        // Enable GPIOB clock 

//PB10 Pluse Generating Pin
    GPIOB->MODER   &=   ~(0x03 << (2*10));     // Clear bit 12 & 13 Alternate function mode 
    GPIOB->MODER   |=   0x02 << (2*10);                 // set as Alternate function mode 
    GPIOB->OSPEEDR &=   ~(0x03<< (2*10));           // 40 MHz  speed 
    GPIOB->OSPEEDR |=   0x03<< (2*10);              // 40 MHz  speed 
    GPIOB->PUPDR &=         ~(1<<10);                           // NO PULL-UP PULL-DOWN 
    GPIOB->OTYPER &=        ~(1<<10);                           // PUSH-PULL 
    GPIOB->AFR[1] |=        0x1 << (4*2);                   // set PB pin 10 as AF1 (TIM2_CH3)

    RCC->APB1ENR |= RCC_APB1ENR_TIM2EN;                 // ENABLE TIM2 CLOCK
    TIM2->PSC = 159;                                                        // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK
    TIM2->ARR = 0XFFFF;                                                 // SET MAX PULSE WIDTH OF 65536us FOR 16-BIT TIMER
    TIM2->CR1 |= TIM_CR1_DIR;                                       // Set downcounting counter direction
    TIM2->CCMR2 &= ~(TIM_CCMR2_OC3M);                       // Clear OC3M (Channel 3)
  TIM2->CCMR2 |= TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2;
    TIM2->CCMR2 |= TIM_CCMR2_OC3PE;                         // CH3 Output Preload Enable
    TIM2->CR1 |= TIM_CR1_ARPE;                                  // Auto-reload Prelaod Enable
    TIM2->CCER |= TIM_CCER_CC3E;                                // Enable Output for CH3
    TIM2->EGR |= TIM_EGR_UG;                                        // Force Update
    TIM2->SR &= ~TIM_SR_UIF;                                        // Clear the Update Flag
    TIM2->DIER |= TIM_DIER_UIE;                                 // Enable Interrupt on Update
    TIM2->CCR3 &= ~(TIM_CCR3_CCR3);                     // Clear CCR3 (Channel 3) 
    TIM2->CCR3 |= 0x1;                                            // Load the register 
    TIM2->CR1 |= TIM_CR1_CEN;                           // Enable the counter
}


// CONFIGURE TIM4 FOR RECEIVING INPUT SIGNAL
void TIM4_C1_Init(void){
    RCC->AHBENR |= RCC_AHBENR_GPIOBEN;        // Enable GPIOB clock 
    GPIOB->MODER   &=   ~(0x03 << 12);     // Clear bit 12 & 13 Alternate function mode 
    GPIOB->MODER   |=   (0x02 << 12);               // set as Alternate function mode 
    GPIOB->OSPEEDR &=   ~(0x03<< 12);           // 40 MHz  speed 
    GPIOB->OSPEEDR |=   (0x03<< 12);                // 40 MHz  speed 
    GPIOB->PUPDR &=         ~(0X3<<12);                         // NO PULL-UP PULL-DOWN 
    GPIOB->OTYPER &=        ~(1<<6);                            // PUSH-PULL 
    GPIOB->AFR[0] &= ~GPIO_AFRL_AFRL6;  // Clear pin 6 for alternate function
    GPIOB->AFR[0] |=        0x2 << (4*6);                   // set PB pin 6 as AF2 (TIM4_CH1) 

    RCC->APB1ENR |= RCC_APB1ENR_TIM4EN;                 // ENABLE TIM4 CLOCK
    TIM4->PSC = 15;                                     // SET APPROPRAIT PRESCALER TO SLOW DOWN THE CLOCK                                              
    TIM4->CCMR1 &= ~TIM_CCMR1_CC1S;                         // CLEAR CAPTURE/COMPARE REGISTER
    TIM4->CCMR1 |= 0X1;                                                 // SELECT CH1 INPUTE CAPTURE 
    TIM4->CCMR1 &= ~TIM_CCMR1_IC1F;                         // DISABLE DIGITAL FILTERING
    TIM4->CCER |= (1<<1 | 1<<3);                                // SELECT BOTH RISING AND FALLING EDGE DETECTION CC1P & CC1NP
    TIM4->CCMR1 &= ~(TIM_CCMR1_IC1PSC);                 // INPUT PRESCALER 0 TO CAPTURE EACH VALID EDGE
    TIM4->CCER |= TIM_CCER_CC1E;                                // ENABLE COUNTER CAPTURE
    TIM4->DIER |= TIM_DIER_CC1IE;                               // ENABLE CH1 CAPTURE/COMPARE INTERRUPT
    TIM4->DIER |= TIM_DIER_CC1DE;   
    TIM4->DIER |= TIM_DIER_UIE;                                 // UPDATE INTERRUPT ENABLE
    TIM4->CR1 &= ~TIM_CR1_DIR;                                      // Set downcounting counter direction
    TIM4->CR1 |= TIM_CR1_CEN;                                       // Enable the counter
    NVIC_SetPriority(TIM4_IRQn, 1);                         // SET PRIORITY TO 1
    NVIC_EnableIRQ(TIM4_IRQn);                                  //ENABLE TIM4 INTERRUPT IN NVIC


}

void TIM4_IRQHandler(void){

    if ((TIM4->SR & TIM_SR_UIF) != 0){                  // Check the update event flag
        overflow++;                                 // if UIF = 1, increment overflow counter
        TIM4->SR &= ~TIM_SR_UIF;                                    // clear UIF
    }
    if ((TIM4->SR & TIM_SR_CC1IF) != 0){                // Check capture event flag 
    newcounter = TIM4->CCR1;                                        // read capture value, store as newcounter
    timespan = (newcounter - lastcounter)+(65536 * overflow);   // calculate the total pulse width
    lastcounter = newcounter;                               // save the value of newcounter as lastcounter to be used for the next cycle
    overflow = 0;                                                       // clear overflow counter
    }

}

void LED (void){

    float Distance;                                             // actual distance in cm
    Distance = (timespan / 58.0);

    if (Distance > 0.0 && Distance <= 100.0){

        GPIOB->BSRRL = (1<<7);
    }
        else {
        GPIOB->BSRRH = (1<<7);

        }   
    }