STM32自学周记(二)

STM32自学周记(二)

接着上一周的学习,开始寄存器控制跑马灯程序的编写。
(1)调用函数RCC_APB2PeriphColckCmd();控制使能IO口是时钟在这里插入图片描述
(上图是STM32mini版的原理图,上一周学习的是STM32 M4,和mini版的IO口有很多区别,所有重新附图。)
如图可知LED0对应IO口为PD2,LED1所对IO口为PA8。在中文参考手册找出RCC_APB2的介绍,找到这两个IO口对应的位数。在这里插入图片描述

RCC->APB2ENR|=1<<5; 

在这里插入图片描述

RCC->APB2ENR|=1<<2;

这里用到了C语言的位或运算“|=”,类似于C++中的“+=”。这里的意思是RCC->APB2ENR=它本身的位数或RCC->APB2ENR=1。然后将1左移5位,如图

在这里插入图片描述
当1左移5位后来到了 5 的位置,此时无论第五位为何值,与1做或运算结果都为1,此IO就是开启状态,初始化成功。PA8同理。
(2)对GPIO_Init初始化
CRL控制0~7位
CRH控制8~15位

在这里插入图片描述
CRL寄存器每个IO口由四位控制,所以PD2对应位置如图中画圈处。LED的配置模式和库函数中相同,分别是推完输出和50HZ,对应的编码为0011,换算成16进制为3。再赋值进行初始化前要将对应位置清零,就用到了“与运算”,它的特点是在16进制中,与运算乘以F不改变值,所以将他的第三位清零

 GPIOD->CRL&=0xFFFFF0FF;

再运用或运算对第三位进行赋值

 GPIOD->CRL|=0x00000300;

ODR寄存器的每个IO口由一位控制,它不需要清零,直接用或运算将其初始化为高电平

 GPIOD->ODR|=1<<2;

PA8的初始化原理同上。
(3)操作IO口,输出高低电平
在主函数通过while循环和延时函数实现小灯的闪烁,其中会用到C语言的非运算:
~(111011)=000100
具体如下

 while(1)
 {
  
  GPIOD->ODR|=1<<2;
  GPIOA->ODR|=1<<8;
  delay_ms(500);
  
  GPIOD->ODR|=~(1<<2);  
  GPIOA->ODR|=~(1<<8);
  delay_ms(500);  
 
 }

随后学习了用位带操作编写跑马灯的程序。
相比于之前的两种方法,位带操作大大简化了主函数中输出高低电平的代码数量,只需要调用对ODR寄存器的宏定义,便可实现高低电平的初始化。
在这里插入图片描述若想把PD2设置为高电平,只需要打出“PDout(2)=1”即可。通过位带操作的函数如下

  while(1)
  {
   
   PAout(8)=1; 
   Dout(2)=1; 
   
   delay_ms(500);
   
   PAout(8)=0; 
   PDout(2)=0; 
   
   delay_ms(500);   
  
  }

学习了三种跑马灯的编译方法,趁热打铁,把理论运用到实践上,学习了mini板的第一个实验——按键实验
与跑马灯相比,按键实验需要再初始化一个与按键IO口连接有关的函数。如图
在这里插入图片描述
WK UP对应PA0 KEY0对应PC5 KEY1对应PA15 低电平为按下 高电平为松开
宏定义以上三个按键

#define KEY0  GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_5)
#define KEY1  GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_15)
#define WK_UP   GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)

#define KEY0_PRES 1  
#define KEY1_PRES 2  
#define WKUP_PRES 3  

之后编写按键IO初始化函数按键扫描函数
按键初始化和LED的初始化编译方法类似,也是通过“右键→go to definition”选择参数的范围,完成初始化。
按键扫描函数用到了 static 关键字,由于第一周对常用C语言的学习,这一部分的理解没有费太大力气。
u8 KEY_Scan(u8 mode)
{
static u8 key_up=1; //表示key未按下
if(mode==1) key_up=1; //支持连续按
if(key_up && (KEY0 == 0||KEY1 == 0||WK_UP == 1)) //如果此刻按键没有按下之后执行了或运算中的某一个操作,开始扫描
{
delay_ms(10); //延时,防抖
key_up=0; //标记这次key已经按下
if(KEY0 == 0) return KEY0_PRES;
else if(KEY1 == 0) return KEY1_PRES;
else if(WK_UP == 1) return WKUP_PRES;
}
else if(KEY0 == 1&&KEY1 == 1&&WK_UP == 0) key_up=1;
return 0; //无按键按下
}

主函数运用了switch语句,使每次按键LED灯都能改变状态(按一次亮,再按一次灭)

switch(t)
  {     
   case KEY0_PRES:
    LED0=!LED0;
    break;
   case KEY1_PRES:
    LED1=!LED1;
    break;
   case WKUP_PRES:    
    LED0=!LED0;
    LED1=!LED1;
    break;
   default:
    delay_ms(10); 
  } 

以上就是本周的学习内容,对STM32程序的编写有了大致的逻辑:
在这里插入图片描述

欢迎大家在博客下留言讨论,指明错误,共同进步!

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值