图9.端口配置低寄存器的比特位//对应端口的配置涉及到4位,后两位配置端口输入输出速度,前两位配置工作模式;清零端口2的配置位
GPIOB->CRL &= ~(0xf << 8u);
//速度配置位为0,端口为输入模式,上拉输入的工作模式位为10,因此使用0x08.
GPIOB->CRL |= (0x08 << 8u);
//配置PB2引脚为高电平
GPIOB->BSRR |= (1u << 2u);
LED初始化
实验使用PB3、PB4,引脚,为观察LED的高低电平,在配置工作模式时使用可以输出高低电平的推挽输出。因为PB3与PB4对应端口在端口0~7中,所以使用GPIOx_CRL寄存器对LED进行初始化配置(若使用端口为8~15则使用GPIOx_CRH寄存器)。
如图9所示,端口3为GPIOx_CRL寄存器内第12~15位,端口4为GPIOx_CRL寄存器内第16~19位。由于LED为低电平点亮,设置GPIOx_BSRR寄存器中LED2与LED3的对应位置1使LED初始状态为灭。//复位将要使用的端口3与端口4的配置位
GPIOB->CRL &= ~( (0xf << 12u) | (0xf << 16u) );
//端口输入输出速度配置位不为00时,端口为输出模式,配置最大速度为50MHz,推挽输出模式的配置为00.
GPIOB->CRL |= ( (0x01 << 12u) | (0x01 << 16u) );
//PB3对应的LED2初始化状态为灭
GPIOB->BSRR = (1u << 3u);
//PB4对应的LED3初始化状态为灭
GPIOB->BSRR = (1u << 4u);
按键扫描
读GPIOx_IDR寄存器获取对应端口输入数据,本实验中K2配置为上拉输入,即按键未按下时为高电平,按下按键后,K2对应端口输入为低电平。若GPIOx_BSRR寄存器的低16位的对应端口位置1,则该端口为高电平;若GPIOx_BRR寄存器的对应端口位置1,则该端口为低电平。实验设置按键未按下时,LED2(PB3)亮、LED3(PB4)灭;按下按键时LED2灭、LED3亮。while(1)
{
//K2的引脚为PB2, 1u<<2u = 0100u,将PB2的对应位置1,若读出GPIOx_IDR的对应端口数据为高电平则按键未按下
IF ( 0u != ( GPIOB->IDR & (1u << 2u) ) )
{
//PB4引脚对应的LED3灭
GPIOB->BSRR = (1u << 4u);
//PB3引脚对应的LED2亮
GPIOB->BRR = (1u << 3u);
}
else //K2 按键按下
{
//PB4引脚对应的LED3亮
GPIOB->BRR =(1u << 4u);
//PB3引脚对应的LED2灭
GPIOB->BSRR = (1u << 3u);
}
}
Main()函数
综合上述寄存器配置到main函数中,图10为实验效果。int main(void)
{
//GPIOB时钟初始化
RCC->AHB1ENR |= (1u << 18u);
//清零端口2的配置位
GPIOB->CRL &= ~(0xfu << 8u);
//端口2配置为上拉输入
GPIOB->CRL |= (0x08u << 8u);
//端口2配置为高电平
GPIOB->BSRR |= (1u << 2u);
//端口3与端口4配置位清零
GPIOB->CRL &= ~( (0xf << 12u) | (0xf << 16u) );
//端口3与端口4配置为推挽输出,速度最大为50MHz
GPIOB->CRL |= ( (0x01 << 12u) | (0x01 << 16u) );
//PB3对应的LED2初始化状态为灭
GPIOB->BSRR = (1u << 3u);
//PB4对应的LED3初始化状态为灭
GPIOB->BSRR = (1u << 4u);
while(1)
{
//K2的引脚为PB2, 1u << 2u = 0100u,将PB2的对应位置1,若读出GPIOx_IDR的对应端口数据为高电平则按键未按下
if ( 0u != ( GPIOB->IDR & (1u << 2u) ) )
{
// PB4引脚对应的LED3灭
GPIOB->BSRR = (1u << 4u);
//PB3引脚对应的LED2亮
GPIOB->BRR = (1u << 3u);
}
else //按下按键K2
{
// PB4引脚对应的LED3亮
GPIOB->BRR = (1u << 4u);
// PB3引脚对应的LED2灭
GPIOB->BSRR = (1u << 3u);
}
}
}