搜索
bottom↓
回复: 28

STM8固件库GPIO学习笔记

[复制链接]

出0入0汤圆

发表于 2009-3-23 22:38:12 | 显示全部楼层 |阅读模式
[如果转载,请注明原作者ifree64,谢谢]

1、STM8的寄存器映射
STM8 core采用了哈佛结构,有两条总线分别用于访问Flash和RAM,但Flash,RAM,GPIO and peripheral registers都被映射到了线性的16Mbyte(24位地址)的存储器空间中;stm8s208rb的GPIO and peripheral registers被映射到了0x00 5000 ~ 0x00 57FF地址空间。所以要在C语言中访问外围设备寄存器我们只需要指向这些地址空间的指针即可了。

2、STM8的寄存器的地址
在STM8中,与某个外围设备有关的寄存器在地址上都是顺序排列的;比如与GPIO有关的寄存器有ODR、IDR、DDR、CR1、CR2,与PA口有关的这五个寄存器就被安排在了0x00 5000~0x00 5004这5个地址空间中,它们有一个0x005000的基地址,分别偏移0,1,2,3,4。

3、”stm8s.h"中与GPIO有关的定义,以及固件库中访问外围设备寄存器的方法
typedef struct GPIO_struct
{
  vu8 ODR; /*!< Output Data Register */
  vu8 IDR; /*!< Input Data Register */
  vu8 DDR; /*!< Data Direction Register */
  vu8 CR1; /*!< Configuration Register 1 */
  vu8 CR2; /*!< Configuration Register 2 */
}
GPIO_TypeDef;

#define GPIOA_BaseAddress       0x5000
#define GPIOB_BaseAddress       0x5005
#define GPIOC_BaseAddress       0x500A
#define GPIOD_BaseAddress       0x500F
#define GPIOE_BaseAddress       0x5014
#define GPIOF_BaseAddress       0x5019

#define GPIOA ((GPIO_TypeDef *) GPIOA_BaseAddress)
#define GPIOB ((GPIO_TypeDef *) GPIOB_BaseAddress)
#define GPIOC ((GPIO_TypeDef *) GPIOC_BaseAddress)
#define GPIOD ((GPIO_TypeDef *) GPIOD_BaseAddress)
#define GPIOE ((GPIO_TypeDef *) GPIOE_BaseAddress)
#define GPIOF ((GPIO_TypeDef *) GPIOF_BaseAddress)

在结构体GPIO_TypeDef中,ODR,IDR,DDR,CR1,CR2的偏移分别是0,1,2,3,4正好与STM8S208RB对这几个安排一致,当我们将0x5000这个地址转换为指向GPIO_TypeDef的指针后,
我们就可以用类似GPIOA->ODR的方法访问寄存器了。非常巧妙,STM32中也是这种方法。

4、GPIO特性简述
STM8的每一个GPIO引脚都可以独立的作为输入/输出IO引脚使用,作为输入IO引脚使用时,每一个IO引脚都可以作为外部中断的触发输入端使用,输入有上拉和悬浮,输出有模拟开漏和推挽模式。
DDR用于设置方向,ODR用于输出,IDR用于输入,CR1、CR2用于控制,具体可参考数据手册,使用固件库时我们可以不关心具体值。

5、GPIO的初始化
固件库为我们提供了GPIO_Init这个函数,用于GPIO工作模式的初始化设置,它的原型为
void GPIO_Init(GPIO_TypeDef* GPIOx,  GPIO_Pin_TypeDef GPIO_Pin, GPIO_Mode_TypeDef GPIO_Mode);
第一个参数是上面提到的GPIOA这样的指针,第二、三个参数都是枚举型变量(本质就是一些常数),用来制定要初始化的引脚和工作模式。枚举变量定义如下:
typedef enum
{
  GPIO_MODE_IN_FL_NO_IT      = (u8)0b00000000,  /*!< Input floating, no external interrupt */
  GPIO_MODE_IN_PU_NO_IT      = (u8)0b01000000,  /*!< Input pull-up, no external interrupt */
  GPIO_MODE_IN_FL_IT         = (u8)0b00100000,  /*!< Input floating, external interrupt */
  GPIO_MODE_IN_PU_IT         = (u8)0b01100000,  /*!< Input pull-up, external interrupt */
  GPIO_MODE_OUT_OD_LOW_FAST  = (u8)0b10000000,  /*!< Output open-drain, low level, no slope control */
  GPIO_MODE_OUT_PP_LOW_FAST  = (u8)0b11000000,  /*!< Output push-pull, low level, no slope control */
  GPIO_MODE_OUT_OD_LOW_SLOW  = (u8)0b10100000,  /*!< Output open-drain, low level, slow slope */
  GPIO_MODE_OUT_PP_LOW_SLOW  = (u8)0b11100000,  /*!< Output push-pull, low level, slow slope */
  GPIO_MODE_OUT_OD_HIZ_FAST  = (u8)0b10010000,  /*!< Output open-drain, high-impedance level, no slope control */
  GPIO_MODE_OUT_PP_HIGH_FAST = (u8)0b11010000,  /*!< Output push-pull, high level, no slope control */
  GPIO_MODE_OUT_OD_HIZ_SLOW  = (u8)0b10110000,  /*!< Output open-drain, high-impedance level, slow slope */
  GPIO_MODE_OUT_PP_HIGH_SLOW = (u8)0b11110000   /*!< Output push-pull, high level, slow slope */
}GPIO_Mode_TypeDef;

