Невозможно включить или выключить зеленый / синий светодиод STM32F429ZI - Nucleo Board? - PullRequest
0 голосов
/ 09 мая 2019

Я пытаюсь написать голую металлическую программу, чтобы мигать зеленый светодиод. На самом деле, я не могу включить или выключить светодиоды. Это готовая доска. Название платы NUCLEO F429ZI. Изображение платы

Я просмотрел схемы и уверен, что это вывод PA5, т. Е. Порт A и вывод № 5. Однако светодиод вообще не мигает. Я вижу, что мой код загружен на плату STM32 с помощью IDE uVision.

Я попытался установить синий светодиод, то есть PB7, но это также не сработало вообще.

void delayMs(int delay);

int main(void)
{
    //enable clock access to A
    RCC->AHB1ENR |= 1;  //enable GPIO A clock
    GPIOA->MODER |= 0x400; //       PA-5 01   0000 - PA0
    while(1)
    {
          GPIOA->ODR |= 0x20;
         //delay
          delayMs(100);
          GPIOA->ODR &=~ 0x20;
          delayMs(100);
    }

}

void delayMs(int delay)
{
    int i = 0;
    for(; delay >0; delay--)
    {
     for(i=0; i<3195; i++)
        {
        }
    }
}

Зеленый светодиод в STM32F429ZI должен мигать.

Затем я попытался включить синий светодиод, который также не работает. Согласно моему пониманию, глядя на схемы - PB7 должен быть включен для синий светодиод. Но это тоже не работает.

#include "stm32f4xx.h"
int main(void)
{
    RCC->AHB1ENR |= 1;
    // ob 01 00 00 00 00 00 00 00 // PB7
    GPIOB->MODER = 0x4000;
    for(;;)
    {
        GPIOB->ODR = 0x80;
    }
}

Ответы [ 3 ]

1 голос
/ 09 мая 2019

Довольно бесполезно, что ссылка для скачивания руководства пользователя Nucleo F429ZI UM1974 по адресу https://www.st.com/en/evaluation-tools/nucleo-f429zi.html#resource, похоже, не работает (на момент написания), но я нашел копию в другом месте и назначение выводов:три пользовательских светодиода описаны следующим образом:

enter image description here

Схема предполагает, что заводское состояние паяных мостов SB120 и SB119 установлено для LD1 на PB0, а не назатем PA5.Проблема с вашей попыткой установить LD2 (синий) заключается в том, что вы не включили GPIOB в RCC - он включает GPIOA, как при попытке LD1 (зеленый).

Другая проблема заключается в том, что при настройке GPIO MODER предполагается, что состояние сброса для порта равно нулю.Это не так (хотя это касается конкретных пинов, о которых идет речь - поэтому вы «сойдете с рук» * в этом случае ):

enter image description here

Хорошая идея определить все константы портов / выводов в одном месте, чтобы вы могли легко переключать или добавлять выходы и с меньшей вероятностью ошибки:

#define LED_PORT              GPIOB
#define LED_PORT_RCC_EN       0x2u 
#define GPIO_MODE_MASK       ~0x3u
#define GPIO_MODE_OUTPUT      0x1u

#define GREEN_LED_PIN         0u
#define BLUE_LED_PIN          7u
#define RED_LED_PIN           14u
#define FLASH_LED             GREEN_LED_PIN

int main(void)
{
    RCC->AHB1ENR |= LED_PORT_RCC_EN ;
    LED_PORT->MODER &= GPIO_MODE_MASK << (FLASH_LED << 1) ;
    LED_PORT->MODER |= GPIO_MODE_OUTPUT << (FLASH_LED << 1) ;

    for(;;)
    {
          LED_PORT->ODR |= 0x1 << FLASH_LED ;
          delayMs( 100 ) ;
          LED_PORT->ODR &= ~(0x1 << FLASH_LED) ;
          delayMs( 100 ) ;
    }

    return 0 ;
}

Ваша функция задержкисерьезно испорчен, и, вероятно, будет оптимизирован, чтобы "ничего не делать".Ваш счетчик цикла должен быть объявлен энергозависимым, чтобы избежать его оптимизации.Если это произойдет, индикатор не будет заметно мигать, но будет пульсировать с очень высокой частотой и включаться, но не на полной яркости.

