物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14)

这篇具有很好参考价值的文章主要介绍了物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

通过外部中断实现按键捕获代码的实现及分析

1 代码的流程分析
2 代码的实现
库函数HAL_Init(void)分析:

HAL_StatusTypeDef HAL_Init(void)
{
  /* Configure Flash prefetch, Instruction cache, Data cache */
#if (INSTRUCTION_CACHE_ENABLE != 0U) //0U表示无符号整型 0 , 1U 表示无符号整型1 ~0U就是对无符号数0取反。
  __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
#endif /* INSTRUCTION_CACHE_ENABLE  允许指令缓存*/

#if (DATA_CACHE_ENABLE != 0U)
  __HAL_FLASH_DATA_CACHE_ENABLE();
#endif /* DATA_CACHE_ENABLE */

#if (PREFETCH_ENABLE != 0U)
  __HAL_FLASH_PREFETCH_BUFFER_ENABLE();
#endif /* PREFETCH_ENABLE */

  /* Set Interrupt Group Priority 中断优先级分组*/
  HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);

  /* Use systick as time base source and configure 1ms tick (default clock after Reset is HSI) */
  HAL_InitTick(TICK_INT_PRIORITY); //初始化系统时钟

  /* Init the low level hardware 初始化底层硬件(堆栈指针)*/
  HAL_MspInit();  //使用HAL_Delay延时

  /* Return function status */
  return HAL_OK;
}

Tip1:函数说明的格式

/****************
*函数名:main
*函数的描述:通过中断实现按键的捕获
*输入参教:
*输出参数:
*返回值:
*图数作者:
*创建时间:
*更改说明:
*****************/

Tip2:如何使用CMSIS的延时

HAL_Delay()系统延时的步骤:
它的实现步骤如下:
1.用变量获得系统时钟源计数器的值
2.获得要延迟时间的参数值
3.比较两者大小,若时钟计数器的值大于要实现延迟的值,就会困在循环里;反之,跳出循环,延时完成。

/**
    * @brief此函数提供最小延迟(以毫秒为单位)对变量递增。
    * @note在默认实现中,SysTick计时器是基准时间的来源。
    *它用于在固定的时间间隔生成中断,其中uwTick是递增的。
    这个函数被声明为__weak,在其他情况下会被覆盖实现在用户文件。
    *@param Delay指定延迟时间长度,单位为毫秒。
    *@retval无
  */
__weak void HAL_Delay(uint32_t Delay)
{
  uint32_t tickstart = HAL_GetTick(); //获得起始时钟
  uint32_t wait = Delay;

  /* Add a freq to guarantee minimum wait */
  if (wait < HAL_MAX_DELAY)   //#define HAL_MAX_DELAY      0xFFFFFFFFU=1111 1111 1111 1111 1111 1111 1111 1111
  {

    //  HAL_TICK_FREQ_1KHZ         = 1U,
    //  HAL_TICK_FREQ_DEFAULT      = HAL_TICK_FREQ_1KHZ

    wait += (uint32_t)(uwTickFreq);  //作用是给wait加1。HAL_TickFreqTypeDef uwTickFreq = HAL_TICK_FREQ_DEFAULT;  /* 1KHz */

  }

  while((HAL_GetTick() - tickstart) < wait) //当前时钟-起始时钟的值小于wait(delay)就重复操作,直到计时结束
  {
  }
}

GetTick函数原型

/**
 调用这个函数是为了增加一个全局变量“uwTick”用作申请时基。
在默认实现中,这个变量每1ms增加一次在SysTick ISR。
这个函数被声明为__weak,在其他情况下会被覆盖实现在用户文件。
* @retval无
  */
__weak void HAL_IncTick(void)
{
  uwTick += uwTickFreq;
}

/**
* @brief提供以毫秒为单位的tick值。
这个函数被声明为__weak,在其他情况下会被覆盖实现在用户文件。
@retval tick value
  */
__weak uint32_t HAL_GetTick(void)
{
  return uwTick;
}

对于裸机程度,没有其他的隐蔽的东西,自己好好分析还是可以理清程序运行的细节及时序关系。遵守的原则:
1、尽量不要在主程序中使用死等的延时,二、每个子程序(也可以叫任务吧)的查询频率要大于主程序运行的时间。比如:ad采样,100ms采样一次,那么,主程序一定要在100ms以内执行完毕。
死等的延时可以是us级别的,时序性较高的地方,大的延时就使用定时器。

