第十五届蓝桥杯备赛-嵌入式类-0:整体概述

学习前言

嵌入式学习的基础就是STM32开发板各个模块的熟练使用,已经对应功能的实现

HAL库由于Cubemx的开发带来了巨大便利,所以熟练掌握该开发软件的使用很重要,其实也就是对时钟的配置以及各个引脚的功能实现

另外多读代码提供编程能力必不可少

整体开发板的所有应用及组合如图:

第一个程序cubemx的使用

①cubemx中选择芯片型号

②使能必要IO口【晶振与下载接口】:RCC_OSC_IN and RCC_OSC_OUT(External crystal oscillator)、SWDIO and SWCLK(CMSIS DAP Link)

③配置时钟Clock Configuration【重要】:外部时钟设置为24MHz,第一个选择器选择HSI即内部RC振荡器(没用HSE是因为引脚与LED冲突),PLLM为2分频,PLL内部先乘20再除以2,最终得80MHz,第二个选择器选择PLLCLK,后APB1和APB2总线时钟均设置为80MHz(此设置根据官方学习程序配置)

④在Project Manager中,确定工程名称、位置、IDE,勾选为每个外设初始化生成c和h文件。GENERATE CODE生成工程

/*****细节注意

⑤在keil中,打开Options for Target(魔术棒),Output勾选Create HEX File,Debug菜单右上角选择CMSIS-DAP Debugger,进入Setting,Port选择SW,Max Clock选择10MHz,如果插上开发板(注意板子有两个接口,插上DOWNLOAD接口),在SW Device中可以看到芯片IDCODE和Name,进入Flash Download选择Erase Full Chip,Reset and Run,然后下方Add添加Flash编程算法,选择STM32G4X,128K,确定保存

***/

LED模块-

创建新工程,使能PD2(信号锁存引脚,点亮灯的操作需要先对灯操作,然后依次拉高、拉低PD2引脚)拉低,使能PC8-PC15对应LED1-LED8,低电平亮,高电平灭

代码-【对GPIO高低电平的设置,只需使用WritePin(GPIOX,GPIO_PIN_x,GPIO_PIN_STATION)函数来直接操作对应端口】:
HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET);

HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET); //拉高PD2,将PC信号送入输入端

HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);//拉低PD2,锁存输出端信号

HAL_Delay(1000);

注:操作LED时需要设置全部的LED状态,因为对LCD操作也会影响LED状态

按键和定时器中断模块

传统按键检测有两种方式,一种直接读IO电平状态,另一种是中断,这两种方式都处理按键抖动都有些许误差,因此使用定时器来计数判断按键是否按下

创建新工程,使用timer1,时钟源选择 内部时钟【Internal Clock】,分频系数选择80,意味着一个tick是1us,计数值设为9999,则定时器中断周期为10ms,在NVIC Settings中使能更新中断

代码中需要在主循环上方手动启动定时器中断:HAL_TIM_Base_Start_IT(&htim1);

在timer.c文件最后加上回调函数:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{

        if (htim == (&htim1))

        {

                static uint8_t keycount = 0;  //按键计数

                if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)

                {

                    keycount ++;

                 }else keycount = 0;

                if(keycount == 8)

                {   //这个值根据情况设定,if内为key按下执行的内容

                  HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_8);

                  HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);

          HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);                                        

                     keycount = 0;   //计数清零

                 a++;

                }        

       }         

}

// 长、短按

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

        if (htim == (&htim1))

        {

        static int keycount = 0,key2count = 0;  //按键计数  keycount是判断有按键按下,                                                                                                            key2count是判断长或短按

           if(keycount >= 8)

          {   //这个值根据情况设定  消抖                                                  

                 key2count++;

                 if(key2count>=100)

                { //长按

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_RESET);

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_SET);

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_SET);

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET);

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET);

                 HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);                        

                 HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);

HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);                                                                       }

                 else if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_SET)

                {  //短按                 

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_8, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_9, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_10, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_11, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_12, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_14, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOC, GPIO_PIN_15, GPIO_PIN_SET);                        

                       HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);

                       HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);   

               }

       }

   if(HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0) == GPIO_PIN_RESET)

   {

       keycount ++;

    }else {

            keycount = 0;key2count=0;     

             }        

   }         

}

/*****这里对回调函数做个补充,该函数是最常用于我们编程逻辑的实现*******/

回调函数是一种编程技术,可以在事件发生时执行预定义的代码。在STM32中,回调函数通常是在硬件发生特定事件时调用的,例如定时器中断、串口接收中断、外部中断等。回调函数的作用是可以在事件发生时执行一些需要及时响应的操作,例如读取传感器数据、处理接收到的数据、控制外设等。

回调函数的使用通常是通过HAL库实现的,HAL库提供了一些预定义的回调函数和函数指针,可以方便地在需要时进行调用。在使用HAL库时,通常需要先进行相关的初始化和配置,然后注册相应的回调函数。当事件发生时,HAL库会自动调用相应的回调函数进行处理。

例如,当使用定时器时,需要先初始化定时器、设置时钟源和预分频等参数,然后注册一个回调函数用于处理定时器中断事件。当定时器中断事件发生时,HAL库会自动调用该回调函数执行预定义的代码。在回调函数中可以进行各种操作,例如修改输出状态、读取传感器数据等。

回调函数的使用可以提高程序的响应速度和实时性,特别是在实时控制和数据采集应用中,回调函数经常被使用。需要注意的是,回调函数需要占用一定的资源和时间,因此在设计时需要合理选择回调函数的数量和复杂度,以避免影响程序的性能。

一种最简单的方法可以说直接读取IO电平状态判断按键是否按下:

if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){

        HAL_Delay(100);

        if(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){

                HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_14 | GPIO_PIN_15);

                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_SET);

                HAL_GPIO_WritePin(GPIOD, GPIO_PIN_2, GPIO_PIN_RESET);

        }

}

  • 11
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值