1. 按键亮灯
设计 GPIO 实验项目 1,功能:当按键 KB1 按下时,实验板上全彩发光二极管周边 的发光二极管全亮,当按键 KB2 按下时跑马灯 D0 闪亮。
实验要求基于寄存器的GPIO配置,所以需要手动操作寄存器来配置时钟和输入输出模式(如果不要求,在cubemx里可以直接配置)。
跑马灯和按键KB1,KB2的端口模式为推挽输出和输入,因此需要编程将它们设置为对应的模式:
参考下面的端口位配置表,
一个端口占用配置寄存器的四位来设置工作模式,可以知道CRL(0-7(低八位)的引脚对应CRL配置寄存器)里输出跑马灯和输入按键KB1,KB2的每个端口应配置为:0011(16进制0x3)和0100(16进制0x4)
那么,使用 CubeMX 创建工程,只设置芯片选型、 系统时钟、调试端口; GPIO 配置在程序中通过寄存器配置完成。
按键按下为低电平,所以检测 数据输入寄存器(GPIOx_IDR)与(&)上对应位为1的数的 结果,比如PE0就是与 0x01。
if((GPIOE->IDR&0X01)==0){flag=1;}else if((GPIOE->IDR&0X02)==0){flag=2;}
功能是 当按键 KB1 按下时,实验板上全彩发光二极管周边 的发光二极管全亮,当按键 KB2 按下时跑马灯 D0 闪亮,因为跑马灯是高电平点亮,就是数据输出寄存器 GPIOF_ODR 对应位 置为1,D0闪亮的话就是对这一位不断取反,这一位异或1其他位异或0即可。
if(flag==1){GPIOF->ODR|=0XFF;}else if(flag==2){GPIOF->ODR^=0X01;HAL_Delay(50);}
主要代码如下:
#flag设为全局变量,方便调试查看
int flag=0;
int main(void)
{HAL_Init();/* Configure the system clock */SystemClock_Config();/* Initialize all configured peripherals */MX_GPIO_Init();RCC->APB2ENR|=1<<7;//使能PORTF时钟GPIOF->CRL&=0X00000000;GPIOF->CRL|=0X33333333;//PF.0-PF.7推挽输出GPIOF->ODR=0X00;//清除显示RCC->APB2ENR|=1<<6;//使能PORTE时钟GPIOE->CRL&=0X00;GPIOE->CRL|=0X44;//PE.0-PE.1开漏输入while (1){if((GPIOE->IDR&0X01)==0){flag=1;}else if((GPIOE->IDR&0X02)==0){flag=2;}else flag=0;if(flag==1){GPIOF->ODR|=0XFF;}else if(flag==2){GPIOF->ODR^=0X01;HAL_Delay(50);}else{GPIOF->ODR=0X00;}}
}
2.顺时针方向旋转的跑马灯
实现顺时针方向旋转的跑马灯,跑马灯延时 0.2 秒。按照灯的顺序,将GPIOF_ODR 对应位 置为1。
基于寄存器:
RCC->APB2ENR|=1<<6;GPIOE->CRL&=0X00000000;GPIOE->CRL|=0X44;//while里for(int i=0;i<8;i++){GPIOF->ODR=0X01<<i;
//这里的延时不是0.2s,自行调整for(int k=0;k<100000;k++);}
HAL库:
uint16_t x=0x0001;
for(int i=0;i<8;i++){//GPIOF->ODR=0X01<<i;//for(int k=0;k<100000;k++);HAL_GPIO_WritePin(GPIOF,x<<i,1);HAL_Delay(200);HAL_GPIO_WritePin(GPIOF,x<<i,0);}
3.按键控制跑马灯方向
编写程序,当按键 KB1 按下时,跑马灯按顺时针方向旋转,按下 KB2 时,跑马灯 按逆时针方向旋转。
结合前两者代码,为了方便,逆时针用新的变量y=0x0080 右移 来选择八个灯的引脚。
RCC->APB2ENR|=1<<6;GPIOE->CRL&=0X00000000;GPIOE->CRL|=0X44;uint16_t x=0x0001;uint16_t y=0x0080;while (1){if((GPIOE->IDR&0X01)==0){flag=1;}else if((GPIOE->IDR&0X02)==0){flag=2;}else if(HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_6)==0){flag=3;}//else flag=0;if(flag==1){for(int i=0;i<8;i++){HAL_GPIO_WritePin(GPIOF,x<<i,1);HAL_Delay(200);HAL_GPIO_WritePin(GPIOF,x<<i,0);}}else if(flag==2){for(int i=0;i<8;i++){HAL_GPIO_WritePin(GPIOF,y>>i,1);HAL_Delay(200);HAL_GPIO_WritePin(GPIOF,y>>i,0);}}else if(flag==3){}else{GPIOF->ODR=0X00;}}}