typedef enum
{
  GPIO_PIN_0    = ((u8)0x01),  /*!< Pin 0 selected */
  GPIO_PIN_1    = ((u8)0x02),  /*!< Pin 1 selected */
  GPIO_PIN_2    = ((u8)0x04),  /*!< Pin 2 selected */
  GPIO_PIN_3    = ((u8)0x08),   /*!< Pin 3 selected */
  GPIO_PIN_4    = ((u8)0x10),  /*!< Pin 4 selected */
  GPIO_PIN_5    = ((u8)0x20),  /*!< Pin 5 selected */
  GPIO_PIN_6    = ((u8)0x40),  /*!< Pin 6 selected */
  GPIO_PIN_7    = ((u8)0x80),  /*!< Pin 7 selected */
  GPIO_PIN_LNIB = ((u8)0x0F),  /*!< Low nibble pins selected */
  GPIO_PIN_HNIB = ((u8)0xF0),  /*!< High nibble pins selected */
  GPIO_PIN_ALL  = ((u8)0xFF)   /*!< All pins selected */
}GPIO_Pin_TypeDef;

我们可以如此使用这个函数:

#define LEDS_PORT (GPIOH)
#define LED1_PIN  (GPIO_PIN_3)
#define LED2_PIN  (GPIO_PIN_2)
#define LED3_PIN  (GPIO_PIN_1)
#define LED4_PIN  (GPIO_PIN_0)

#define BUTTON_PORT (GPIOC)
#define BUTTON_PIN  (GPIO_PIN_0)

/* Initialize I/Os in Output Mode */
GPIO_Init(LEDS_PORT, (LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN), GPIO_MODE_OUT_PP_LOW_FAST);
/* Initialize I/O in Input Mode with Interrupt */
GPIO_Init(BUTTON_PORT, BUTTON_PIN, GPIO_MODE_IN_FL_IT);

6、GPIO的操作函数
void GPIO_Write(GPIO_TypeDef* GPIOx, u8 PortVal);             //写端口,8个脚一起设置
void GPIO_WriteHigh(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins); // 将指定脚设置为高
void GPIO_WriteLow(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);  // 讲指定脚设置为低
void GPIO_WriteReverse(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef PortPins);  // 指定脚取反
u8 GPIO_ReadInputData(GPIO_TypeDef* GPIOx);  // 读引脚
u8 GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);  // 读端口,上次锁存到ODR中的数据
BitStatus GPIO_ReadInputPin(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin); // 读制定脚的状态,高电平返回非0,低返回0

// NewState取值为ENABLE或DISABLE,用于配置外部的上拉有效或无效?这个函数怎么用我不懂,还请懂的朋友告知,非常感谢!
void GPIO_ExternalPullUpConfig(GPIO_TypeDef* GPIOx, GPIO_Pin_TypeDef GPIO_Pin, FunctionalState NewState)
{
  /* Check the parameters */
  assert_param(IS_GPIO_PIN_OK(GPIO_Pin));
  assert_param(IS_FUNCTIONALSTATE_OK(NewState));

  if (NewState != DISABLE) /* External Pull-Up Set*/
  {
    GPIOx->CR1 |= (u8)GPIO_Pin;       // CR1=1时,如输入则上拉,如输出则推挽
  } else /* External Pull-Up Reset*/
  {
    GPIOx->CR1 &= (u8)(~(GPIO_Pin));  //CR1=0时,如输入则悬浮,如输出则开漏
  }
}

出0入42汤圆

发表于 2009-3-23 23:37:34 | 显示全部楼层
沙发!

出0入0汤圆

发表于 2009-3-23 23:43:13 | 显示全部楼层
不 错 期待STM8   和STM32的好多设置一样。

我就奇怪了,为什么STM先出32位的,再出8位的? 是不是将来还出4位的??

出0入0汤圆

发表于 2009-4-18 12:40:28 | 显示全部楼层
楼主你好,我安装的STVD环境里没有stm8s.h文件,请问到哪弄STM8的固件库,谢谢!!

出0入0汤圆

 楼主| 发表于 2009-4-18 20:22:41 | 显示全部楼层
到ST的网站下载STM8的固件函数库。

出0入0汤圆

