1 STM32中IO口的原理及使用方法
(1) GPIO的数量 :在stm32中GPIO口有ABCDEFG七组,每一组有16个管脚0~15。
(2)GPIO口的表示方法:PXX--P--PORT X--端口号 X--管脚号,如PA0--A端口中的第0个管脚。
(3)GPIO口电平与数字量之间的关系:0--0v±0.1v; 1--3.3v±0.3v。
(4)模式:输入/输出
输入 : 输入浮空--输入的是数字量(不具有上下拉功能),
输入上拉--输入的是数字量(具有上拉功能)
输入下拉--输入的是数字量(具有下拉功能)
模拟输入 --输入的是模拟量 (ADC)
输出:通用/复用
通用:GPIO口功能有开漏(只输出0)和推挽(输出0或1)两种输出方式
复用:除了GPIO口功能
(5)速率:设置引脚的响应速度
2 对stm32进行配置的方法
(1)寄存器地址映射
(2)寄存器(具有大小的存储区域)
寄存器的查看:数据手册中查看寄存器的名称及意义,位数和复位值,权限和功能
GPIO 端口模式寄存器 (GPIOx_MODER) (x = A..I) GPIO port mode register
偏移地址:0x00
复位值:
● 0xA800 0000(端口 A)
● 0x0000 0280(端口 B)
● 0x0000 0000(其它端口)
位 2y:2y+1 MODERy[1:0]:端口 x 配置位 (Port x configuration bits) (y = 0..15)
这些位通过软件写入,用于配置 I/O 方向模式。
00:输入(复位状态)
01:通用输出模式
10:复用功能模式
11:模拟模式
GPIO 端口输出类型寄存器 (GPIOx_OTYPER) (x = A..I) GPIO port output type register
偏移地址:0x04
复位值:0x0000 0000
位 31:16 保留,必须保持复位值。
位 15:0 OTy[1:0]:端口 x 配置位 (Port x configuration bits) (y = 0..15)
这些位通过软件写入,用于配置 I/O 端口的输出类型。
0:输出推挽(复位状态)
1:输出开漏
GPIO 端口输出速度寄存器 (GPIOx_OSPEEDR) (x = A..I/) GPIO port output speed register
偏移地址:0x08
复位值:
● 0x0000 00C0(端口 B)
● 0x0000 0000(其它端口)
位 2y:2y+1 OSPEEDRy[1:0]:端口 x 配置位 (Port x configuration bits) (y = 0..15)
这些位通过软件写入,用于配置 I/O 输出速度。
00:2 MHz(低速)
01:25 MHz(中速)
10:50 MHz(快速)
11:30 pF 时为 100 MHz(高速)(15 pF 时为 80 MHz 输出(最大速度))
GPIO 端口上拉/ 下拉寄存器 (GPIOx_PUPDR) (x = A..I/) GPIO port pull-up/pull-down register
偏移地址:0x0C
复位值:
● 0x6400 0000(端口 A)
● 0x0000 0100(端口 B)
● 0x0000 0000(其它端口)
位 2y:2y+1 PUPDRy[1:0]:端口 x 配置位 (Port x configuration bits) (y = 0..15)
这些位通过软件写入,用于配置 I/O 上拉或下拉。
00:无上拉或下拉
01:上拉
10:下拉
11:保留
GPIO 端口输入数据寄存器 (GPIOx_IDR) (x = A..I) GPIO port input data register
偏移地址:0x10
复位值:0x0000 XXXX(其中 X 表示未定义)
位 31:16 保留,必须保持复位值。
位 15:0 IDRy[15:0]:端口输入数据 (Port input data) (y = 0..15)
这些位为只读形式,只能在字模式下访问。它们包含相应 I/O 端口的输入值。
GPIO 端口输出数据寄存器 (GPIOx_ODR) (x = A..I) GPIO port output data register
偏移地址:0x14
复位值:0x0000 0000
位 31:16 保留,必须保持复位值。
位 15:0 ODRy[15:0]:端口输出数据 (Port output data) (y = 0..15)
这些位可通过软件读取和写入。
注意:对于原子置位/ 复位,通过写入 GPIOx_BSRR 寄存器,可分别对 ODR 位进行置位和复位 (x = A..I/)。
3 led流水灯
/*-------------------------------------------------------------------------------
*------------------------共阳极led流水灯-----------------------------------------
*控制GPIO口进行操作LED1-LED3分别与PF6 PF9 PF10, LED4与PC0相连
*1、控制IO口时应先给相应端口时钟,时钟选着有两种:
* 0:禁止 1:使能
*2、再配置端口的模式,配置时应先复位再选着相应模式,端口模式有四种:
* 00:输入(复位状态) 01:通用输出模式 10:服用功能模式 11:模拟模式
*3、再进行输出类型的选择,有两种:
* 0:输出推挽 1:输入开漏
*4、再进行输出速度选择,四种:
* 00:2MHZ 01:25MHZ 10:50MHZ 11:100MHZ/80MHZ
*5、再进行输出数据的写入
*---------------------------------------------------------------------------*/
/* Includes ------------------------------------------------------------------*/
#include "main.h"
void delay_ms(uint32_t ms)
{
uint64_t Time = ms * 16800;
while(Time--);
}
void Led_Init(void)
{
//给PC和PF时钟
RCC->AHB1ENR |= (9<<2);
//端口模式
GPIOC->MODER &=~ (3<<0);
GPIOC->MODER |= (1<<0);
GPIOF->MODER &=~ (0x3c3<<12);
GPIOF->MODER |= (0x141<<12);
//输出类型
GPIOC->OTYPER &=~ (1<<0);
GPIOF->OTYPER &=~ (0x19<<6);
//输出速度
GPIOC->OSPEEDR |= (1<<0);
GPIOF->OSPEEDR |= (0x3c3);
//上下拉
GPIOC->PUPDR |= (1<<0);
GPIOF->PUPDR |= (0x19<<6);
}
void Led_Light(uint32_t i,uint32_t j)//j判断是开还是关,i判断是第几个灯
{
if(j)
{
switch(i)
{
case 1:GPIOF->ODR &=~ (1<<6);break;
case 2:GPIOF->ODR &=~ (1<<9);break;
case 3:GPIOF->ODR &=~ (1<<10);break;
case 4:GPIOC->ODR &=~ (1<<0);break;
}
}
else
{
switch(i)
{
case 1:GPIOF->ODR |= (1<<6);break;
case 2:GPIOF->ODR |= (1<<9);break;
case 3:GPIOF->ODR |= (1<<10);break;
case 4:GPIOC->ODR |= (1<<0);break;
}
}
}
int main(void)
{
uint32_t i;
Led_Init();
while (1)
{
for(i=1;i<5;i++)
{
Led_Light(i,1);
delay_ms(500);
}
for(i=4;i>=1;i--)
{
Led_Light(i,0);
delay_ms(500);
}
}
}
如有错误,还请指出,谢谢。