本科时候学过基础的51,现在打算学习STM32。感觉正点原子的资料和开发板还不错。本人的总结全部来自正点原子的资料和视频。
有过开发51开片机经验的同学都知道,点亮一个led灯,从硬件上确定是和哪个管脚相连,从软件上我们网对应位写0就可以了。我们采用库函数的方法,库函数就是把需要的函数封装到一起,我们只需要设定相应的参数和调用需要的库函数,这种方法大大减少了工作量。
假定:我们的两个led等是和芯片的PB5和PE5相连。
我们先确定驱动一个led灯的步骤:
1.使能IO时钟。
调用的函数是RCC_APB2PeriphClockCmd();
注意:不同的IO组调用的调用的时钟使能函数不一样。
使能的函数:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB| RCC_APB2Periph_GPIOE, ENABLE); //使能 GPIOB,GPIOE 端口时钟
或者我们也可以分开写成两个语句:
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); //使能 GPIOB端口时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE); //使能 GPIOE端口时钟
2.初始化IO 参数。
第一步:给函数参数赋值,并且调用GPIO_Init();
通过"Go To Definition Of xxx "(go to 方法)确定函数原型:
void GPIO_Init (GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
我们也可看到被调用的函数有两个参数,第一个参数似乎是确定哪个IO口,第二个暂时看不出来,我们用go to方法定位到gpio的头文件中:
typedef struct
{
uint16_t GPIO_Pin; //哪个管脚
GPIOSpeed_TypeDef GPIO_Speed; //传输的速度
GPIOMode_TypeDef GPIO_Mode; //gpio模式的选择
}GPIO_InitTypeDef;
如果学过C的话,就能理解,想要调用函数 GPIO_Init() ; 必须给参数复制,所以我们需要给结构图参数赋值后传递给调用的函数。
所以,我们先定义实参 :GPIO_InitTypeDef InitTypeStructure;
然后给结构体中的元素赋值(go to 方法)
InitTypeStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置推挽输出
InitTypeStructure.GPIO_Pin = GPIO_Pin_5; //gpio端口是pin5
InitTypeStructure.GPIO_Speed = GPIO_Speed_50MHz; //Speed是50MHz参数赋值完成以后,我们就调用函数 GPIO_Init (GPIOB, &GPIO_InitStruct);
当我看到这里的时候,我有个疑惑, GPIOx、GPIO_InitStruct都是指针参数,为什么第一个实参不加取地址符号,第二个得加&?
我们把GPIOB通过“go to 方法”定位。
#define GPIOB ((GPIO_TypeDef *) GPIOB_BASE);
#define GPIOB_BASE (APB2PERIPH_BASE + 0x0C00);
GPIOB本来就是一个地址。所以就不用“&”。
第二步:设置对应的位为高电平
使能时钟并且初始化IO端口以后,我们就能对端口进行操作了。一般我们先让led不亮,我们就设置为高电平。
我们调用函数: void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
容易判断第一个参数GPIO的端口,第二个参数是端口对应的管脚。
函数是: GPIO_SetBits(GPIOB,GPIO_Pin_5);
同样的方法我们可以初始化GPIOE、调用 GPIO_Init (GPIOE, &GPIO_InitStruct); 以及设置PE5是高电平。
3.操作 IO。
在主函数中调用第二步写的程序,并且调用 void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);使端口清零。
函数是:GPIO_ResetBits(GPIOB,GPIO_Pin_5);