【第一章 GPIO及寄存器详解 】

系列文章目录

第一章 GPIO及寄存器详解



前言

嵌入式期末复习


一、STM32F103ZET6芯片资源解读

内核:
32位 高性能ARM Cortex-M3处理器
时钟:高达72M,实际还可以超频一点点
单周期乘法和硬件除法
IO口:
144个引脚,112个IO口
大部分IO口都耐5V(模拟通道除外)
支持调试:SWD和JTAG,SWD只要2根数据线
存储器容量:
512K FLASH,64K SRAM
时钟,复位和电源管理:
2.0~3.6V电源和IO电压
上电复位,掉电复位和可编程的电压监控
强大的时钟系统
4~16M的外部高速晶振
内部8MHz的高速RC振荡器
内部40KHz低速RC振荡器,看门狗时钟
内部锁相环(PLL,倍频),一般系统时钟都是外部或者内部高速时钟经过PLL倍频后得到
外部低速32.768K的晶振,主要做RTC时钟源
低功耗:
睡眠,停止和待机三种低功耗模式
可用电池为RTC和备份寄存器供电
AD:
3个12位AD【多达21个外部测量通道】
转换范围:0~3.6(电源电压)
内部通道可以用于内部温度测量
内置参考电压
DA:
2个12位DA
DMA:
12个DMA通道(7+5=12; 7通道DMA1,5通道DMA2)
支持外设:定时器,ADC,DAC,SDIO,I2S,SPI,I2C,和USART
定时器,多达11个定时器:
4个通用定时器
2个基本定时器
2个高级定时器
1个系统定时器
2个看门狗定时器
通信接口,13个通信接口:
2个I2C接口
5个串口
3个SPI接口
1个CAN2.0
1个USB FS
1个SDIO

二、8种模式

1.输入

1,输入浮空
2,输入上拉
3,输入下拉
4,模拟输入

2.输出

1,开漏输出
2,推挽输出
3,推挽式复用功能
4,开漏式复用功能

3.stm32的IO口位配置表

在这里插入图片描述

输出模式配置表

在这里插入图片描述

三、3种速度

1,最大输出速度10MHz
2,最大输出速度2MHz
3,最大输出速度50MHz

四、每个IO端口有七个寄存器控制

1,CRL
2,CRH
配置模式的2 个 32 位的端口配置寄存器 CRL 和 CRH,控制着每个IO口的模式及输出速率

3,IDR
4,ODR
2 个 32 位的数据寄存器 IDR 和 ODR

5,BSRR
1 个 32 位的置位/复位寄存器BSRR

6,BRR
一个 16 位的复位寄存器 BRR

7,LCKR
1 个 32 位的锁存寄存器 LCKR

五、寄存器详细配置

1.CRL(配置低八位)

(1).模式配置图

在这里插入图片描述

(2).寄存器配置速记

0:模拟输入
4:浮空输入
8:上拉/下拉输入
C:保留
输入

1:推挽输出,速度10MHz
5:开漏输出,速度10MHz
9:复用功能推挽输出,速度10MHz
D:复用功能开漏输出,速度10MHz
速度10MHz 输出

2:推挽输出,速度2MHz
6:开漏输出,速度2MHz
A:复用功能推挽输出,速度2MHz
E:复用功能开漏输出,速度2MHz
速度2MHz 输出

3:推挽输出,速度50MHz
7:开漏输出,速度50MHz
B:复用功能推挽输出,速度50MHz
F:复用功能开漏输出,速度50MHz
速度50MHz 输出

2.CRH(配置高八位)

和CRL完全一样,只不过只是 CRL 控制的是低8 位输出口,而 CRH 控制的是高 8位输出口

3.IDR(端口输入数据寄存器,只读)

在这里插入图片描述
要想知道某个 IO 口的状态,你只要读这个寄存器,再看某个位的状态就可以了。

可以用来读取按键事件的发生,这里若PA0按下IDR的值为1。
在这里插入图片描述

int main()
{
	Stm32_Clock_Init(9);
	LED_Init();
	RCC->APB2ENR|=1<<2;
	GPIOA->CRL&=0xfffffff0;
	GPIOA->CRL|=0x00000008;
	while(1)
	{
		if(GPIOA->IDR==1)
		{
			Delay_ms(20);
			LED0=!LED0;
			Delay_ms(20);
		}
	}
}

也可以用来判断某些开关的状态,这里用来判断key0和key2是否连通。
在这里插入图片描述

int main()
{
	Stm32_Clock_Init(9);
	LED_Init();
	RCC->APB2ENR|=1<<2;
	GPIOA->CRL&=0xfffffff0;
	GPIOA->CRL|=0x00000008;
	while(1)
	{
		if(GPIOA->IDR==5)
		{
			LED0=!LED0;
			Delay_ms(70);
		}
	}
}

