STM32点亮LED的三种方法详解

学习STM32的第一课,都是点亮LED。

芯片:STM32F107RC

系统时钟:72MHz

LED引脚:板载引脚PD2,正极接3.3V,负极接PD2,低电平点亮

第一种方法:使用库函数操作

LED引脚配置:

void LED_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;//GPIO配置结构体
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD, ENABLE);//使能PD2的时钟,GPIOD

	//PD2引脚配置
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;//PD2引脚
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;//推挽输出
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;//50MHz
	GPIO_Init(GPIOD, &GPIO_InitStruct);//GPIO配置
  
}

主函数:

int main(void)
{
  delay_init();//延时函数初始化
  LED_Init();//led的引脚初始化
  
  while(1)
  {
    GPIO_ResetBits(GPIOD, GPIO_Pin_2);//PD2输出低电平,点亮
    delay_ms(200); //延时200ms
    GPIO_SetBits(GPIOD, GPIO_Pin_2);//PD2输出高电平,熄灭
    delay_ms(200); //延时200ms
  }
}

第二种方法:使用寄存器操作

LED引脚配置:

void LED_Init(void)
{
	RCC->APB2ENR |= 1<<5;  //使能GPIOD
	GPIOD->CRL &= 0xFFFFF0FF; //把2#引脚对应位清零
	GPIOD->CRL |= 0x00000300; //配置2#引脚为推挽输出模式,速度50MHz
}

解释:

1.第1句:RCC->APB2ENR寄存器的位[5]设为1,表示GPIOD时钟使能。类似的还有位[2]表示GPIOA,位[3]表示GPIOB,位[4]表示GPIOC,设为1表示使能,设为0表示失能。

1<<5就是二进制 0010 0000,位[5]为1,(|=)操作就是把位[5]设为1,其他位不变。

2.第2句:GPIOD->CRL寄存器的位[11:8]这4个位表示2#引脚,联系上面操作的是GPIOD,这里操作2#引脚,也就是操作GPIOD.2。类似的还有CRL寄存器的[3:0]这4位操作0#引脚,[7:4]这4位操作1#引脚。

0xFFFFF0FF就是位[11:8]这4位是0,其他位都是1,(&=)操作就是把[11:8]这4位清零,其他位不变。

3.同理,第3句的意思是把[11:8]这4位设为0011,其中11表示GPIO配置成输出模式,速度50MHz;00表示推挽模式,连在一起就是把PD2配置成推挽输出模式。

主函数:

int main(void)
{
	delay_init();//延时函数初始化
	LED_Init();//LED引脚初始化

	while(1)
	{
		GPIOD->ODR |= 1<<2;   //设置PD2输出高电平1,熄灭
		delay_ms(200); //延时200ms
		GPIOD->ODR &= ~(1<<2); //设置PD2输出低电平0,点亮 
		delay_ms(200); //延时200ms
	}
}

解释:

1.GPIOD->ODR寄存器的位[2]表示引脚输出高电平还是低电平,(1<<2)表示二进制0100,也就是位[2]为1,这句表示把ODR寄存器的位[2]设为高电平,其他位不变,LED熄灭。

2.(1<<2)表示二进制0100,那么~(1<<2)就表示二进制1011,也就是位[2]清零,其他位不变,这句表示把ODR寄存器的位[2]设为低电平,LED点亮了。

第三种方法:电平翻转

其实这也不算一种方法,只是一个翻转引脚电平,让LED闪烁的小技巧。

LED引脚配置函数,用第一种或第二种方法都可以

主函数:

int main(void)
{
	delay_init();
	LED_Init();
	while(1)
	{
		GPIOD->ODR ^= GPIO_Pin_2;//翻转PD2电平
		delay_ms(200); //延时200ms
	}
}

解释:

GPIO_Pin_2是定义在stm32f10x_gpio.h里面的宏定义,

#define GPIO_Pin_2    ((uint16_t)0x0004)

16进制数4对应的二进制是0100,也就是位[2]为1,(^=)操作会不断翻转这一位,把这一位反复设为0或1,也就实现了LED的亮和灭。

总结:

以上的方法,其实推荐的还是第一种,用标准库函数来配置和操作,这样代码的可读性好。

第二种方法看起来代码量很少,但是可读性不佳,可以参照理解如何操作寄存器。

有关寄存器的详细配置,就要多看看stm32参考手册了。

另外关于位操作,可以参考这篇文章:

简单理解16进制

简单理解位运算:位与&、位或|、位非~、异或^、左移<<、右移>>

物联沃分享整理
物联沃-IOTWORD物联网 » STM32点亮LED的三种方法详解

发表评论