C 无法打开或关闭绿色/蓝色LED STM32F429ZI-核子板?

C 无法打开或关闭绿色/蓝色LED STM32F429ZI-核子板?,c,embedded,C,Embedded,我试图写一个裸机程序闪烁绿色led。 事实上,我无法打开或关闭任何LED。这是一块现成的木板。 董事会名称为核仁F429ZI。 我已经看完了示意图,我确信针脚是PA5,即端口A和针脚编号5。但是,led根本不闪烁。我可以看到我的代码是使用uVision IDE加载到STM32板上的 我曾尝试设置蓝色LED,即PB7,但也没有任何效果 void delayMs(int delay); int main(void) { //enable clock access to A RCC

我试图写一个裸机程序闪烁绿色led。 事实上,我无法打开或关闭任何LED。这是一块现成的木板。 董事会名称为核仁F429ZI。

我已经看完了示意图,我确信针脚是
PA5
,即端口A和针脚编号5。但是,led根本不闪烁。我可以看到我的代码是使用uVision IDE加载到STM32板上的

我曾尝试设置蓝色LED,即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++)
        {
        }
    }
}

您不应该直接修改ODR,因为它对整个端口执行读/写操作。相反,您应该使用BSRR寄存器,在这里您只能影响一位。请注意,一些STM32部件使用单个32位BSRR寄存器来设置和清除位(一个操作左移16位),而其他部件使用两个16位寄存器,因此有关详细信息,请参阅参考手册或头文件

您的MODER设置不正确。您需要先清除PA5的2位,然后再输入01,例如

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

非常无用的是,Nucleo F429ZI UM1974用户手册下载链接(在撰写本文时)似乎已断开,但我已找到一份副本,三个用户LED的pin分配如下所述:

示意图表明,焊桥SB120和SB119的出厂状态设置为PB0上的LD1,而不是PA5。您尝试设置LD2(蓝色)的问题在于,您没有在RCC中启用GPIOB-它在LD1(绿色)尝试中启用GPIOA

另一个问题是GPIO MODER的设置假定端口的重置状态为零。事实并非如此(尽管这是针对所讨论的特定管脚-因此在本例中您可以“侥幸逃脱”):

最好在一个位置定义所有端口/管脚特定常数,以便您可以轻松切换或添加输出,并且出错的可能性较小:

#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 ;
}
#定义LED#U端口GPIOB
#定义LED_端口_RCC_EN 0x2u
#定义GPIO_模式_掩码~0x3u
#定义GPIO_模式_输出0x1u
#定义绿色发光二极管引脚0u
#定义蓝色发光二极管引脚7u
#定义红色发光二极管引脚14u
#定义闪烁发光二极管绿色发光二极管引脚
内部主(空)
{
RCC->AHB1ENR |=LED_端口_RCC_EN;
LED_PORT->MODER&=GPIO_MODE_MASK
这是核仁144-STM32F429ZI的完整解决方案。
#包括“stm32f4xx.h”
#定义LED_端口GPIOB
#定义LED_端口_RCC_EN 0x2u
#定义GPIO_模式_掩码~0x3u
#定义GPIO_模式_输出0x1u
#定义绿色发光二极管引脚0u
#定义蓝色发光二极管引脚7u
#定义红色发光二极管引脚14u
#定义闪烁发光二极管蓝色发光二极管引脚
无效延迟ms(无符号延迟);
内部主(空)
{
RCC->AHB1ENR |=LED_端口_RCC_EN;//为端口B启用
//LED|U端口->MODER&=GPIO|U模式|U掩码MODER |=GPIO|U模式|U输出MODER |=0x4000;//蓝色LED PB7
GPIOB->MODER |=0x1;//绿色LED PB0
GPIOB->ODR |=0x1;//绿色LED ODR
GPIOB->MODER |=0x1 ODR |=0x1 AHB1ENR |=0x1 MODER |=//输入模式PC13-第13引脚0
//默认情况下,管脚仅为输入
GPIOC->MODER |=0;
对于(;;)
{
//按下蓝色按钮

如果((GPIOC->IDR&(1)时钟设置在哪里?为什么
int main(无效)
,STM32不是PC。优化器与延迟循环有什么关系?最好使用计时器。显示
GPIOA
RCC
的声明,我打赌它们不会波动。在尝试闪烁之前,请尝试打开或关闭它-如果这两个都有效(在单独的程序中)然后是你不明智的延迟实现出了问题(在任何情况下都是有缺陷的)。如果不是,那么你的GPIO设置或pin。如果是现成的板,那么告诉我们它是什么,如果你对原理图不确定,有人可以检查你的假设(甚至阅读文档)@means matters:它们是在供应商提供的部件头文件中定义的,所以我认为不太可能-我怀疑他自己定义了它们,或者使用了一些损坏的第三方实现。但是延迟循环计数器是一个问题。虽然在这种情况下使用BSRR可能是更好的方法,但使用ODR的读写修改本身并没有错,但是,如果端口也在不同的线程或中断处理程序中被修改,则可能是不安全的。但是,这不是问题的原因。@ChrisStratton:这是我认为减少未使用引脚功耗的建议状态,而不是重置状态,对于这一部分,端口A为0xA800 0000,端口B为0x0000 0280其他端口为0x0000 0000。该板的LED指示灯位于PB0、PB7和PB14上,因此在这种情况下,您可以“侥幸逃脱”.理查德的观点很好。嗯,好吧,我承认我检查了RM中的L0而不是F4。但如果是这样的话,那么这封回复中的任何一点都与问题没有任何实际关系,只是一些无关紧要的评论。不确定,但如果我给出#define FLASH_LED到BLUE_LED,代码就不起作用了_PIN@kurramkurramD:试试看现在-我已经纠正了MODER掩码移位-它是每个引脚两位,而不是1位。对不起,对它进行盲编码,未经测试。
#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++ )
        {
        }
    }
}
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 );
}
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++ )
        {
        }
    }
}