stm32之GPIO

来源:互联网 发布:乡村爱情 知乎 编辑:程序博客网 时间:2024/05/16 12:03

GPIO (general port input output ) 即通用端口输入输出。 是我们学习单片接触的第一个外设。想想当初我们点亮第一个流水灯时的欣喜,就像学习C语言的时候写出Hello world 是的惊喜感觉自己会编程了,接触了一个多么伟大的学科。 嘿嘿,上硬菜。
我手上的开发板是野火的MINI板,功能够用,型号是 STM32F103VE 144P个引脚,STM32有多种封装相应的同一种型号也有多种不同的引脚。

STM32 GPIO 有四种输入四种输出。
{
1. 浮空输入
2. 上拉输入
3. 下拉输入
4. 模拟输入
5. 推挽输出
6. 开漏输出
7. 推挽式复用功能
8. 开漏复用
}
首先我们回顾 数电中学过的, 二进制是0和1 0表示低电平,TTL电平中(0~5V) 0~2V表示0,3~5V表示1 ,2~3V为不确定状态,
一个IO 可以有三种状态
*{
高阻态
高电平
低电平
}*
浮空输入: 就是这个引脚的状态不确定,有三种状态,一把这种模式用来传输数据。
上拉输入: 就是在浮空上接一个电阻和电压(具体看是TTL还是其他)。一般时上拉输入为1
下拉输入: 就是在浮空上接一个电阻和地,一般下拉输入为0 .
模拟输入: 我的认识是 输入模拟信号,一般作为ADC的输入。
四种输出没有具体查资料。先留在这。
到现在基本对STM32的GPIO有了个基本认识。现在让我们认识认识他的寄存器

{
GPIOX__CRL (configuration register low 低位配置寄存器) : 配置:引脚是输出还是输出,输出频率多大。
GPIOX__CRH(C R HIGH 高位位置寄存器)
GPIOX__IDR(input data r 输入数据寄存器)
GPIOX__ODR(output data register 输出数据寄存器)
GPIOX__BSRR(bit set reset register 设置清除寄存器)
GPIOX__BRR(bit reset register 清除寄存器)
GPIOX__LCKR(port lock configuration register 端口配置锁定寄存器 )
}
位设置清除寄存器: 如果寄存器中同时设置了 置位和清除, 则以置位起作用。
现在我们来看具体代码的实现。
例: 点亮一个LED,硬件接口: PC3。
代码如下(下面是MAIN文件里面的函数):

int main(void){    led_init();  while(1)   {    stateChange( ENABLE);      delay();      stateChange(DISABLE);    delay();     }}void delay(){    int i,j,k;   for(i=50;i>0;i--)    for(j=50;j>0;j--)       for(k=130;k>0;k--);}

看下led_init()函数里面的具体代码

void led_init(){   GPIO_InitTypeDef   GPIOCI;  //GPIO_Init(GPIO_TypeDef * GPIOx,GPIO_InitTypeDef * GPIO_InitStruct)   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);   GPIOCI.GPIO_Mode=GPIO_Mode_Out_PP;   GPIOCI.GPIO_Speed=GPIO_Speed_50MHz;   GPIOCI.GPIO_Pin=GPIO_Pin_3;   GPIO_Init(GPIOC,&GPIOCI);}

GPIO_InitTypeDef GPIOCI; 定义名为GPIOCI的GPIO_InitTypeDef型的变量,看看GPIO_InitTypeDef的来源

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;

可以看出,这个是一个结构体类型。
这里涉及到了Typedef这个关键字,关于语言方面的知识,我随后开个专门的博文写这些东西。
GPIO_InitTypeDef 这是一个类型就行了。
在led_init();开始首先定义了一个GPIO_InitTypeDef型的变量用来存储要配置引脚的信息。 然后打开了GPIOC相应得时钟,不懂得朋友可以看我 写的STM32时钟分析
用过 RCC->APB2ENR 设置相应的外设。

之后是往GPIO_InitTypeDef里面传值,
***GPIOCI.GPIO_Mode=GPIO_Mode_Out_PP; // 设置模式为 推挽输出
GPIOCI.GPIO_Speed=GPIO_Speed_50MHz;// 速度为50MHZ
GPIOCI.GPIO_Pin=GPIO_Pin_3;// 引脚3 .*
然后下面这个函数把值传入相应的寄存器。
GPIO_Init(GPIOC,&GPIOCI);
这个函数实际上就是干了一件如下这么的事:
GPIOC->CRL =0x0000 3000;
可是为什么我们不直接这样去写呢,看起来多简单,反而要使用一个代码比较多的函数,等我们以后分析完GPIO_Init();这个函数后就会知道,那个函数写的有多么的美妙,这也是库开发的美妙。
继续,
程序进入一个while(1)死循环。
通过置GPIO__Pin_3 为1 .为0循环,就可以实现LED的一亮一灭。
GPIOx->BSRR = GPIO_Pin; // 置1
GPIOx->BRR = GPIO_Pin; //清零。

好了,完成了这些我们基本就可实现LED的亮灭循环。

由于我们写的只是一个简单的例子,我们使用了死循环,这太浪费资源,开发中最好不要做这样事情,这里只是为了演示方便。

0 0
原创粉丝点击