本帖最后由 wolfgang2015 于 2017-6-17 10:49 编辑 一、实验开始之前二、实验过程0、上次实验回顾 上次实验中,我们通过STM32CubeMX创建了一个Keil工程,增加了少量代码就实现了点亮LED灯的试验目的;板子能按HAL_Delay(x)函数,在x=500时,按照这个时间间隔闪亮熄灭LED灯。 回顾实验,有几个核心函数出现在试验中: 1、GPIO口操作函数,HAL_GPIO_WritePin: HAL_GPIO_WritePin(LD2_GPIO_Port,LD2_Pin,GPIO_PIN_SET) HAL_GPIO_WritePin(LD2_GPIO_Port,LD2_Pin,GPIO_PIN_RESET); 上面两个函数将GPIO口设置为高电平、低电平实现了LED的点亮、熄灭,制造了LED的闪亮。 2、GPIO口引脚的相关定义,LD2_GPIO_Port,LD2_Pin,GPIO_PIN_SET、GPIO_PIN_RESET 这几个引脚的定义在{项目名称}\Inc\ mxconstants.h 文件中,定义内容如下:
这里我们可以发现GPIOA是一个32位的寄存器,每个GPIO引脚都由这个积存器的bit来控制,而且这个寄存器的基地址由GPIOA_BASE 得来,GPIOA_BASE这个基地址是由AHB2PERIPH_BASE + 0x0000得来,AHB2PERIPH_BASE这个基地址是由 PERIPH_BASE +0x08000000得来;PERIPH_BASE这个基地址是由(uint32_t)0x40000000。 这种用基址+偏移的方法来定义常量很不错,寄存器往往有一个固定的地址,如果编译、移植,如果偏移不变,只需要更换基址即可。 GPIO_TypeDef 结构体是在{项目名称}\Drivers\CMSIS\Device\ST\STM32L4xx\Include\stm32l476xx.h
GPIO_PIN_SET、GPIO_PIN_RESET的定义在{项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal_gpio.h 文件中
定义GPIO_PIN_RESET 低电平,GPIO_PIN_SET 高电平。 3、亮与暗的时间间隔我们是用HAL_Delay(delay)函数来实现的, delay是在程序体中定义的一个变量值来定义的uint16_t delay = 500; HAL_Delay(uint32_tDelay) 是在{项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal.h 定义,在{项目名称} \Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c的函数中HAL_GetTick()-tickstart< Delay,来实现的。 HAL_GetTick是在{项目名称}\Drivers\STM32L4xx_HAL_Driver\Inc\stm32l4xx_hal.h 定义,在{项目名称} \Drivers\STM32L4xx_HAL_Driver\Src\stm32l4xx_hal.c的函数中用uwTick实现的。 查资料得到, HAL_IncTick(void) 中断函数是1ms进来一次,也就是说uwTick+1就代表1ms。 [url=]结论是:HAL_Delay(delay)是闪亮500ms、熄灭延时500ms。[/url] 1、新实验设想 当我们知道了点灯的原理之后,我就就在想,能否对试验进行改进,再增加些已有的外设,比如,用按钮B1来控制等的闪亮延时长短,当检查到GPIO连接的B1发生按键时发起延时值得改变。除了事用HAL_GetTick()之外还有那些定义的时钟函数可以使用。 使用CubeMX打开芯片引脚设置,观察B1所用的PC13 引脚设置: 设置为GPIO_EXIT13:GPIO口启用外部中断13。
GPIO 类型设置为外部中断,在上升沿触发检测。
NVIC:嵌套向量中断控制器:NestedVectored Interrupt Controller (NVIC) 在NVIC这里我们查询我们设置的中断向量:
启用GPIO[15:10]的中断。 在CubeMX设置好后,创建实验代码。 2、实验步骤 先在main.h中增加定义延时的值:
在main.c中引用main.h,并在USER CODEBEGIN 0处定义延时初始值;USER CODE BEGIN 1处初始化亮灯的值;USER CODE BEGIN 3处将循环中加入闪亮等的相关操作(继续沿用前面试验中LED亮灯的设置;USER CODE BEGIN 4 处增加按键中断的相应代码,即修改延时的值。
3、实验的观察结果 当我们把程序下载到板子中后,按下Reset按钮重起系统,这时LED闪亮,我们按下LB按钮,闪亮频率加快,大约按下6~7下后,几乎看不出闪亮了; 通过实验发现 Delay_8到Delay_0LED几乎不闪,这是为什么呢?频率太高?还是((HAL_GetTick() - tickstart) < Delay)的时代码有缺陷呢?这里通过Debug是无法跟踪到的,F5按键的频率决定了程序响应速度,我们只好通过其它方式来验证; HAL_GetTick 调试中固定值为 0x08000FD0。 看来还得引入其他方法来验证,这里暂且不表,等到后边的实验来验证。 三、实验后的心得 这个实验,可以了解STM32l4xx_hal_gpio.h/.c中 HAL_GPIO_EXTI_Callback回调函数的定义和调用。通过__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) 定义回调函数,在程序运行空间中定义具体的实现内容。 GPIO回调函数这仅是众多回调函数的一个案例,虽则对功能模块的熟悉还有机会接触到更多的[url=]系统[/url][ZL2] 回调函数。 经常看见有人问如何来避免抖动,这里用检测中断来判断按键。这种方法是比较好的一种方法,几乎不会出现按键抖动情况。而且这里使用检测GPIO的上升沿来触发中断,根据电路图上按键接的是一个下拉电阻,松开按键的瞬间引发上拉电平。检测电平上拉这时候的上升沿往往自只有一个,只要是按钮或按键没有接触不良的情况,几乎都不会出现抖动现象,若出现就是你要更换按键了,鼠标的微动开关就是出现连击情况就是这样,你要跟换鼠标微动开关/鼠标了。 到这里,刚拿到板子时的延时程序就还原了,诸位是否有收获呢?以后的实验我们需要外设了,Uart TTL电平转串口的芯片、SPI 液晶显示屏、IIC时钟模块或者IIC的Flash、做PWM实验的电机驱动模块及直流电机等等,或许还有其他我们自己制作的模块。 |
哈哈,顺便做了扫屏测试
(*^_^*)
被沐紫mm,赞了太荣幸了~~