简单分析:红色框主要是输出电路(O),蓝色框主要是输入电路(I);关于输出电路,可以通过写位设置/清除寄存器来改变输出数据寄存器,或者直接读写输出数据寄存器,有这两种方式,继而通过I/O端口输出。如果打开了复用功能,就走复用的通道,输出控制就是一个锁存器。若寄存器写入1,输出控制的上方输出1,则CMOS管P-MOS导通,CMOS管N-MOS不导通,输出高电平,若寄存器写入0,输出低电平。关于输入电路,I/O进来有两个保护二极管,防止电压过高,再进入,有两个电阻,上拉和下拉,当不拉时为浮空输入,一般用于模拟输入,经过施密特触发器,如果用作GPIO口,将值写入寄存器,如果用作复用,走复用通道。
GPIO功能描述 端口配置表+输出模式位
开漏输出就是P-MOS上方不接
推挽输出就是两个CMOS都正常
如图所示,涉及到四个位来决定输入输出
端口配置低寄存器 CRL 端口配置高寄存器 CRH
0-7一个八组,控制8个GPIO, 8-15另外八组,控制另外8个GPIO,GPIOX的 x的取值范围为(A-E)
端口输入数据低寄存器 IDR 端口输出数据高寄存器 ODR
输入、输出数据寄存器都只用到1位(一个端口16个引脚),只需要16位,所以高16位保留
端口位设置/复位寄存器 BSRR 端口位复位寄存器 BRR 端口配置锁定寄存器 LCKR
设置I/O口的引脚,输出电平。
int main(void)
{
// GPIOA->CRL = 0x00; //CRL 代表低八个引脚(0-7)
// GPIOA->CRH = 0xffffffff; //CRH 代表高八个引脚(8-15)
/*1.设置GPIOA组的引脚的工作模式;应该是输出模式,输出模式应该是通用GPIO(非复用),假设使用的是GPIOA.0、GPIOA.1
这两个引脚应该设置为推挽输出(查看端口位配置表<表11>:CNF1设为0、CNF0设为0)、速度50Mhz(查看端口位配置表<表11>:
MODE1、MODE0设为1),继续查看 端口配置低寄存器(GPIOx_CRL),一共32位(0-31),0-3控制GPIOA的第一个引脚,
4-7控制GPIOB的第二个引脚,0-3内是MODE0、MODE1、CNF0、CNF1,需要设置对应位已达到推挽输出与速度的要求。
*/
GPIOA->CRL = 0x33; //CRL是端口配置寄存器
//2.在相应的引脚输出一个电平
GPIOA->ODR = 0x0; //00 设置这两个引脚输出两个低电平
GPIOA->ODR = 0x3; //11 设置这两个引脚输出两个高电平
return(1);
}
通过改变GPIOA的第8位,使第0位状态跟着改变
int main(void)
{
// 1、PA.0输出、50Mhz PA.8输入(PA.0用到CRL, PA.8用到CRH)
GPIOA->CRL = 0x03; //PA.0输出、50Mhz
GPIOA->CRH = 0x04; //PA.8输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
// 2、PA.0 == PA.8
while(1)
{
//第8位输入影响第0位输出
if((GPIOA->IDR & 0x0100) == 0x0100) //若成立,则第八位为1 (IDR 输入数据寄存器)
GPIOA->ODR = 0x01; //则相应第0位也置为1 (ODR 输入数据寄存器)
else
GPIOA->ODR = 0x00;
}
return(1);
}
GPIOA.8 ~ GPIOA.15 引脚输入状态影响GPIOA.0 ~ GPIOA.7 引脚输出状态
方案一
int main(void)
{
// 1、PA.0 ~ PA.7 输出、50Mhz PA.8 ~ PA.15 输入(PA.0用到CRL, PA.8用到CRH)
GPIOA->CRL = 0x33333333; //PA.0 ~ PA.7 输出、50Mhz
GPIOA->CRL = 0x44444444; //PA.8 ~ PA.15 输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
// 2、PA.8 ~ PA.15 引脚输入状态影响PA.0 ~ PA.7 引脚输出状态
while(1)
{
//则第八位为1 (IDR 输入数据寄存器),则相应第0位也置为1 (BSRR为 端口位设置寄存器,BRR位复位寄存器)
if((GPIOA->IDR & 0x0100) == 0x0100) GPIOA->ODR = GPIOA->ODR | 0x01;
else GPIOA->ODR = GPIOA->ODR & (~0x01);
if((GPIOA->IDR & 0x0200) == 0x0200) GPIOA->ODR = GPIOA->ODR | 0x02;
else GPIOA->ODR = GPIOA->ODR & (~0x02);
if((GPIOA->IDR & 0x0400) == 0x0400) GPIOA->ODR = GPIOA->ODR | 0x04;
else GPIOA->ODR = GPIOA->ODR & (~0x04);
if((GPIOA->IDR & 0x0800) == 0x0800) GPIOA->ODR = GPIOA->ODR | 0x08;
else GPIOA->ODR = GPIOA->ODR & (~0x08);
if((GPIOA->IDR & 0x1000) == 0x1000) GPIOA->ODR = GPIOA->ODR | 0x10;
else GPIOA->ODR = GPIOA->ODR & (~0x10);
//………………以此类推
}
return(1);
}
方案二
int main(void)
{
// 1、PA.0 ~ PA.7 输出、50Mhz PA.8 ~ PA.15 输入(PA.0用到CRL, PA.8用到CRH)
GPIOA->CRL = 0x33333333; //PA.0 ~ PA.7 输出、50Mhz
GPIOA->CRL = 0x44444444; //PA.8 ~ PA.15 输入(选择浮空输入,因为模拟输入与复用输入不经过输入数据寄存器)
// 2、PA.8 ~ PA.15 引脚输入状态影响PA.0 ~ PA.7 引脚输出状态
while(1)
{
//则第八位为1 (IDR 输入数据寄存器),则相应第0位也置为1 (BSRR为 端口位设置寄存器,BRR位复位寄存器)
if((GPIOA->IDR & 0x0100) == 0x0100) GPIOA->BSRR = 0x01; //第0位置1;
else GPIOA->BRR = 0x01; //第0位清零
if((GPIOA->IDR & 0x0200) == 0x0200) GPIOA->BSRR = 0x02;
else GPIOA->BRR = 0x02;
if((GPIOA->IDR & 0x0400) == 0x0400) GPIOA->BSRR = 0x04;
else GPIOA->BRR = 0x04;
if((GPIOA->IDR & 0x0800) == 0x0800) GPIOA->BSRR = 0x08;
else GPIOA->BRR = 0x08;
//………………以此类推
}
return(1);
}
//若使程序简便,可使用#define GPIOA1 GPIOA->BSRR #define GPIOA0 GPIOA->BRR
上一篇:STM32-(04):STM32F103VCT6芯片内部资源分析
下一篇:STM32-(06):位绑定的基础应用
推荐阅读最新更新时间:2024-11-13 11:20
设计资源 培训 开发板 精华推荐
- ADR550B 5V 输出高精度并联模式电压基准的典型应用
- 使用 Microchip Technology 的 U644B-FP 的参考设计
- 具有可调软启动功能的 LT1767EMS8-5 降压转换器的典型应用电路
- 具有 PWM 调光功能的 NSI45025T1G 350mA LED 灯串的典型应用
- and8008/D:采用三相一马力电机的固态控制解决方案应用电路
- LT3091IFE 简单电缆压降补偿的典型应用
- 51电子琴
- LT3091HR 浮动 3 端子稳压器的典型应用,适用于任意高压应用
- 用于 HDD/DVD 刻录机的 1.2V DC 到 DC 单路输出电源
- LT1764ET-2.5 3.3 VIN 至 2.5 VOUT LDO 稳压器的典型应用