嵌入式 · 2010-05-22

STM32 入门教程 GPIO 简单应用和外部中断

这个章节我们将学习最基本的 STM32 的 GPIO 的应用. 我们将分为两个章节来学习.

第一部份: GPIO 的基本应用和 IO 口的配置
第二部份: 外部中断的使用

————————————————————————–

1: 设计要求:
开发板上有 2 个 LED,  我们的目的为有规律的点亮 LED1 和 LED2. 当按键按下去的时候所有的灯灭, 等待 2 秒钟后恢复有规律的点亮.

2: 硬件电路:

2.GIF

下载 (7.83 KB)

2009-7-29 22:55

3: 软件程序设计:
(1) 根据要求配置 GPIOA 中的 PA0,PA1 为输出, PA3, PA8 为输入

对于下面程序中的  GPIO_InitStructure.GPIO_Speed 和 GPIO_InitStructure.GPIO_Mode 推荐大家看下面两篇文章.

STM32 GPIO的十大优越功能综述

备注: 当STM32的GPIO端口设置为输出模式时,有三种速度可以选择:2MHz、10MHz和50MHz,这个速度是指I/O口驱动电路的速度,是用来选择 不同的输出驱动模块,达到最佳的噪声控制和降低功耗的目的。

STM32 GPIO端口的输出速度设置

备注: 共有8种模式,可以通过编程选择:

1. 浮空输入

2. 带上拉输入

3. 带下拉输入

4.

模拟

输入

5. 开漏输出——(此模式可实现hotpower说的真双向IO)

6. 推挽输出

7. 复用功能的推挽输出

8. 复用功能的开漏输出

模式7和模式8需根据具体的复用功能决定。

void GPIO_Configuration(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

/* Configure PA. as Output push-pull */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA, &GPIO_InitStructure);

/* Configure PA3,PA8  as input floating (EXTI Line3 , EXTI Line8) */

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 | GPIO_Pin_8;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA, &GPIO_InitStructure);

}

(2) 打开 GPIOA 的时钟

, 因为 STM32 是一个低功耗的 MCU , 每一个你使用的外围设备都需要单独开启时钟, 如果不开启将不能使用, 这个也是对于 STM32 初学者容易疏忽的地方

/* Enable GPIOA and AFIO clocks */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |

RCC_APB2Periph_AFIO, ENABLE);

STM32共有5种时钟源,其中三种不同的时钟源可用作为驱动系统时钟(SYSCLK);

1、HSI 由内部8MHz RC振荡器产生,它是可以直接用来作为系统时钟或经2分频后作为PLLSRC输入。

HIS时钟频率在出厂时被校准在1%(25°C),在系统复位时,工厂校准值会被装载到时钟控制寄存器的HISCAL[7..0] 位。

用户可以通过更改HISCAL[4..0]来调整HSI频率。

另外时钟寄存器中有一个HSIRDY位用来指示HSI RC是不稳定工作,在时钟启过后,直到这个标志位置被硬件置1后,HSI RC时钟才被输出。

HSI RC时钟还可以用时钟寄存器中的HSION位来启动和关闭。

HSI时钟同时也是HSE晶体荡振器的备用时钟源。

使用HSE时钟,程序设置时钟参数流程:

1、将RCC寄存器重新设置为默认值   RCC_DeInit;

2、打开外部高速时钟晶振HSE    RCC_HSEConfig(RCC_HSE_ON);

3、等待外部高速时钟晶振工作    HSEStartUpStatus = RCC_Wait

For

HSEStartUp();

4、设置AHB时钟         RCC_HCLKConfig;

5、设置高速AHB时钟     RCC_PCLK2Config;

6、设置低速速AHB时钟   RCC_PCLK1Config;

7、设置PLL              RCC_PLLConfig;

8、打开PLL              RCC_PLLCmd(ENABLE);

9、等待PLL工作   while(RCC_GetFlagStatus(RCC_FLAG_PLLRDY) == RESET)

10、设置系统时钟        RCC_SYSCLKConfig;

11、判断是否PLL是系统时钟     while(RCC_GetSYSCLKSource() != 0x08)

12、打开要使用的外设时钟    RCC_APB2PeriphClockCmd()/RCC_APB1PeriphClockCmd()

具体设置请参考下面的文章

STM32时钟系统与软件配置

STM32的时钟系统分析

STM32 的时钟与RTC

(3) 设置外部中断

, 所有的 GPIO 口都可以作为外部中断源. 具体可以参考下面这篇文章.

STM32中外部中断与外部事件

/* Connect EXTI Line3 to PA.3 */

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA, GPIO_PinSource3);

/* Configure EXTI Line3 to generate an interrupt on falling edge */

EXTI_InitStructure.EXTI_Line = EXTI_Line3;

EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;

EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;

EXTI_InitStructure.EXTI_LineCmd = ENABLE;

EXTI_Init(&EXTI_InitStructure);

同样不要忘记打开时钟, 我们在打开 PA 口的时候已经加上了 RCC_APB2Periph_AFIO, 这里再提醒大家一下.

/* Enable GPIOA and AFIO clocks */

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |

RCC_APB2Periph_AFIO, ENABLE);

最后就是编写外部中断入口函数.

void EXTI3_IRQHandler(void)

{

int i;

if(EXTI_GetITStatus(EXTI_Line9) != RESET)

{

GPIO_SetBits(GPIOA,GPIO_Pin_0);

GPIO_SetBits(GPIOA,GPIO_Pin_1);

for(i=0;i<=8000000;i++);

GPIO_ResetBits(GPIOA,GPIO_Pin_0);

GPIO_ResetBits(GPIOA,GPIO_Pin_1);

for(i=0;i<=1000000;i++)

/* Clear the EXTI line 3 pending bit */

EXTI_ClearITPendingBit(EXTI_Line3);

}

}

不要忘记在中断函数处理完成后清掉标志位,不然会不停的进入中断.

(4) 编译与调试

我们已经完成所有程序编写部份, 接下来就是将工程编译成功后下载到我们的 Mini-STM32 开发板中进行调试和仿真.

如果看到 LED 有规律的点亮和熄灭, 按下

按钮

后 LED 先是一起熄灭, 在一起点亮, 然后恢复有规律的点亮这个过程, 说明我们已经达到我们的设计目标.

————————————————————————–

总结: 我们学习完了这篇教程之后, 相信大家对下面几个方面的内容已经掌握了.
* GPIO 的设置
* STM32 GPIO 的优势
* STM32 的时钟结构
* 外部中断的配置
* 外部中断和外部事件的区别