0
\$\begingroup\$

I am using an NUCLEO-F411RE and try to use the GPIO with HAL. Its the first time i am facing this problem. I initialized the GPIO Pins like this:

static void MX_GPIO_Init(void)
{
      GPIO_InitTypeDef GPIO_InitStruct = {0};

      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOC_CLK_ENABLE();
      __HAL_RCC_GPIOH_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();

      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(User_LED_GPIO_Port, User_LED_Pin, GPIO_PIN_RESET);

      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOA, O_Reset_Pin|O_Wake_Up_Pin, GPIO_PIN_RESET);

      /*Configure GPIO pin Output Level */
      HAL_GPIO_WritePin(GPIOC, O_Boot_Pin|O_Mode_1_Pin, GPIO_PIN_RESET);

      /*Configure GPIO pins : O_Reset_Pin O_Wake_Up_Pin */
      GPIO_InitStruct.Pin = O_Reset_Pin|O_Wake_Up_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_PULLUP;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

      /*Configure GPIO pin : O_Boot_Pin */
      GPIO_InitStruct.Pin = O_Boot_Pin;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

I removed some PIN init code because i am facing the Problem with the Reset and Wake_up Pin which are part of GPIOA. For test behaviour i keep the BOOT Pin from GPIOC.

One side question, after the initialisation as GPIO_PULLUP. Why are these two pins on a low level. Shouldn't they be as default on a high level?

Because of that i Set this Pins to High bevor my while(1) loop like this:

HAL_GPIO_WritePin(O_Boot_GPIO_Port, O_Boot_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(O_Reset_GPIO_Port, O_Reset_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(O_Wake_Up_GPIO_Port, O_Wake_Up_Pin, GPIO_PIN_SET);

The record of my logic analyzer looks like this:

enter image description here

The Reset & Wake_up pin from GPIOA are dropping back to low level. But the boot Pin keeps high level like expected. I started a debug session and realized, when i call the Hal_delay() function these two pins are dropping back to low level. So i just put a HAL_delay() function between the WritePin function.

HAL_GPIO_WritePin(O_Boot_GPIO_Port, O_Boot_Pin, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(O_Reset_GPIO_Port, O_Reset_Pin, GPIO_PIN_SET);
HAL_Delay(10);
HAL_GPIO_WritePin(O_Wake_Up_GPIO_Port, O_Wake_Up_Pin, GPIO_PIN_SET);
HAL_Delay(10);

The logic analyzer looks like this:

enter image description here

As you can see, the Pin level drop to low after i use the HAL_delay function. But just for the GPIOA Pins.

I actually know what problem i have! In the Timer Callback function i toggle two pins PA8 and PA11. If i remove this code everything works fine. So the Problem is my Bitmanipulation on GPIOA.

Here is the function

void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
    static uint8_t countClkCycles;

    countClkCycles++;    

    if(countClkCycles >= 40)
    {
        k++;
    }
        if(k == 10)
        {
            k=0;
        }
    else
    {
        if(goldcode1[k] == 1)
        {
                GPIOA->ODR ^= (1<<11);                  // Toggle output GPIO PA11
        }
        else
        {
            GPIOA->BSRR = (1<<27);
        }
    }


    if(countClkCycles >= 40)
    {
        int j=i+1;

        if(j == 10)
        {
            j=0;
        }
        if(goldcode1[i] == goldcode1[j])
        {
                GPIOA->ODR ^= (1<<8);                               //Toggle output GPIOA PA8
        }
        else
        {
                //GPIOA->BSRR = (1<<24);
                if(goldcode1[i] == 1)
                {
                        //GPIOA->ODR = (1<<8);                          //sets output GPIOA PA8
                        GPIOA->BSRR = (1<<24);
                }
                else
                {
                        //GPIOA->BSRR = (1<<24);                        //resets output GPIOA PA8
                        GPIOA->ODR = (1<<8);                            //sets output GPIOA PA8
                }
        }
        i=j;

        //TIM2->CCMR1 ^= 1 << 4;
        countClkCycles = 0;
    }
    else
    {
            GPIOA->ODR ^= (1<<8);                                 //Toggle output GPIOA PA8
    }

}

How should i do the Bitmanipulation that i just toggle PA8 and PA11 and not the whole GPIOA register.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ Re your side question - the PULLUP setting is only effective on Input pins, not Outputs. \$\endgroup\$
    – brhans
    Commented Nov 9, 2020 at 13:16
  • \$\begingroup\$ You need to show your entire program. What happens next? Does the chip hard fault? Does main() return? Put it into an infinite loop if you want to see your output settings persist. \$\endgroup\$ Commented Nov 9, 2020 at 15:52
  • 1
    \$\begingroup\$ @brhans Thats a new information for me. Are you sure Pullups don't work on output pins? As far as I remember we have used this feature many times on outputs. \$\endgroup\$
    – A.R.C.
    Commented Nov 10, 2020 at 8:08
  • 1
    \$\begingroup\$ @A.R.C. - Ok, clarification: the pullup has no effect on push-pull outputs (as the OP has them configured). It could have an effect on open-drain outputs. For a push-pull output the output driver will drive the pin either high or low - there is no state where the output would float and the pull-up would have an effect. \$\endgroup\$
    – brhans
    Commented Nov 10, 2020 at 13:56

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.