stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别

本文内容基于https://www.bilibili.com/video/BV1Lx411Z7Qa

P11

GPIO工作模式:

输入模式1:浮空输入

输入模式2:输入上拉模式

输入模式3:输入下拉模式

由于浮空输入模式的电压不确定,容易误读,检测高电平时一般用输入下拉模式,检测低电平时一般用输入上拉模式。

输入模式4:模拟模式

 

输出模式1:开漏输出

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第1张图片

 

输出控制电路输出1时,N-MOS断开,实际输出由外部上拉下拉决定,输出0时,N-MOS闭合,实际输出0,实际输出可以由输入数据寄存器读取

 

输出模式2:开漏复用输出模式

与开漏输出模式区别:输出来自片上的外设模块,而不是由CPU控制。

输出模式3:推挽输出模式

P-MOS与N-MOS同时参与控制,输出控制电路直接决定实际输出

输出工作模式4:推挽复用输出模式

输出来自外设

 

GPIO端口介绍:

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第2张图片

 

BSRR寄存器可以单独设置ODR寄存器的其中一位,较为方便。由于ODR寄存器只能以字的形式操作,如果直接设置ODR寄存器则需要先读入ODR寄存器的值再改变其中的某一位。

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第3张图片stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第4张图片

 

P12

4个读取输入/输出电平函数有读取一位和读取整组的区别

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第5张图片

 

先定义结构体变量,再逐个设置参数,具体的参数名称在函数中的有效性判断里,最后使用函数初始化IO口。

 

 

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第6张图片

1.复制库函数工程模板

 

2.新建文件夹HAREWARE,子文件夹LED,并新建led.c,led.h

写头文件

 

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第7张图片

3.新建分组HAREWARE,添加led.c

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第8张图片

 

4.添加led.h

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第9张图片

 

5.编译以便查看头文件

6.初始化时钟

方法一:

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第10张图片

 

方法二:

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第11张图片

 

由于操作的是同一个寄存器中不同的位,可以用或运算写

 

7.在led.c中写初始化程序

 

GPIO_Init()这个函数在stm32f10x_gpio.h头文件的最下方

先定义结构体变量,再逐个设置参数,配置好后使用函数初始化IO口。

初始化完成后使用置位函数将IO口设为高电平,使得初始化完成时LED熄灭

 

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第12张图片

8.通过控制IO口输出控制LED灯,这里引入了延时函数

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第13张图片

 

P13

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第14张图片

 

1.创建工程

2.初始化IO口时钟

通过或运算设置寄存器,防止影响其它位

 

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第15张图片

3.模式配置为推挽输出,并配置为输出为1,使得LED熄灭

与运算清0,或运算置1,防止影响其它位

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第16张图片

 

5.写主函数

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第17张图片

 

这里应改为GPIOB->ODR&=~(1<<5); GPIOE->ODR&=~(1<<5);

否则将改变其它位。

 

P14

 

  

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第18张图片   

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第19张图片

这里通过宏定义将PAout(n)映射到ODR寄存器的特定位,具体过程为

PAout(n)

》》BIT_ADDR(GPIOA_ODR_Addr,n)

》》MEM_ADDR(BITBAND((GPIOA_ODR_Addr,n))

》》 MEM_ADDR(((GPIOA_ODR_Addr & 0xF0000000)+0x2000000+(( GPIOA_ODR_Addr &0xFFFFF)<<5)+(n<<2)))

》》*((volatile unsigned long  *)(((GPIOA_ODR_Addr & 0xF0000000)+0x2000000+(( GPIOA_ODR_Addr &0xFFFFF)<<5)+(n<<2))))

最终的映射结果表明PAout(n)即是*(指向ODR寄存器的特定位的指针),改变PAout(n)的值即是改变ODR寄存器特定位的值

注:位带操作最终是操作了ODR、IDR寄存器,所以对应的IO口也需要先初始化

 

P15

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第20张图片

 

三极管可以起到放大电流的作用。

R38电阻可以将小电流导入GND,防止浮空状态时蜂鸣器响。

 

 

P16

stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第21张图片

按键有两种,一种支持连续按,一种不支持

 stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第22张图片

通过静态局部变量key_up保存按键是否被释放的信息,再通过一个if语句决定其是否生效,达到了两种模式合二为一的效果。

P17

   stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第23张图片  

增加结构体成员不影响其它代码,可扩展性强

    stm32入门 第二周 IO口实验,了解库函数开发和寄存器开发的区别_第24张图片

GPIOA->ODR

》》((GPIO_TypeDef*)GPIOA_BASE)->ODR

这里GPIOA_BASE是一串地址常量,((GPIO_TypeDef*)GPIOA_BASE)将GPIOA_BASE强制转换为指向GPIO_TypeDef结构体变量首地址的指针变量 ,于是GPIO_TypeDef结构体变量首地址变成了GPIOA_BASE。

因为结构体中的变量按顺序存储在内存中,GPIOA系列寄存器的地址也按顺序排列在内存中,两者成一一对应的关系,所以改变结构体成员的值就是改变对应寄存器的值。

 

你可能感兴趣的:(学习笔记)