4.ODR(端口输出数据寄存器,可读可写)

在这里插入图片描述
该寄存器为可读写,从该寄存器读出来的数据可以用于判断当前 IO 口的输出状态。而向该寄存器写数据,则可以控制某个 IO 口的输出电平。

ODR的读取和IDR的读取是有很大的区别的
ODR可读的意义在于:你在编程的时候,如果你需要通过该端口的当前电平来判断你的下一步操作,你就需要把它的电平放入if-else的判断语句或者switch块中。这时,虽然它的电平完全是由你的上一步操作决定,但如果我们可以直接从底层硬件中读回,那会给编程带来很大方便。
IDR寄存器的值是从输入端口的电平采样得到的(个人理解),直接反映芯片外部的情况。ODR的值反映的是你对输出端口电平的配置。两者完全不同
感谢知乎罗华昱的解答

int main()
{
	Stm32_Clock_Init(9);
	LED_Init();
	RCC->APB2ENR|=1<<2;
	GPIOA->CRL&=0xfffffff0;
	GPIOA->CRL|=0x00000008;
	GPIOA->ODR|=1<<2;
	while(1)
	{		
		if(GPIOA->ODR==4)
		{
			LED0=!LED0;
			Delay_ms(70);
		}
	}
}

ODR寄存器写入数据

int main()
{
	Stm32_Clock_Init(9);
	RCC->APB2ENR|=1<<3;
	GPIOB->CRL&=0xff00ffff;
	GPIOB->CRL|=0x00330000;
	while(1)
	{
		GPIOB->ODR=1<<5;
		Delay_ms(60);
		GPIOB->ODR=0<<5;
		Delay_ms(60);
	}
}

5.BSRR(端口位设置/清除寄存器)

在这里插入图片描述
在ODR里面提到过,BSRR可以分别地对各个ODR位进行独立的设置/清除

这怎么理解呢,就是字面意思
(1)ODR设置位值时是影响其他的位,ODR使用时先读取其状态才能设置其值。
(2)BSRR寄存器设置位值的时候,不会影响到其他的位的输出或输入。
为什么要这样呢
(1)用BSRR和BRR去改变管脚状态的时候,没有被中断打断的风险。也就不需要关闭中断。
(2)关闭中断明显会延迟或丢失一事件的捕获,所以控制GPIO的状态最好还是用SBRR和BRR。

int main()
{
	Stm32_Clock_Init(9);
	RCC->APB2ENR|=1<<3;
	GPIOB->CRL&=0xff00ffff;
	GPIOB->CRL|=0x00330000;
	GPIOB->ODR=1<<4;
	while(1)
	{
		Delay_ms(300);
		GPIOB->ODR=1<<5;
		Delay_ms(60);
		GPIOB->ODR=0<<5;
		Delay_ms(60);
		Delay_ms(300);
	}
}

在这里插入图片描述
可以看出在初始状态时D2是处于熄灭的状态,D1是点亮的状态,就是说此时ODR=00010000
而进入while(1)循环之后,虽然只修改了ODR的第五位,但是第四位还是一起被改变了。

怎么解决呢

int main()
{
	Stm32_Clock_Init(9);
	RCC->APB2ENR|=1<<3;
	GPIOB->CRL&=0xff00ffff;
	GPIOB->CRL|=0x00330000;
	GPIOB->ODR=1<<4;
	while(1)
	{
		Delay_ms(200);
		GPIOB->BSRR=1<<5;
		Delay_ms(60);
		GPIOB->BSRR=1<<(5+16);
		Delay_ms(60);
	}
}

在这里插入图片描述
这里用BSRR寄存器进行设置,可以独立的修改位电平,这样D2就不受影响了。

6.BRR(端口位清除寄存器)

在这里插入图片描述
在这里插入图片描述
BRR只能将ODR的位清除,清除功能和BSRR差不多

int main()
{
	Stm32_Clock_Init(9);
	RCC->APB2ENR|=1<<3;
	GPIOB->CRL&=0xff00ffff;
	GPIOB->CRL|=0x00330000;
	GPIOB->ODR=1<<4;
	while(1)
	{
		Delay_ms(200);
		GPIOB->BSRR=1<<5;
		Delay_ms(60);
		GPIOB->BRR=1<<5;
		Delay_ms(60);
	}
}

7.LCKR(端口配置锁定寄存器)

在这里插入图片描述
当执行正确的写序列设置了位16(LCKK)时,该寄存器用来锁定端口位的配置。位[15:0]用于锁定GPIO端口的配置。在规定的写入操作期间,不能改变LCKP[15:0]。当对相应的端口位执行了LOCK序列后,在下次系统复位之前将不能再更改端口位的配置。
每个锁定位锁定控制寄存器(CRL, CRH)中相应的4个位。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值