发表于 2009-4-21 09:04:47 | 显示全部楼层
多谢楼主指点,还有个问题就是,我在调用
GPIO_Init(LEDS_PORT, (LED1_PIN | LED2_PIN | LED3_PIN | LED4_PIN), GPIO_MODE_OUT_PP_LOW_FAST);
的时候总是报错
#error cpstm8 ..\..\main.c:46(14) incompatible argument type
不知如何解决,我还按照ST提供的GPIO例程重新建立一个工程,按照例程把需要的文件加进去,可是编译时,ST的例程成功,我的总报错,不知什么地方出了问题,还请楼主或其他高手指点,万分感谢!!!

出0入0汤圆

发表于 2009-4-21 10:51:24 | 显示全部楼层
LS,出错的意思是参数的类型不对,你看看函数传递的变量是否和原型声明的一样。

出0入0汤圆

发表于 2009-4-23 15:31:30 | 显示全部楼层
谢谢指点,总算找出来了!

出0入0汤圆

发表于 2010-3-21 20:46:57 | 显示全部楼层
xlswyf,你好,我现在也遇到下面弄问题,请问你是怎样找出来的?
我按照ST提供的GPIO例程重新建立一个工程,按照例程把需要的文件加进去,可是编译时,ST的例程成功,我的总报错,不知什么地方出了问题?
hahacomcn说,出错的意思是参数的类型不对,看看函数传递的变量是否和原型声明的一样。
我还是没有看明白,请指点,谢谢。

出0入0汤圆

发表于 2010-4-2 17:25:40 | 显示全部楼层
我做GPIO中断实验的时候 老是一进入TL1就马上跳出来了 不知道为什么 请问LZ遇到过这样的问题吗

出0入0汤圆

发表于 2010-4-20 16:59:51 | 显示全部楼层
GPIOB用作双向I/O口,该怎么初始化?GPIO_Write,GPIO_ReadInputData两个函数就可以直接应用。在读写RC500时候还是读写不起来、

出0入0汤圆

发表于 2010-6-11 09:53:41 | 显示全部楼层
回复【2楼】chen1986sl 动感超人
      不 错 期待stm8   和stm32的好多设置一样。
我就奇怪了,为什么stm先出32位的,再出8位的? 是不是将来还出4位的??
-----------------------------------------------------------------------

不用奇怪,32的是用的ARM公司的内核,当然比较快,8位的则是自己开发的,当然得慢点

出0入0汤圆

发表于 2011-9-17 09:43:22 | 显示全部楼层
stm8的库还是小很多啊 ,呵呵 !比较容易上手些!

出0入0汤圆

发表于 2011-9-29 22:45:51 | 显示全部楼层
一看都这些头都大了哦,
配置的时候喜欢“裸”着配。

出0入0汤圆

发表于 2011-11-3 10:08:55 | 显示全部楼层
回复【5楼】xlswyf  
-----------------------------------------------------------------------

有些引用的东西。编译器不认。找找是不是定义了(缺少宏定义)。

出0入0汤圆

发表于 2011-11-3 10:11:24 | 显示全部楼层
回复【5楼】xlswyf  
-----------------------------------------------------------------------

在main.c中加#include“”
就ok

出0入0汤圆

发表于 2011-11-5 16:57:13 | 显示全部楼层
学习

出0入0汤圆

发表于 2012-1-13 10:14:12 | 显示全部楼层
请问哪里有stm8L的库下载......

出0入0汤圆

发表于 2012-2-1 15:51:13 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-6-11 13:22:23 | 显示全部楼层
学习了。

出0入0汤圆

发表于 2013-2-8 17:48:49 | 显示全部楼层
mark!准备学stm8

出0入0汤圆

发表于 2013-8-14 23:53:01 | 显示全部楼层
mark!! 支持技术交流

出0入0汤圆

发表于 2013-8-16 09:47:41 | 显示全部楼层
发送一个非常好用的STM8库文件调用的软件

出0入0汤圆

发表于 2013-8-16 09:48:08 | 显示全部楼层
中文的哦

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-9-24 16:08:20 | 显示全部楼层
虽然有点晚,我也遇到了9楼的问题,我的原因如下
我用的芯片是003,例程中调用了GPIOH端口,但是003芯片中没有H端口,所以就报参数不匹配了,我把H端口改成A端口就OK了

出0入0汤圆

发表于 2013-9-27 11:56:53 | 显示全部楼层
  哥,去哪里找的库...?能否给我发一份?

出0入0汤圆

发表于 2014-11-26 19:18:44 | 显示全部楼层
顶                     

出0入0汤圆

发表于 2014-11-26 20:30:56 | 显示全部楼层
这个最基础了!~

出0入0汤圆

发表于 2020-6-23 15:10:12 | 显示全部楼层
GPIO操作非常便利啊
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-19 20:59

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表