Следующее действие не позволит оптимизировать петли.

void delayMs( unsigned delay )
{
    for( volatile unsigned d = delay; d > 0; d--)
    {
        for( volatile int i = 0; i < 3195; i++ )
        {
        }
    }
}

Однако это часть с частотой 180 МГц;если вы используете его на полной скорости 3195 итераций, это, вероятно, не займет 1 мс.Больше похоже на несколько десятков микросекунд.Даже если он работает на частоте запуска HSI 16 МГц, он может составлять порядка нескольких сотен микросекунд и в любом случае будет зависеть от настроек оптимизации и времени, затрачиваемого на работу любых обработчиков прерываний.Гораздо лучше использовать счетчик Cortex-M SYSTICK следующим образом:

static volatile uint32_t ms_tick = 0 ;

void SysTick_Init(void) 
{
    SysTick_Config( SystemCoreClock / 1000 ) ;  
}

void SysTick_Handler(void)
{
    ms_tick++;
}

void delayMs( uint32_t delay)
{
    uint32_t start_tick = ms_tick ;
    while( (ms_tick - start_tick) < delay );
}

Тогда задержка будет точной независимо от тактовой частоты, на которой вы запускаете процессор, или от прерывания нагрузки.

0 голосов
/ 11 мая 2019
This is complete solution for Nucleo 144 - STM32F429ZI.

#include "stm32f4xx.h"

#define LED_PORT              GPIOB
#define LED_PORT_RCC_EN       0x2u 
#define GPIO_MODE_MASK       ~0x3u
#define GPIO_MODE_OUTPUT      0x1u

#define GREEN_LED_PIN         0u
#define BLUE_LED_PIN          7u
#define RED_LED_PIN           14u
#define FLASH_LED             BLUE_LED_PIN


void delayMs( unsigned delay );

int main(void)
{
    RCC->AHB1ENR |= LED_PORT_RCC_EN ; // enable for PORT B
    //LED_PORT->MODER &= GPIO_MODE_MASK << FLASH_LED ;
    //LED_PORT->MODER |= GPIO_MODE_OUTPUT << FLASH_LED ;
      GPIOB->MODER |= 0x4000;  // blue LED PB7
      GPIOB->MODER |= 0x1;  // green LED PB0
      GPIOB->ODR |= 0x1; // green LED ODR
      GPIOB->MODER |=  0x1 << 28; // red LED PB14
      GPIOB->ODR |= 0x1 <<14; // RED LED ODR
      //GPIOB->BSRR |= 0x4000; // 7th pin 
    // connected to pull up resistor -- when we press button , it goes low
        //B1 user button is connected to PC13 - i.e. blue button
      // Enable clock to PC13 i.e. Port C
      RCC->AHB1ENR |=  0x1 << 2;
      //GPIOC->MODER |=     //Input mode PC13- 13th pin 0
       // by default pins are input only
      GPIOC->MODER |=  0;
    for(;;)
    {
               // pressed blue button
               if( (GPIOC->IDR & (1<<13)) ) // PC13
                 {
                      LED_PORT->ODR |= 0x1 << FLASH_LED ;

                 }
                 else
                 {
            LED_PORT->ODR &= ~(0x1 << FLASH_LED) ;

                 }
    }

    return 0 ;
}

void delayMs( unsigned delay )
{
    for( volatile unsigned d = delay; d > 0; d--)
    {
        for( volatile int i = 0; i < 3195; i++ )
        {
        }
    }
}
0 голосов
/ 09 мая 2019

Вы не должны изменять ODR напрямую, так как он выполняет чтение / запись для всего порта.Вместо этого вы должны использовать регистр BSRR, где вы можете влиять только на один бит.Обратите внимание, что некоторые части STM32 используют один 32-битный регистр BSRR для установки и сброса битов (одна операция сдвинута на 16 бит влево), тогда как другие используют два 16-битных регистра, поэтому для получения подробной информации обратитесь к справочному руководству или файлу заголовка.

Ваша настройка MODER неверна.Вам нужно сначала очистить 2 бита для PA5, перед ИЛИ 01, например,

GOPIOA->MODER &= ~0b1100000000;
GPIOA->MODER |= 0b0100000000;
...