小蜜蜂笔记
嵌入式开发与物联网应用教育践行者

【STM8教程-03】GPIO的基本原理及应用

项目案例:按键控制灯光的开关切换

硬件电路:详见:XMF06A电路结构框图
功能要求
步骤1:系统上电后,D3灯到D6灯依次点亮,然后依次熄灭,进行灯光检测。
步骤2:查询按键SW3的状态,如果SW3按下,等待按键松开后,切换D3灯的开关状态。
步骤3:重复步骤2。

STM8关于GPIO的知识要点

STM8S106K6芯片共有32个引脚,其中GPIO有25个,但实际上可以供开发使用的只有22个。因为PA1PA2需要用于外部晶振,PD1需要用与仿真器的数据接口。

STM8的GPIO有如下的主要功能特性
1. 端口的各个位可以被单独配置。
2. 可选择的输入模式:浮动输入带上拉输入
3. 可选择的输出模式:推挽式输出开漏输出
4. 数据输入和输出采用独立的寄存器
5. 外部中断可以单独使能和关闭。
6. 片上外设的I/O功能复用。
7. 输出摆率控制用以减少EMC噪声。
8. 当作为模拟输入时,可以关闭输入施密特触发器来降低功耗。
9. 在数据输出锁存时,支持“读-修改-写”。
10. 输入兼容5V电压。
11. I/O端口的工作电压范围是1.6V到VDDIOmax。

每一个端口有5个相关的寄存器,每个寄存器都可以位操作
数据输出寄存器 Px_ODR
引脚输入寄存器 Px_IDR
数据方向寄存器 Px_DDR
控制寄存器1 Px_CR1
控制寄存器2 Px_CR2
寄存器的具体定义详见:【STM8开发速查】GPIO常用寄存器定义与应用参考

一个I/O端口工作在输入还是输出模式,取决于该端口的数据方向寄存器的状态。
输入模式:将DDRx位清0就选择了输入模式。
在该模式下,读Px_IDR寄存器的位将返回对应I/O引脚上的电平值。
输出模式:将DDRx位置1就选择了输出模式。
在该模式下,向Px_ODR寄存器的位写入数据将会通过锁存器输出对应的数字值到I/O端口。

项目案例的基本实现思路

为了编程方便,首先对LED灯和按键对应的引脚作宏定义的预处理。在这里需要注意的是,写GPIO读GPIO是两个不同的寄存器。这两个寄存器都可以位操作,在头文件iostm8s105k6.h中对寄存器的位做了命名,我们可以直接利用这些名字操作寄存器对应的位。例如:PC2的输出位就是PC_ODR_ODR2PB0引脚的输入位为PB_IDR_IDR0

在对具体引脚操作之前,需要对其进行初始化。首先对数据方向寄存器Px_DDR进行设置,确定了引脚输入或输出之后,再根据应用需要对Px_CR1和Px_CR2进行设置。对GPIO进行了正确的初始化后,就可以根据项目案例的要求进行相应的逻辑编码了。

案例的参考源码及注释

#include "iostm8s105k6.h"

#define D3      PC_ODR_ODR1
#define D4      PC_ODR_ODR2
#define D5      PC_ODR_ODR3
#define D6      PC_ODR_ODR4

#define SW3     PB_IDR_IDR0
/*=========================普通延时函数==========================*/
void Delay(unsigned int t)
{
  while(t--);
}
/*=========================灯光测试函数==========================*/
void LED_Check()
{
  //D3灯到D6灯依次点亮
  D3 = 1;               //D3灯点亮
  Delay(60000);
  D4 = 1;               //D4灯点亮
  Delay(60000);
  D5 = 1;               //D5灯点亮
  Delay(60000);
  D6 = 1;               //D6灯点亮
  Delay(60000);
  //D3灯到D6灯依次熄灭
  D3 = 0;               //D3灯熄灭
  Delay(60000);
  D4 = 0;               //D4灯熄灭
  Delay(60000);
  D5 = 0;               //D5灯熄灭
  Delay(60000);
  D6 = 0;               //D6灯熄灭
  Delay(60000);
}

/*========================GPIO端口初始化=========================*/
void Init_GPIO()
{
  //初始化按键SW3的PB0引脚
  PB_DDR &= ~0x01;      //PB0设置为输入模式              
  PB_CR1|= 0x01;        //PB0设置为带上拉电阻输入
  PB_CR2&= ~0x01;       //PB0禁止外部中断
  //初始化D3灯的PC1引脚
  PC_DDR |= 0x1e;       //PC1、PC2、PC3、PC4设置为输出模式
  PC_CR1|= 0x1e;        //PC1、PC2、PC3、PC4设置为推挽输出
  PC_CR2&= ~0x1e;       //PC1、PC2、PC3、PC4输出速度最大为2MHz
}
/*===========================按键扫描函数========================*/
void Scan_Keys()
{
  if(SW3 == 0)          //监测SW3的输入信号
  {
    Delay(100);         //按键去抖动处理
    if(SW3 == 0)        //确认为SW3按键触发信号
    {
      while(SW3 == 0);  //等待按键松开
      D3 = ~D3;         //切换D3灯的开关状态
    }
  }
}
/*==========================主函数===============================*/
void main()
{
  Init_GPIO();          //初始化GPIO端口
  LED_Check();          //依次检测灯光
  while(1)
  {
    Scan_Keys();        //轮询扫描按键
  }
}
赞(6)
未经允许不得转载:小蜜蜂笔记 » 【STM8教程-03】GPIO的基本原理及应用

小蜜蜂笔记 更专业 更方便 更高效

联系我们精品小店