stm32f407_intr_handle.c解析

中断处理函数:void EXTI4_IRQHandler

根据startup_stm32f407xx.s中对于handler的描述,编写相应的断点处理函数:

__Vectors       DCD     __initial_sp               ; Top of Stack
                DCD     Reset_Handler              ; Reset Handler
                DCD     NMI_Handler                ; NMI Handler
                DCD     HardFault_Handler          ; Hard Fault Handler
                DCD     MemManage_Handler          ; MPU Fault Handler
                DCD     BusFault_Handler           ; Bus Fault Handler
                DCD     UsageFault_Handler         ; Usage Fault Handler
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     0                          ; Reserved
                DCD     SVC_Handler                ; SVCall Handler
                DCD     DebugMon_Handler           ; Debug Monitor Handler
                DCD     0                          ; Reserved
                DCD     PendSV_Handler             ; PendSV Handler
                DCD     SysTick_Handler            ; SysTick Handler

执行函数:HAL_GPIO_EXTI_IRQHandler(KEY0_PIN),调用stm32f4xx_hal_gpio.c中的void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin),函数的定义为:

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  //#define __HAL_GPIO_EXTI_GET_IT(__EXTI_LINE__) (EXTI->PR & (__EXTI_LINE__))
  //__EXTI_LINE__ specifies the EXTI line flag to check.
  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET) // RESET = 0U(stm32f4xx.h),表明检测到了中断
  {
    /**
  * @brief  Clears the EXTI's line pending bits.
  * @param  __EXTI_LINE__ specifies the EXTI lines to clear.
  *          This parameter can be any combination of GPIO_PIN_x where x can be (0..15)
  * @retval None
  */
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);

    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

回调函数在HAL_GPIO_EXTI_Callback在HAL中未明确实现(弱声明),需要自己构造实现函数。
原型为:

/**
  * @brief  EXTI line detection callbacks.
  * @param  GPIO_Pin Specifies the pins connected EXTI line
  * @retval None
  */
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
  UNUSED(GPIO_Pin);
  /* NOTE: This function Should not be modified, when the callback is needed,
           the HAL_GPIO_EXTI_Callback could be implemented in the user file
   */
}

在key.c中对回调函数进行了重写:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == KEY0_PIN) // KEY0_PIN被按下
	{
		Led_Ctrl(LED0_PIN_ROW, LED0_PIN, LED_ON); //执行点灯操作
  }
}

本节中uint16_t Detect_key(uint16_t key_pin)未使用。

调试流程

在中断处理函数和uwTick自加操作函数处设立中断进行调试:

void EXTI4_IRQHandler(void)
{
	HAL_GPIO_EXTI_IRQHandler(KEY0_PIN);
}


void SysTick_Handler(void)
{
		HAL_IncTick(); //uwTick自加操作 uwTick += uwTickFreq;

}

物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14),物联网开发入门与实战,物联网,学习,笔记
物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14),物联网开发入门与实战,物联网,学习,笔记

软件模拟调试

采用软件模拟方式,进入调试,停在了main函数底下的LED0_Init()函数:

运行出现错误:*** error 65: access violation at 0x40023830 : no ‘write’ permission
由于没有指定相应的cpu:
解决方法:

  • 1 新建cpu.ini,写入:
map 0x40000000,0x400FFFFF read write
  • 2 将cpu.ini添加入debug:
    物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14),物联网开发入门与实战,物联网,学习,笔记

两种代码的比较

中断模式对CPu占用率更小,等待时间更短,减小CPU占有率

课后作业:

1:预习缤程手册关于USART控制器的描述(第30章)
2:通过中断的方式实现一个程序,要求按下KEY1以后:让LED1间隔0.5S闪烁,并持续5S后关闭,实现代码并在板调试文章来源地址https://www.toymoban.com/news/detail-630410.html

