之前的草稿
一个人终究要为他偷的懒负责的,水过来了课程,但是你有什么提升了。一拖再拖,拖了好几个学期,还是回来补个STM32基础入门吧,永远都在入门不实操的我真的对自己无语了。
串口通信的代码:
注意GPIOA的时钟线是AHB1不是APB1,不要打错了
void uart_init(u32 bound)
{
GPIO_InitTypeDef GPIO_InitStructure;
USART_InitTypeDef USART_InitStructure;
NVIC_InitTypeDef NVIC_InitStructure;
//GPIOA 和 USART1 时钟使能①
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE); //使能 GPIOA 时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE);//使能 USART1 时钟
//USART_DeInit(USART1); //复位串口 1 ②
GPIO_PinAFConfig(GPIOA,GPIO_PinSource9,GPIO_AF_USART1); //PA9 复用为 USART1
GPIO_PinAFConfig(GPIOA,GPIO_PinSource10,GPIO_AF_USART1); //PA10复用为USART1
//USART1_TX PA.9 PA.10 ③
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9 | GPIO_Pin_10; //GPIOA9 与 GPIOA10
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;//复用功能
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //速度 50MHz
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP; //推挽复用输出
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOA,&GPIO_InitStructure); //初始化 PA9,PA10
//USART 初始化设置 ④
USART_InitStructure.USART_BaudRate = bound;//一般设置为 9600;
USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为 8 位数据格式
USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
USART_InitStructure.USART_HardwareFlowControl =USART_HardwareFlowControl_None;
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; //收发模式
USART_Init(USART1, &USART_InitStructure); //初始化串口
#if EN_USART1_RX //NVIC 设置,使能中断 ⑤
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启中断
//Usart1 NVIC 配置
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;//抢占优先级 2
NVIC_InitStructure.NVIC_IRQChannelSubPriority =2; //响应优先级 2
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ 通道使能
NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化 VIC 寄存器、
#endif
}
USART_Cmd(USART1, ENABLE); //使能串口 ⑥
GPIO
相关的函数和定义分布在固件库文件
stm32f4xx_gpio.c
和头文件
stm32f4xx_gpio.h
文
件中。
在固件库开发中,操作四个配置寄存器初始化
GPIO
是通过
GPIO
初始化函数完成:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct)
这个函数有两个参数,第一个参数是用来指定需要初始化的
GPIO
对应的
GPIO
组,取值范围
为
GPIOA~GPIOK
。第二个参数为初始化参数结构体指针,结构体类型为
GPIO_InitTypeDef
。
下面我们看看这个结构体的定义。首先我们打开我们光盘的跑马灯实验,然后找到
FWLib
组下
面的
stm32f4xx_gpio.c
文件,定位到
GPIO_Init
函数体处,双击入口参数类型
GPIO_InitTypeDef
后右键选择“
Go to definition of
…”可以查看结构体的定义:
typedef struct
{uint32_t GPIO_Pin;GPIOMode_TypeDef GPIO_Mode;GPIOSpeed_TypeDef GPIO_Speed;GPIOOType_TypeDef GPIO_OType;GPIOPuPd_TypeDef GPIO_PuPd;}GPIO_InitTypeDef;
下面我们通过一个
GPIO
初始化实例来讲解这个结构体的成员变量的含义。
通过初始化结构体初始化
GPIO
的常用格式是:
GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9//GPIOF9GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;// 普通输出模式GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;//100MHzGPIO_InitStructure.GPIO_OType = GPIO_OType_PP;// 推挽输出GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;// 上拉GPIO_Init(GPIOF, &GPIO_InitStructure);// 初始化 GPIO
上面代码的意思是设置 GPIOF 的第 9 个端口为推挽输出模式,同时速度为 100M,上拉。
从上面初始化代码可以看出,结构体
GPIO_InitStructure
的第一个成员变量
GPIO_Pin
用来
设置是要初始化哪个或者哪些
IO
口,这个很好理解;第二个成员变量
GPIO_Mode
是用来设置
对应
IO
端口的输出输入端口模式,这个值实际就是配置我们前面讲解的
GPIOx
的
MODER
寄
存器的值。在
MDK
中是通过一个枚举类型定义的,我们只需要选择对应的值即可:
typedef enum{GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */}GPIOMode_TypeDef;
GPIO_Mode_IN
是用来设置为复位状态的输入,
GPIO_Mode_OUT
是通用输出模式,
GPIO_Mode_AF
是复用功能模式,
GPIO_Mode_AN
是模拟输入模式。
第三个参数
GPIO_Speed
是
IO
口输出速度设置,有四个可选值。实际上这就是配置的
GPIO
对应的
OSPEEDR
寄存器的值。在
MDK
中同样是通过枚举类型定义:
typedef enum
{GPIO_Low_Speed = 0x00, /*!< Low speed */GPIO_Medium_Speed = 0x01, /*!< Medium speed */GPIO_Fast_Speed = 0x02, /*!< Fast speed */GPIO_High_Speed = 0x03 /*!< High speed */}GPIOSpeed_TypeDef;/* Add legacy definition */#define GPIO_Speed_2MHz GPIO_Low_Speed#define GPIO_Speed_25MHz GPIO_Medium_Speed#define GPIO_Speed_50MHz GPIO_Fast_Speed#define GPIO_Speed_100MHz GPIO_High_Speed
这里需要说明一下,实际我们的输入可以是
GPIOSpeed_TypeDef
枚举类型中
GPIO_High_Speed
枚举类型值,也可以是
GPIO_Speed_100MHz
这样的值,实际上
GPIO_Speed_100MHz
就是通
过
define
宏定义标识符定义出来的,它跟
GPIO_High_Speed
是等同的。
第四个参数
GPIO_OType
是
GPIO
的输出类型设置,实际上是配置的
GPIO
的
OTYPER
寄
存器的值。在
MDK
中同样是通过枚举类型定义:
typedef enum{GPIO_OType_PP = 0x00,GPIO_OType_OD = 0x01}GPIOOType_TypeDef;
如果需要设置为输出推挽模式,那么选择值
GPIO_OType_PP
,如果需要设置为输出开漏模式,
那么设置值为
GPIO_OType_OD
。
第五个参数
GPIO_PuPd
用来设置
IO
口的上下拉,实际上就是设置
GPIO
的
PUPDR
寄存
器的值。同样通过一个枚举类型列出:
typedef enum
{GPIO_PuPd_NOPULL = 0x00,GPIO_PuPd_UP = 0x01,GPIO_PuPd_DOWN = 0x02}GPIOPuPd_TypeDef;
这三个值的意思很好理解,
GPIO_PuPd_NOPULL
为不使用上下拉,
GPIO_PuPd_UP
为上拉,
GPIO_PuPd_DOWN
为下拉。我们根据我们 需要设置相应的值即可。
/* USART Rx--浮空输入 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_InitStructure);