Re:从零开始的stm32(1、32第一个程序,点亮led灯)

3 篇文章 0 订阅
2 篇文章 0 订阅

鸽了这么久终于又想起了CSDN的密码
今天大家一起来学习stm32,对于32如何建工程,网络上已经有很多例子,包括文件也有很多,如果需要的话可以在文末找到群号,我会在群文件里面分享,这里就不再浪费口舌。

32对于51单片机来说,无论是I/O口还是寄存器都有特别大的变化,举个很简单的例子:51单片机的I/O一般是不需要配置的,而32的I/O口需要使能,需要选择模式。(模拟输入、浮空输入、上、下拉输入、开漏输出、推挽输出、复用开漏/推挽输出共计八个模式),所以,想要学好32就必须了解32的库函数定义。

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

这就是一段GPIO初始化的结构体,结构体里面仍然是结构体,比如mode这个

typedef enum
{ GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

真正初始化的函数是

void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)

相信大家看到这里已经懵逼了,这到底该**怎么才能初始化啊,一个I/O口怎么这么麻烦!

不要炸鸡,听我给大家讲解

首先看到前两个函数框,大家估计已经明白了,32的库函数几乎有一半都是结构体,所以大家C语言功底一定要扎实,咱们写单片机的不像搞程序的那个复杂深入,但是基本功一定不要落下。

大家看到入口参数其实就俩GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct
我们先看看GPIO_TypeDef* GPIOx,从名字上就能看出这是找I/O口的,就和51单片机是一样的,比如51叫P1那么32就叫GPIOA,第二个是初始化I/O口的,我们右键进入定义看看

typedef struct
{
  uint16_t GPIO_Pin;             /*!< Specifies the GPIO pins to be configured.
                                      This parameter can be any value of @ref GPIO_pins_define */

  GPIOSpeed_TypeDef GPIO_Speed;  /*!< Specifies the speed for the selected pins.
                                      This parameter can be a value of @ref GPIOSpeed_TypeDef */

  GPIOMode_TypeDef GPIO_Mode;    /*!< Specifies the operating mode for the selected pins.
                                      This parameter can be a value of @ref GPIOMode_TypeDef */
}GPIO_InitTypeDef;

这里也就是刚刚那一段,我们可以看到这个结构体里面有三个东西

uint16_t GPIO_Pin;   GPIOSpeed_TypeDef GPIO_Speed;  GPIOMode_TypeDef GPIO_Mode;

看后面的注释可以知道uint16_t GPIO_Pin;是定义引脚的,也就是51中的P1^1一样

GPIOSpeed_TypeDef GPIO_Speed;这是定义I/O口频率的,我们右键进去看看

typedef enum
{ 
  GPIO_Speed_10MHz = 1,
  GPIO_Speed_2MHz, 
  GPIO_Speed_50MHz
}GPIOSpeed_TypeDef;

这里我们有三个选择10 2 50,根据需要自行决定
我们看下一个

GPIOMode_TypeDef GPIO_Mode;这是对IO口模式的选择,继续右键

typedef enum
{ GPIO_Mode_AIN = 0x0,
  GPIO_Mode_IN_FLOATING = 0x04,
  GPIO_Mode_IPD = 0x28,
  GPIO_Mode_IPU = 0x48,
  GPIO_Mode_Out_OD = 0x14,
  GPIO_Mode_Out_PP = 0x10,
  GPIO_Mode_AF_OD = 0x1C,
  GPIO_Mode_AF_PP = 0x18
}GPIOMode_TypeDef;

可以看到这里也就是我最开始说的八种模式
好了了解这些之后我们就开始第一步,初始化一个I/O口吧,那么因为我的LED在B5和E5,那我就以这两个I/O口为例子。

void LED_Init(void)
{
 
 GPIO_InitTypeDef  GPIO_InitStructure;
 	
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE);	 //使能PB,PE端口时钟
	
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;				 //LED0-->PB.5 端口配置
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
 GPIO_Init(GPIOB, &GPIO_InitStructure);					 //根据设定参数初始化GPIOB.5
 GPIO_SetBits(GPIOB,GPIO_Pin_5);						 //PB.5 输出高

 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;	    		 //LED1-->PE.5 端口配置, 推挽输出
 GPIO_Init(GPIOE, &GPIO_InitStructure);	  				 //推挽输出 ,IO口速度为50MHz
 GPIO_SetBits(GPIOE,GPIO_Pin_5); 						 //PE.5 输出高 
}

我知道大家又懵了,我来依次为大家解答
Q:第一行干什么的?
A:第一行相当于是定义一个GPIO_InitStructure结构体来初始化I/O口