到了这里,关于物联网|按键实验---学习I/O的输入及中断的编程|函数说明的格式|如何使用CMSIS的延时|读取通过外部中断实现按键捕获代码的实现及分析-学习笔记(14)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • ARM实验6-基于中断的按键处理程序实验

    一、实验名称:基于中断的按键处理程序实验 二、实验目的:         1.掌握ARM处理器的中断处理过程。         2.掌握ARM处理器中断服务程序的编写方法。         3.通过该编程实验,进一步巩固和强化学生ARM汇编编程的能,ARM应用程序框架,培养学生实际应用的

    2024年02月08日
    浏览(29)
  • 【Linux驱动】设备树中指定中断 | 驱动中获得中断 | 按键中断实验

    🐱作者:一只大喵咪1201 🐱专栏:《Linux驱动》 🔥格言: 你只管努力,剩下的交给时间! 继续拿这个中断流程图来说话。 在硬件上,中断控制器只有 GIC 这一个,但是我们在软件上可以把 GPIO 也归类为中断控制器。 芯片会有多个GPIO模块,所以软件上的中断控制器就会有很

    2024年01月17日
    浏览(40)
  • 驱动——按键中断控制LED灯实验

    要求:按键按一下灯亮,再按一下灯灭 注:由于开发板位置,为了方便一一对应观察,采用key1控制LED3,key2控制LED2,key3控制LED1 0、添加相关设备树节点信息 ①按键相关引脚,通过原理图可得: key1------gpiof9; key2------gpiof7; key3------gpiof8 ②LED灯相关引脚: led1-----gpioe10; led2---

    2023年04月18日
    浏览(22)
  • 【STM32】外部中断实现按键实验

    🐱作者:一只大喵咪1201 🐱专栏:《STM32学习》 🔥格言: 你只管努力,剩下的交给时间! 在前面的文章控制LED和蜂鸣器的按键实验中详细的讲解了怎样通过GPIO的输入模式来控制LED灯和蜂鸣器的状态。这篇文章同样是实现上诉的功能,但是方式是采用外部中断的方式实现的

    2024年02月05日
    浏览(33)
  • 2.外部中断方式检测按键输入并控制LED示例

    打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行,就叫中断。 其中,系统中断表 及对应的说明 如下图所示: 我们可以按住 Ctrl 点击中断向量表中的 ISR 函数名,可以进入该函数,可以发现,这些系统函数虽然都定义了,但是没有编写其工作方式

    2024年04月13日
    浏览(29)
  • ARM开发,stm32mp157a-A7核中断实验(实现按键中断功能)

    ---key.h头文件--- ---key.c函数实现--- ---do_irq.c终端处理函数--- ---main.c测试文件---

    2024年02月11日
    浏览(26)
  • 按键输入实验(stm32)

    说明:以下内容参考正点原子资料 参考前面文章:流水灯实验的代码 按键读取函数 IDR:端口输入数据寄存器

    2024年02月13日
    浏览(24)
  • 物联网||不一样的点灯实验(2)|通过使用CMSIS库函数实现点灯实验-学习笔记(12)

    根据 Enable the GPIO AHB clock using the following function: __HAL_RCC_GPIOx_CLK_ENABLE(). 初始化需首先调用 __HAL_RCC_GPIOx_CLK_ENABLE() 需要将头文件包含在代码中去。 加入初始化stm32f4xx_hal_gpio.c中的void HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_InitTypeDef *GPIO_Init),增加函数:HAL_GPIO_Init(GPIO_TypeDef *GPIOx, GPIO_Ini

    2024年02月14日
    浏览(29)
  • Linux输入设备应用编程(键盘,按键,触摸屏,鼠标)

    目录 一 输入设备编程介绍 1.1 什么是输入设备呢?  1.2 什么是输入设备的应用编程?   1.3 input子系统 1.4  数据读取流程 1.5 应用程序如何解析数据 1.5.1 按键类事件:  1.5.2 相对位移事件  1.5.3 绝对位移事件  二 读取 struct input_event数据   本章学习Linux输入设备的应用编程

    2024年02月05日
    浏览(36)
  • IMX6ULL裸机篇之中断实验-通用中断驱动说明二

    本文是 IMX6ULL 裸机篇---中断实验 。旨在用 C 语言编写一套简单的中断驱动框架代码。 在 start.S 文件中,我们在中断服务函数 IRQ_Handler 中调用了 C 函数 system_irqhandler 来处 理具体的中断。 本实验会认识中断控制器: GIC控制器。 I.MX6U(Cortex-A)的中断控制器,关于 GIC 的详细内容

    2023年04月24日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包