STM8 - GPIO入门文件认识
更新时间:2023-11-10 08:55:01 阅读量: 教育文库 文档下载
STM8l最白菜的入门笔记(2)——gpio篇
v\\:* {behavior:url(#default#VML);} o\\:* {behavior:url(#default#VML);} w\\:* {behavior:url(#default#VML);} .shape {behavior:url(#default#VML);}
我们先来观察一下 例程里是怎么操作 gpio的。
我们打开discover这个例程。
我们看到main刚开始的几句就是gpio初始化。
(因为我曾折腾过STM32,所以多少熟一点,一看到这个,我就知道,事情就
在这,所以不会再看太多。)
我们截取其中几句看看。
* USER button init: GPIO set in input
interrupt active mode */
GPIO_Init( BUTTON_GPIO_PORT, USER_GPIO_PIN, GPIO_Mode_In_FL_IT);
/* Green led init: GPIO set in output */
GPIO_Init( LED_GREEN_PORT, LED_GREEN_PIN, GPIO_Mode_Out_PP_High_Fast);
/* Blue led init: GPIO set in output */
GPIO_Init( LED_BLUE_PORT, LED_BLUE_PIN, GPIO_Mode_Out_PP_High_Fast);
/* Counter enable: GPIO set in output for
enable the counter */
GPIO_Init( CTN_GPIO_PORT, CTN_CNTEN_GPIO_PIN,
GPIO_Mode_Out_OD_HiZ_Slow);
/* Wake up counter: for detect end of
counter GPIO set in input interupt active mode */
GPIO_Init( WAKEUP_GPIO_PORT, ICC_WAKEUP_GPIO_PIN, GPIO_Mode_In_FL_IT);
注释已经写得很明白了。
玩过430或者stm32的童鞋应该多少都知道,这些比较新款的单片机,跟以前
的51不太一样,那就是外部中断源贼多,而且是跟着gpio走的。
坦白说,现在回想起来,其实51的外部中断也是跟着io口走的,想起来了
吗?
INT0和INT1就是P3.0和P3.1,只不过它少一点而已。
但鉴于我们现在是要入门,所以,我们先不管中断——说起来,玩这个还真费了我不少劲,不过说起来已经不错了,哈哈,那时候STM32还不会定时中断呢(当然,现在也没弄定时,但既然外部中断都会了,想来也差不多吧~~~)
所以,我们的目标先设得简单一点:
我们只要实现基本的gpio读写功能,读用来读按键,写用来点亮LED。
右键就可以点开
相关函数 的定义位置(这里说一下,所谓 定义,对函数来说,就是函数实
现,与函数声明区分,在讨论程序时,我提到
实现,大多是指的都是这个意义上的 实现,而不再是 一般说的那个 实现 的意思。)
void GPIO_Init(GPIO_TypeDef* GPIOx,
uint8_t GPIO_Pin,
GPIO_Mode_TypeDef GPIO_Mode)
没事,我们不会去看源码。
我们只要看函数接口。
一个是gpio的port口,一个是gpio的pin数,一个是gpio的配置
模式。
对单片机比较熟悉的朋友基本不用多说,这里还是简单说一下,在单片机里,
io口都是按组划分。
比如说,最常见的8位机一组8个,然后可能有4到6组。
当然也有16位机的16个一组,让我有点奇怪的是STM32是32位ARM,一组却
也只有16个。
更有甚者,比如我玩的一个32位系统,居然只有8个一组,看来这个跟位数没
必然关系。
说了这么多,我们来看看我们这个stm8l-discover开发套件上的gpio口情
况。
用不着看pdf,从开发板引出的管脚就知道。
它总共有41个io口,
共分6组,五组8个,最后一组1个,它以A~F按顺序命名。
分别是GPIOA~GPIOF.这就是我们的port
然后每组分8位,这就是我们的pin。好了,现在我们搞清楚数目上的状况
了。
我们再看第三个参数,IO口类型。
我们可以通过查看gpio.h这个头文件获取相关的信息。
看的时候不妨多看一些我们曾见到的熟面孔,这样会加快熟悉对与其相关的宏
和操作函数的了解程度。
比如说,首先我们看到的就是io口类型
typedef enum
{
GPIO_Mode_In_FL_No_IT =
(uint8_t)0x00, /*!< Input floating,
no external interrupt */
GPIO_Mode_In_PU_No_IT = (uint8_t)0x40, /*!< Input pull-up,
no external interrupt */
GPIO_Mode_In_FL_IT =
(uint8_t)0x20, /*!< Input floating,
external interrupt */
GPIO_Mode_In_PU_IT =
(uint8_t)0x60, /*!< Input pull-up,
external interrupt */
GPIO_Mode_Out_OD_Low_Fast =
(uint8_t)0xA0, /*!< Output open-drain, low level, 10MHz */
GPIO_Mode_Out_PP_Low_Fast = (uint8_t)0xE0, /*!< Output push-pull, low level, 10MHz */
GPIO_Mode_Out_OD_Low_Slow = (uint8_t)0x80, /*!< Output open-drain, low level, 2MHz */
GPIO_Mode_Out_PP_Low_Slow = (uint8_t)0xC0, /*!< Output push-pull, low level, 2MHz */
GPIO_Mode_Out_OD_HiZ_Fast = (uint8_t)0xB0, /*!< Output
open-drain, high-impedance level, 10MHz */
GPIO_Mode_Out_PP_High_Fast = (uint8_t)0xF0, /*!< Output push-pull,
high level, 10MHz
*/
GPIO_Mode_Out_OD_HiZ_Slow = (uint8_t)0x90, /*!< Output open-drain,
high-impedance level, 2MHz */
GPIO_Mode_Out_PP_High_Slow = (uint8_t)0xD0 /*!< Output push-pull,
high level, 2MHz
*/
}GPIO_Mode_TypeDef;
这是个结构体,如果你熟悉,光看名字就猜到了,如果你不熟悉,看看英文注
释也差不多了,当然,假如你对电路的了解不深,那可能不知其所然。
而对我来说,尽管我了解这些都是什么玩意,但是对于部分模式,我并不了解
它的作用和意义。
于是我另外花了一些时间,去找这方面的的信息看,最后找到一份 周立功 的文档,感觉相当不错,比起那些坑爹的强太多了——说的都是废话。基本就是把STC那种乱七八糟的pdf里的内容半通不通地翻译成中文而已。没
有任何解释。
具体的文档可以上百度搜索,我记得我是请朋友帮我在百度文库里下的,刚找
了找,没找着,下次看看补上链接什么的。
下面是简单总结:
基本输入电路
基本IO输入电路
施密特触发输入电路
弱上拉输入电路
基本IO输入,三态缓冲器,只在 读取 时,外部状态会反映到内部总线上,其
余时刻不影响内部电路。
读取时,CPU发出一个外部选通信号
施密特输入电路
对外部输入脉冲进行整形,它可以去除某种程度的抖动。
带外部弱上拉的输入电路
弱上拉的好处是对外部干扰信号有较好的抵抗能力,但输入阻抗显著降低。
而悬空态的输入电路,对于干扰信号抵抗能力较差。
至于输出,实际上只有两种:
1 开漏输出
2 内部上拉输出。
对这两个我简单解释一下,开漏和开集电极
是 很接近的。
这里的漏
说的是 场效应管的 漏极,它在功能上类似于三极管的 集电极。
英文称之为 open drain 和 open collection,也就是别人总是神侃的OD门和
OC门。
它就是少了一个
上拉电阻,我个人认为它的最大意义有两个:
1 第一,它不怕外部IO短路,可以起相当的保护作用。
2 它适合不同电平之间的匹配,比如常见的5V系统和3.3V系统。
但它的缺陷却是,输出的电平是不定的。也就是 高不一定能高到电源电压,低不能低到地的零电平。
而外部上拉,它则可以保证输出永远是稳定的高或者低电平,但是,很显然它
遇到IO短路,会有烧毁IO口的危险。
关于这一部分,其实我并没说的很明白,这其中的内容,咱们有需要再多找资
料看吧,嘿嘿,我懂的也就这么多了。
我们这里普普通通,只用
外部上拉输入 和 外部上拉输入输出。
接着看一下这个不是很长的头文件。
typedef enum
{
GPIO_Pin_0 =
((uint8_t)0x01), /*!< Pin 0 selected
*/
GPIO_Pin_1 =
((uint8_t)0x02), /*!< Pin 1 selected
*/
GPIO_Pin_2 =
((uint8_t)0x04), /*!< Pin 2 selected
*/
GPIO_Pin_3 =
((uint8_t)0x08), /*!< Pin 3 selected
*/
GPIO_Pin_4 =
((uint8_t)0x10), /*!< Pin 4 selected
*/
GPIO_Pin_5 =
((uint8_t)0x20), /*!< Pin 5 selected
*/
GPIO_Pin_6 =
((uint8_t)0x40), /*!< Pin 6 selected
*/
GPIO_Pin_7 =
((uint8_t)0x80), /*!< Pin 7 selected
*/
GPIO_Pin_LNib = ((uint8_t)0x0F), /*!< Low nibble pins selected */
GPIO_Pin_HNib = ((uint8_t)0xF0), /*!< High nibble pins selected */
GPIO_Pin_All =
((uint8_t)0xFF) /*!< All pins
selected */
}GPIO_Pin_TypeDef;
首先是这个
结构体,注意观察,从0到7很有规律的是十六进制的 01到80,显然这是位
操作模式。
进一步可以在下面三个体现到,高四位和低四位,还有全八位操作,这是为了
提供方面,高四和低四,有点类似51里的SWAP互换高低四位的指令。
Src中,则只有一个gpio.c
当然了,它们的全名是 stm8l115_gpio.c和 stm8l115x_gpio.h
现在,来写我们的主函数。
我们在Project下建立一个main.c源文件,内容很简单,如下:
复制内容到剪贴板
1. #include \
2.
3. #include \
4.
5. //#include \
6.
7. //#include \
8. 9.
10. 11. 12.
13. #define BUTTON_GPIO_PORT GPIOC
14.
15. #define USER_GPIO_PIN GPIO_Pin_1
16. 17. 18.
19. #define LD4_GPIO_PORT GPIOC
20.
21. #define LD4 GPIO_Pin_7
22. 23. 24.
25. int main( void )
26. 27. { 28.
29. GPIO_Init( BUTTON_GPIO_PORT, USER_GPIO_PIN, GPIO_Mode_In_FL_IT);
30. 31. 32.
33. //EXTI_SetPortSensitivity(EXTI_Port_B, EXTI_Trigger_Falling);
34. 35. 36.
37. //EXTI_SetPinSensitivity(EXTI_Pin_0, EXTI_Trigger_Falling);
38. 39. 40.
41. //enableInterrupts();
42. 43. 44. 45. while(1)
46. 47. { 48. 49. 50.
51. if (GPIO_ReadInputDataBit(BUTTON_GPIO_PORT, USER_GPIO_PIN) )
52.
53. GPIO_Init(LD4_GPIO_PORT,LD4, GPIO_Mode_Out_PP_High_Fast);
54. 55. else 56.
57. GPIO_Init(LD4_GPIO_PORT, LD4, GPIO_Mode_Out_PP_Low_Fast);
58. 59. 60. 61. } 62. 63.
这段代码本来是已经做到用gpio口的外部中断了,所以有一些被我注释掉的内
容,你可以直接去掉。
我们这个代码实现的功能就是,按着按键时,灯是灭的,松开手时,灯是亮
的。
具体理解,如同我前面介绍一样,一句话,查看我所调用的函数的函数声明。
你只需要理解它的接口和返回值即可。
对了,差点忘了两件很重要的事。
1 指定 头文件搜索的相对路径 --- 这对我来说,曾经是非常蛋疼的一件事,
现在其实说白了很简单的事情,让我一下就捅破它吧。
我们的编译器在包含头文件时,需要给它指定一个路径,才能准确在特定位置
找到我们要的头文件。
指定路径有两种方式:
1 绝对路径
2 相对路径
绝对路径就是死的,它就是我们在文件夹的地址栏里看到的这个东西:
C:\\Documents and Settings\\Administrator\\桌面\\STM8资料\\stm8l-gpio2\\Project
它的缺陷是,假设下次你把这个项目文件移到另一个位置,比如说D:\\下,那它就全傻了,届时你会看到一堆的警告和错误,实在颇为状况和…..让人心惊
胆战。
所以,一般推荐相对路径。
相对路径以项目文件中的工作环境文件.eew为起点,依次寻找搜寻对应的文件夹,由此,不管我们把文件夹移到哪去,都可以正确找到我们放在里面的头文
件。
无论是相对路径还是绝对路径都在一个地方设置。
右键点击 WorkPlace 里那个灰蓝色
实体,选择 Option。
选择 C/C++ Compiler下的 Preprocessor选项卡
因为
把头文件包含进代码里,这一步正是
预编译阶段,所以要设置的是
预编译器
其中
$PROJ_DIR$\\正是我们前面说的 .eew项目环境文件。
正在阅读:
STM8 - GPIO入门文件认识11-10
2t燃气锅炉成本分析03-02
建筑工程制图与CAD-简答题10-13
管理感悟:心态篇08-06
北师大版数学六年级下册《二正比例和反比例》练习题-推荐12-02
我国区域间居民收入差距分析05-17
HP咨询为某医药公司物流改造项目规划方案09-02
最新长江段VTS及注意事项09-21
光伏太阳能电池用电子浆料行业概况和发展09-14
2009浙江省市政造价员模拟试题最终版05-08
- exercise2
- 铅锌矿详查地质设计 - 图文
- 厨余垃圾、餐厨垃圾堆肥系统设计方案
- 陈明珠开题报告
- 化工原理精选例题
- 政府形象宣传册营销案例
- 小学一至三年级语文阅读专项练习题
- 2014.民诉 期末考试 复习题
- 巅峰智业 - 做好顶层设计对建设城市的重要意义
- (三起)冀教版三年级英语上册Unit4 Lesson24练习题及答案
- 2017年实心轮胎现状及发展趋势分析(目录)
- 基于GIS的农用地定级技术研究定稿
- 2017-2022年中国医疗保健市场调查与市场前景预测报告(目录) - 图文
- 作业
- OFDM技术仿真(MATLAB代码) - 图文
- Android工程师笔试题及答案
- 生命密码联合密码
- 空间地上权若干法律问题探究
- 江苏学业水平测试《机械基础》模拟试题
- 选课走班实施方案
- 入门
- 认识
- 文件
- STM8
- GPIO
- 塞SE四声组词
- 浅谈广告语言中的修辞魅力
- 公司法论文
- 有限元大作业
- 西方对通货膨胀的研究现状
- 中粮集团的全产业链案例研究 - 图文
- 昆明玉器城景观设计说明-明昊设计
- 2011年国考行测笔试试卷 第一部分 常识判断
- 装配基础知识讲座(10.23)
- 民航常用无线电导航设备 - 图文
- 急救护理学讲义第1、2、3、4章讲义
- 海洋科学导论期末复习整理
- 西经复习题
- 中国急性期缺血性脑卒中诊治指南2014
- 2016烟花爆竹经营单位主要负责人和安全管理人员机考题库(774判断题部分)PART 1
- 2018年高考英语真题与模拟类编:专题05-阅读理解(含答案)
- 太平江一级水电站AGC试验方案
- 10kV户外柱上负荷开关预防性试验作业指导书
- 我国失业保险制度存在的问题及对策建议
- 出师表习题