Q:RCC_APB2PeriphClockCmd是什么东西?
A:这是使能B E这两个I/O口的函数。因为GPIOB和BPIOE在APB2总线上(可以在中文参考手册查到其他GPIO的总线,群里有),所以我们需要用这个函数,大家记住即可。

接下来的三行就是一个规范的结构体使用方法,根据定义中的数据,依次录入。那么因为我们是要点灯,所以我们用推挽输出。接着GPIO_Init来根据参数初始化GPIOB。

GPIO_SetBits是输出高电平的函数,使用方法看我例程也就明白了
这里补充一下:低电平是GPIO_ResetBits

Q:为什么GPIOE你只设置了Pin脚的参数,其他参数都不设置呢?
A:因为其他的和GPIOB一样,都是推挽输出和50MHz所以不需要另外设置。

LED_Init写完了之后我们就可以写主函数了

int main(void)
{
	delay_init();
	LED_Init();
	while(1)
	{
		LED0 = 0;
		LED1 = 1;
		delay_ms(300);
		LED0 = 1;
		LED1 = 0;
		delay_ms(300);
	}
}

学过51的同学应该都能看懂吧?
不过还是得说明一下

delay_init();这个函数在delay.h里面已经定义过了,不需要自己写。(群里有工程文件)
LED0 和LED1需要我们自己在led.h头文件中宏定义

#define LED0 PBout(5)
#define LED1 PEout(5)

赶快将代码编译到stm32开发板上试试吧!

下一篇我将会更新STC51的PWM,然后更新STC12的PWM,为更新STM32的PWM做好准备

交流群号:1033131250

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
Using FreeRTOS and libopencm3 instead of the Arduino software environment, this book will help you develop multi-tasking applications that go beyond Arduino norms. In addition to the usual peripherals found in the typical Arduino device, the STM32 device includes a USB controller, RTC (Real Time Clock), DMA (Direct Memory Access controller), CAN bus and more. Each chapter contains clear explanations of the STM32 hardware capabilities to help get you started with the device, including GPIO and several other ST Microelectronics peripherals like USB and CAN bus controller. You’ll learn how to download and set up the libopencm3 + FreeRTOS development environment, using GCC. With everything set up, you’ll leverage FreeRTOS to create tasks, queues, and mutexes. You’ll also learn to work with the I2C bus to add GPIO using the PCF8574 chip. And how to create PWM output for RC control using hardware timers. You'll be introduced to new concepts that are necessary to master the STM32, such as how to extend code with GCC overlays using an external Winbond ?W25Q32 flash chip. Your knowledge is tested at the end of each chapter with exercises. Upon completing this book, you’ll be ready to work with any of the devices in the STM32 family. Beginning STM32 provides the professional, student, or hobbyist a way to learn about ARM without costing an arm! What You'll Learn Initialize and use the libopencm3 drivers and handle interrupts Use DMA to drive a SPI based OLED displaying an analog meter Read PWM from an RC control using hardware timers Who This Book Is For Experienced embedded engineers, students, hobbyists and makers wishing to explore the ARM architecture, going beyond Arduino limits.
下面是一个简单的STM32点亮第一个LED程序: 1. 首先,需要在STM32的开发环境中创建一个工程,并将工程名设置为“LED_Blink”。 2. 然后,需要在工程中添加一个源文件,命名为“main.c”。 3. 在“main.c”文件中,需要包含以下头文件: ``` #include "stm32f10x.h" ``` 4. 在“main.c”文件中,需要定义一个函数来初始化GPIO端口,以便控制LED的亮灭。以下是初始化GPIO端口的函数: ``` void GPIO_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOC, &GPIO_InitStructure); } ``` 5. 在“main.c”文件中,需要定义一个函数来控制LED的亮灭。以下是控制LED的亮灭的函数: ``` void LED_Blink(void) { while (1) { GPIO_SetBits(GPIOC, GPIO_Pin_13); Delay(1000000); GPIO_ResetBits(GPIOC, GPIO_Pin_13); Delay(1000000); } } ``` 6. 在“main.c”文件中,需要定义一个函数来实现延时。以下是实现延时的函数: ``` void Delay(__IO uint32_t nCount) { while(nCount--) { } } ``` 7. 最后,在“main.c”文件中,需要定义一个主函数,并在主函数中调用以上三个函数。以下是主函数的代码: ``` int main(void) { GPIO_Init(); LED_Blink(); } ``` 以上就是一个简单的STM32点亮第一个LED程序。需要注意的是,针脚号和其他硬件配置可能会因不同的开发板而有所不同,需要根据实际情况进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值