欢迎光临散文网 会员登陆 & 注册

菜喵のSTM32F4学习笔记(0)

2020-08-22 22:23 作者:竹之武  | 我要投稿

    

    (讲道理第一篇似乎应该来个开场白,不过那不重要,就不要了)


    这篇文章几乎没有怎么润色,大约保留了自己学习过程中的原始笔记和debug记录,部分内容甚至很基础,bug出的也很没水平,大家笑一笑就好2333。

    注1:本次笔记中使用STM32F407ZGT6,利用STM32库函数进行开发;

    注2:个人笔记,记录的是零散的知识,不对涉及到的背景知识进行的铺开介绍(换句话说这不是一个成体系的可以视作学习用的教材的笔记~);

    注3:啥时候B站专栏有代码块和公式啊qwq。


    2020-8-22自学笔记(PS:基础不牢,地动山摇,嵌入式的深入理解还是补一补好,所以之前的试验,再来一遍(笑))

试验1:按键输入试验

debug1:

    昨天的bug,我定义了LED的初始化函数,但是在主程序里没有调用,可喜可贺,愚蠢至极。

    这么蠢的bug是没有任何描述的。


debug2:

    今天打算写一个按键控制RGB灯的试验,定义了如下的按键扫描函数(PS:这部分参照了正点原子的按键输入试验代码,略作小改动):

int KeyScan(int mode);  //具体的内容我写在最后了。    

    返回值为1、2、4(分别对应于KEY1按下、KEY2按下、KEY1与KEY2同时按下的情况)还有0(KEY1、KEY2都不按下)。

    为了不像正点原子那样写一串的switch判断,同时为了试一试位运算,主程序的while(1)里我是这样写的:

  

 LED点亮函数如下:


   注意这里的mode,之前我写的是:

if(mode == 1)

    但是除了红灯LED_R以外,main函数中余下的与运算得到的是2、4;除非进行移位操作,不然没有效果,所以吧==1去掉了。

#ps:将主函数中的while内容改成如下代码即可继续用if(mode == 1),虽然没必要吧:

debug3:

 原始代码:

    返回值1、2、4分别对应了RGB三个颜色的灯,但是在观察的时候发现,按下KEY2后,绿色只闪烁了一下之后就灭了(理论上应该如此,因为主函数的延迟时间很短,只有10ms),而其他的灯却可以常亮(事实上我没有开启这个功能)

    回看代码发现标红的部分存在比较大的问题。

    等于的运算判断是要比或运算优先级高的,所以先判断了KEY2 是否为零,如果是按下当然要返回一个0,KEY1这时候不按下,为0。两者取与,为0 ,不会执行key_up = 1这条语句。

而对于余下的两个返回值1、4,由于都有KEY1的按下,本行中1与KEY== 0 的结果与运算,一定为1 ,故而出现了长按的bug。(你这编程都咋学的?这也能忘?)

Code:

    这里是以上debug对应的最后修改程序,实现了按下按键灯亮一秒,长按无效的操作。

不过因为判断时间是1s,所以不是每次按下都会有反应(PS:所以大家轻易不要用轮询2333,中断函数和RTOS任务他不香吗(笑);当然,测试程序自己知道咋回事的时候,轮询挺好的,嗯)。

main.c文件:(再次小吐槽一下B站专栏没有代码块的事r(笑))


#include "stm32f4xx.h"

#include "usart.h"

#include "delay.h"


#define KEY_1 GPIO_Pin_0

#define KEY_2 GPIO_Pin_1

#define KEY1 GPIO_ReadInputDataBit(GPIOD,KEY_1)

#define KEY2 GPIO_ReadInputDataBit(GPIOD,KEY_2)


void InitLED()

{

  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1|GPIO_Pin_0;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

}


void InitKey()

{

  GPIO_InitTypeDef  GPIO_InitStructure;

  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);

    

  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4;

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;

  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;

  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

}


void LED_R(int mode)

{

    if(mode)

        GPIO_ResetBits(GPIOD,GPIO_Pin_2);

    else

        GPIO_SetBits(GPIOD,GPIO_Pin_2);

}


void LED_G(int mode)

{

    if(mode)

        GPIO_ResetBits(GPIOD,GPIO_Pin_3);

    else

        GPIO_SetBits(GPIOD,GPIO_Pin_3);

}


void LED_B(int mode)

{

    if(mode)

        GPIO_ResetBits(GPIOD,GPIO_Pin_4);

    else

        GPIO_SetBits(GPIOD,GPIO_Pin_4);

    

}


int KeyScan(int mode)

{

    static int key_up;

    if(mode)key_up =1;

    if(key_up&&(KEY1==1||KEY2==1))

    {

        delay_ms(10);

        key_up = 0;

        if(KEY1 == 1 && KEY2 != 1)return 1;

        else if (KEY1 != 1 && KEY2 == 1)return 2;

        else if (KEY1 == 1 && KEY2 == 1)return 4;

    }

    else if((KEY1||KEY2) == 0) key_up = 1;

    return 0;

}


int main(void)

{

    u32 flag=0;

    uart_init(115200);

    delay_init(168);

    InitLED();

    InitKey();

  while(1){

    flag = KeyScan(0);

    LED_R(flag & 0x01);

    LED_G(flag & 0x02);

    LED_B(flag & 0x04);

    delay_ms(1000);

    printf("%d\n",flag);

  }

}

试验2:按键输入试验(改)

这部分在每个LED_X(int mode)函数中定义了静态变量用于保存当前灯状态,代码如下:

除了加粗的地方以外,LED_G() 和 LED_B()余下的部分与红色LED相同。


//关于状态取反的微操:

state = -(state - 1);  //0、1两个状态的切换

或者这样(取反):state = ~state;

    当然你也可以写在state的if else语句当中,不过大括号会让你的代码变长。篇幅太长的话个人感觉不是很好看。

    附一张接线图:从上到下就是KEY1和KEY2,输入用的是3.3V的电平。

为了方便,GPIO用的是GPIOD的0-4五个端口,Pin0 Pin1作为输入,Pin2~4为R、G、B的输入,低电平有效(我用的RGBLED是共阳的)

    关于GPIO的操作笔记大概就这么多,这篇不涉及关于复用的内容,对于GPIO中的各种寄存器、地址等内容也没有涉及(换句话说,最需要深入了解的内容我没放到这个笔记当中,记在纸上了,懒得搬(笑))

    emmm,如果有空我也整理一下好了,毕竟这些才是嵌入式的浪漫(?),不然能用Arduino解决的事情干满要麻烦STM32呢(咕)


菜喵のSTM32F4学习笔记(0)的评论 (共 条)

分享到微博请遵守国家法律