赞
踩
根据接线图接线,这里采用低电平的接线方式
速通新建工程
还要新建一个System,存放系统资源
1.Start启动文件
找到固件库文件,打开启动文件 放在start的文件夹下
这三个文件同样复制到start文件夹下
2. Library文件夹
找到标准外设驱动文件夹
3.Project文件夹
main.c直接复制过来,就不用新建文件了
到此为止,工程文件的复制就完成了
4.System文件夹
5.工程组里的文件添加
把默认组删掉,再新建三个组还有一个System
6.工程选项配置
6.main函数
加上头文件,写上主函数
- #include "stm32f10x.h" // Device header
-
- int main(void)
- {
- while(1)
- {
-
- }
- }
-
到这里工程就搭建完毕了
*小工具
双击一下keilkill
点亮LED
操作STM32的GPIO需要三个步骤:1.使用RCC打开GPIO的时钟;2.使用GPIO_Init函数初始化GPIO;3.使用输出或输入函数来控制GPIO口
这里涉及了GPIO和RCC两个外设,可以看看这两个外设有哪些库函数
RCC库函数
RCC最常用的库函数有三个
右键点击函数名,跳转到函数定义
GPIO库函数
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
*调用这个函数,所指定的GPIO就会被复位
void GPIO_AFIODeInit(void);
*可以复位AFIO外设
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
*用结构体的参数来初始化GPIO端口,需定义一个结构体变量,然后再给GPIO赋值,最后再调用这个函数,这个函数就会自动读取结构体的值,自动把外设各个参数配好
*这种Init函数几乎在所有外设中都有,一般初始化外设都是使用Init函数来完成的
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
*把结构体变量默认的赋一个值
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
*以上四个是GPIO的读取函数
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
*以上四个是GPIO的写入函数
*这些函数可以实现读取GPIO口的功能
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
这样时钟就开启了
第一个参数根据跳转的定义填写为GPIOA一个小细节,
GPIO_InitTypeDef GPIO_Initstructure;这个结构体是一个局部变量
GPIO_Mode_AIN = 0x0,
*AIN(Analog IN)模拟输入
GPIO_Mode_IN_FLOATING = 0x04,
*IN_FLOATING是浮空输入
GPIO_Mode_IPD = 0x28,
*IPD(In Pull Down)是下拉输入
GPIO_Mode_IPU = 0x48,
*IPU(In Pull Up)是上拉输入
GPIO_Mode_Out_OD = 0x14,
*Out_OD(Out Open Drain)是开漏输出
GPIO_Mode_Out_PP = 0x10,
*Out_PP(Out Push Pull)是推挽输出
GPIO_Mode_AF_OD = 0x1C,
*AF_OD(Atl Open Drain)是复用开漏
GPIO_Mode_AF_PP = 0x18
*AF_PP(Atl Push Pull)是复用推挽
点灯使用的是推挽输出,所以复制GPIO_Mode_Out_PP
然后再配置GPIO_Initstructure.GPIO_Pin,同样跳转定义
第三个GPIO_Initstructure.GPIO_Speed是一样的套路,选择GPIO_Speed_50MHz
内部的主要执行逻辑是,读取结构体参数,执行一堆判断和运算,然后再写入GPIO配置寄存器
- GPIO_InitTypeDef GPIO_Initstructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
- GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Initstructure.GPIO_Pin = GPIO_Pin_12;
- GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
-
- GPIO_Init(GPIOB, &GPIO_Initstructure);
这样GPIO的初始化已经完成了,这样就可以使用GPIO的输入输出函数了
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
*这个函数可以把指定端口设置为高电平
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
*把指定端口设置为低电平
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
*第三个参数BitVal,这个是根据第三个参数的值来设置指定的端口的
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
*这个函数可以同时对16个端口执行写入操作
首先来使用一下void GPIO_ResetBits,看一下函数的定义
于是可以写为
GPIO_ResetBits(GPIOA, GPIO_Pin_0);
同样可得
GPIO_SetBits(GPIOA, GPIO_Pin_0);
接下来使用一下void GPIO_WriteBit
GPIO_WriteBit(GPIOA,GPIO_Pin0, Bit_RESET);
置低电平,灯点亮
GPIO_WriteBit(GPIOA,GPIO_Pin0, Bit_SET);
置高电平,灯熄灭
LED闪烁
为了实现闪烁功能,在逻辑上应该是在循环里,点亮LED,延时一段时间,熄灭LED,延时一段时间
把加入延时函数程序模板放在前面新建工程里了
- #include "stm32f10x.h" // Device header
- #include "delay.h"
-
- int main(void)
- {
- GPIO_InitTypeDef GPIO_Initstructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
- GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Initstructure.GPIO_Pin = GPIO_Pin_0;
- GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_Initstructure);
-
- while(1)
- {
- GPIO_SetBits(GPIOA, GPIO_Pin_0);
- Delay_ms(500);
- GPIO_ResetBits(GPIOA, GPIO_Pin_0);
- Delay_ms(500);
-
- GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_RESET);
- Delay_ms(500);
- GPIO_WriteBit(GPIOA, GPIO_Pin_0, Bit_SET);
- Delay_ms(500);
-
- GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)0);//强制类型转换就可以实现不用填入指定的参数,写0和1即可
- Delay_ms(500);
- GPIO_WriteBit(GPIOA, GPIO_Pin_0, (BitAction)1);
- Delay_ms(500);
- }
- }
-
这里讨论一下推挽输出和开漏输出驱动问题
把LED的正负极对换,这样LED是高电平点亮方式,这样可以看到,LED依旧是正常闪烁的,说明在推挽模式下,高低电平都是有驱动能力的
把端口模式换为GPIO_Mode_Out_OD,开漏输出模式,LED不亮了,现在LED还是高电平点亮方式,LED不亮,说明开漏输出没有高电平驱动能力,再调换LED正负极,可以看到LED正常闪烁,说明开漏模式下低电平是有驱动能力的
这就映证了上节推挽输出和开漏输出的特性,推挽输出高低电平均有驱动能力,开漏输出高电平相当于高阻态,没有驱动能力,低电平有驱动能力
一般输出用推挽输出就行了,开漏输出在特殊情况下使用
LED流水灯
为什么可以这样操作?将各位转化为二进制是0000000000000001、0000000000000010、0000000000000100,这里每一个端口对应着一个位,按位或的操作就相当于0000000000000111
GPIO_Write看第二个参数的定义
- #include "stm32f10x.h" // Device header
- #include "delay.h"
-
- int main(void)
- {
- GPIO_InitTypeDef GPIO_Initstructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
-
- GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
- //GPIO_Initstructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2; 按或取
- GPIO_Initstructure.GPIO_Pin = GPIO_Pin_All;
- GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_Initstructure);
-
- while(1)
- {
- //Q1:一开始是没有按位取反~,然后导致小灯常亮
- //Q2:看弹幕说可以用for循环减轻工作量
- GPIO_Write(GPIOA, ~0x0001); //0000 0000 0000 0001
- Delay_ms(500);
- GPIO_Write(GPIOA, ~0x0002); //0000 0000 0000 0010
- Delay_ms(500);
- GPIO_Write(GPIOA, ~0x0004); //0000 0000 0000 0100
- Delay_ms(500);
- GPIO_Write(GPIOA, ~0x0008); //0000 0000 0000 1000
- Delay_ms(500);
- GPIO_Write(GPIOA, ~0x0010); //0000 0000 0001 0000
- Delay_ms(500);
- GPIO_Write(GPIOA, ~0x0020); //0000 0000 0010 0000
- Delay_ms(500);
- GPIO_Write(GPIOA, ~0x0040); //0000 0000 0100 0000
- Delay_ms(500);
- GPIO_Write(GPIOA, ~0x0080); //0000 0000 1000 0000
- Delay_ms(500);
- }
- }
-
蜂鸣器
- #include "stm32f10x.h" // Device header
- #include "delay.h"
-
- int main(void)
- {
- GPIO_InitTypeDef GPIO_Initstructure;
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
-
- GPIO_Initstructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_Initstructure.GPIO_Pin = GPIO_Pin_12;
- GPIO_Initstructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_Initstructure);
-
- while(1)
- {
- GPIO_SetBits(GPIOB, GPIO_Pin_12);
- Delay_ms(100);
- GPIO_ResetBits(GPIOB, GPIO_Pin_12);
- Delay_ms(100);
- GPIO_SetBits(GPIOB, GPIO_Pin_12);
- Delay_ms(100);
- GPIO_ResetBits(GPIOB, GPIO_Pin_12);
- Delay_ms(700);
-
- }
- }
-
库函数的使用方法
*我打不开这个参考文档
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。