当前位置: 首页 > article >正文

【北京迅为】《STM32MP157开发板使用手册》-第四十三章 软件定时器实验

iTOP-STM32MP157开发板采用ST推出的双核cortex-A7+单核cortex-M4异构处理器,既可用Linux、又可以用于STM32单片机开发。开发板采用核心板+底板结构,主频650M、1G内存、8G存储,核心板采用工业级板对板连接器,高可靠,牢固耐用,可满足高速信号环境下使用。共240PIN,CPU功能全部引出:底板扩展接口丰富底板板载4G接口(选配)、千兆以太网、WIFI蓝牙模块HDMI、CAN、RS485、LVDS接口、温湿度传感器(选配)光环境传感器、六轴传感器、2路USB OTG、3路串口,CAMERA接口、ADC电位器、SPDIF、SDIO接口等


第四十三章 软件定时器实验

43.1 软件定时器的基本概念

定时器,是指从指定的时刻开始,经过一个指定时间,然后触发一个超时事件,用户可以自定义定时器的周期与频率。类似生活中的闹钟,我们可以设置闹钟每天什么时候响,还能设置响的次数,是响一次还是每天都响。

定时器有硬件定时器和软件定时器之分:

硬件定时器是芯片本身提供的定时功能。一般是由外部晶振提供给芯片输入时钟,芯片向软件模块提供一组配置寄存器,接受控制输入,到达设定时间值后芯片中断控制器产生时钟中断。硬件定时器的精度一般很高,可以达到纳秒级别,并且是中断触发方式。

软件定时器,软件定时器是由操作系统提供的一类系统接口,它构建在硬件定时器基础之上,使系统能够提供不受硬件定时器资源限制的定时器服务,它实现的功能与硬件定时器也是类似的。使用硬件定时器时,每次在定时时间到达之后就会自动触发一个中断,用户在中断中处理信息; 而使用软件定时器时,需要我们在创建软件定时器时指定时间到达后要调用的函数。

在很多应用中,我们需要一些定时器任务,硬件定时器受硬件的限制,数量上不足以满足用户的实际需求,无法提供更多的定时器,那么可以采用软件定时器来完成,由软件定时器代替硬件定时器任务。但需要注意的是软件定时器的精度是无法和硬件定时器相比的,因为在软件定时器的定时过程中是极有可能被其他中断所打断,因为软件定时器的执行上下文环境是任务。所以,软件定时器更适用于对时间精度要求不高的任务,一些辅助型的任务。

43.2 实验目的

1)STM32CubeIDE工具软件建立freertos工程

2)学习软件定时器相关的知识与初步使用

我们的实验任务为串口打印软件定时器的信息,软件定时器来观察计数信号量的特性。

首先对实验进行分析,总共需要有一个任务,需要设置定时器的计时时间,然后在回调函数中,通过串口来进行定时时间的打印。

本章节完成的实验存放位置为“iTOP-STM32MP157开发板\iTOP-STM32MP157开发板网盘资料汇总\08_freertos实验例程\07_软件定时器实验.zip”。

43.3 软件定时器实验

43.3.1建立freertos_TIME工程

首先我们打开STM32CubeIDE软件,进入软件界面之后,我们点击File属性,选择NEW下的STM32 Project的选项,如下图所示:

然后我们会进入下图所示界面:在Part Number选择框输入STM32MP157A,然后在右边的选择界面选择STM32MP157AAA,然后点击Next选项 

在Project Name框中输入工程名字freertos_TIME,然后点击Finish选项即可,如下图所示: 

等待工程创建完毕,会询问我们是否要安装OpenSTLinux ,由于我们是在windows环境下,所以我们不需要安装,点击NO即可 

至此我们的工程创建完毕,进入工程界面如下图所示界面: 

43.3.2串口引脚的功能配置

首先我们在下面的搜索框之中输入我们要配置的引脚,我们在这里以PB2为例进行搜索,输入名称之后,对应的引脚在工程中会闪烁,如下图所示:

然后我们使用鼠标左键点击对应的引脚会弹出PB2的复用功能选择,我们在这里选择复用为UART4_RX功能,如下图所示: 

用同样的方法对PG11进行搜索,然后我们使用鼠标左键点击对应的引脚会弹出PG11的复用功能选择,我们在这里选择复用为UART4_TX功能,如下图所示: 

配置完成之后打开左侧菜单的 System CoreàGPIO 进入 GPIO 模式配置界面:如下图所示: 

 

点击对应的引脚配置之后会弹出右下方的管脚配置界面,如上图所示:

在下方会列出要配置选项的具体说明和我们要进行的配置。

选项 GPIO Pull-up/Pull-down 用来设置 IO 口是上拉/下拉/没有上下拉。本实验我们设置为上拉(Pull-up)。

选项 GPIO mode用来设置 GPIO 口的模式,这里默认为alternate function,也就是复用功能。

选项 User Label 是用来设置初始化的 IO 口 Pin 值为我们自定义的宏,这里我们填写为 UART_RX。按照如上要求设置后的界面如下(由于PG11的配置相同,只是最后的Label值不同,也在下方列了出来):

而PG11和PB2的设置相似,只是多了出了一个选项:选项 Mzximum ouput speed 用来设置 IO 口输出速度为低速(Low)/中速(Medium)/高速 (Hign)/快速(Very High)。我们设置为高速Very High 。 

43.3.3时钟的配置

我们本次实验所采用的时钟为外部时钟HSE,所以我们要在左侧属性栏中的System Core 属性下找到RCC将High Speed Clock选择为Crystal/Ceramic Resonator(晶体/陶瓷晶振)。如下图所示:

 

然后在Clock Configuration里我们选择 HSE,作为锁相环 PLL3P 的时钟源,在 MCU 子系统时钟里输入 209 并回车,软件会自动设置相应的倍频和分频,如下图所示:

设置完成之后,如下图所示,然后再手动配置 APB1DIV、APB2DIV 和 APB3DIV的分频值为 2。当 APB1DIV 的分频数大于 1 的时候,基本定时器的倍频器倍频值始终为 2,所以基本定时器的时钟频率为 209MHz。 

43.3.4 配置 FreeRTOS

时钟配置完成之后,我们要再所以我们要在左侧属性栏中的Middleware属性下找到FREERTOS将Interface函数接口选择 CMSIS_V2,选择完成如下图所示:

每个功能窗口对应的功能如下: 

窗口

对应的功能

Mutexes

互斥量

Events

事件

FreeRTOS Heap Usage

堆情况使用

User Constants

常量的定义

Tasks and Queues

任务和消息队列

Timers and Semaphores

软件定时器和信号

Config parameters

配置参数

Inclued parameters

头文件配置

Advanced settings

高级设置

然后我么进入到Tasks and Queues任务和消息队列窗口,如下图所示: 

随后我们点击default默认创建的任务,添加任务名字为TIME的工程,修改优先级为最低osPriorityLow如下图所示: 

创建完成如下图所示: 

随后我们来到Timers and Semaphores选项界面(即软件定时器和信号界面),在该页面中总共有三个任务栏,分别为定时器、二值信号量、计数信号量,如下图所示,然后我们点击最上方软件定时器的Add添加按钮如下图所示:

弹出队列的添加窗口之后,对默认的Timer Name进行修改,修改为Timer01,然后我们点击确定按钮,如下图所示: 

用同样的方法创建Timer02软件定时器,这里要注意的是,Timer02的类型为osTimeOnce, 

创建完成如下图所示: 

配置完成之后我们需要在Project Manage下的Code Generator选项下勾选 Generate peripheral initialization as a pair of ".c/.h' files per peripheral 选项,这样可以独立生成对应外设的初始化.h 和.c 文件(方便配置的查看),如下图所示: 

43.3.5工程的生成与完善

在上述的步骤完成之后,按下键盘的Ctrl+S组合键保存保存 LED.ioc 文件,系统开始生成初始化代码此处会弹出一个警告,提示我们 Systick 定时器已被 HAL 库占用,在 STM32MP157 Cortex-M4 内核上我们更换不了其他的定时器,选择 Yes 继续生成代码即可。

 

工程生成之后如下图所示: 

然后我们进行工程的完善,以及添加对应的逻辑代码。

43.3.5.1 uart.h文件的完善

首先打开uart.h文件,文件存放位置如下图所示:

进入uart.h文件后在/* USER CODE BEGIN Private defines */和/* USER CODE END Private defines */之间添加定义

uint8_t RxBuffer;

用来设置串口发送和接收缓冲区的大小。添加完成如下图所示:

 

43.3.5.2 uart.c文件的完善

首先打开uart.h文件,文件存放位置如下图所示:

进入uart.c文件后在/* USER CODE BEGIN 1 */和/* USER CODE END 1 */之间添加回调函数,在没有编写回调函数的时候,串口只能完成一次发送和接收,在完成一次中断接收以后,就关闭串口中断了,该回调函数的作用是实现字符的循环发送和接收,添加内容如下: 

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)

{

  HAL_UART_Transmit(&huart4,&RxBuffer,1,0);

  HAL_UART_Receive_IT(&huart4,&RxBuffer,1);

}

添加完成之后如下图所示: 

43.3.5.3 main.c文件的完善

我们要修改的main.c文件路径如下图所示:

 

打开main.c文件,在 /* USER CODE BEGIN 2 */和/* USER CODE END 2 */之间添加以下内容:

HAL_UART_Receive_IT(&huart4,&RxBuffer,1);

 

在/* USER CODE BEGIN 4 */和/* USER CODE END 4 */之间添加以下内容:

#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE
{
    while ((UART4->ISR & 0X40) == 0);
    UART4->TDR = (uint8_t) ch;
    return ch;
}

该函数的目的是实现串口输出重定向,重定向是指将fputc里面的输出指向目标设备。因printf函数调用了fputc,而fputc输出有默认指向的目标,且不同库中的fputc输出指向不同,所以需要重写fputc。

43.3.5.4 app_freertos.c文件的完善

我们要修改的 app_freertos.c文件路径如下图所示:

打开app_freertos.c文件,然后我们来到文件的底部可以看到我们创建的TIME_Task任务

修改TIME_Task 任务的for循环上方添加以下内容:

osTimerStart (Timer01Handle, 1000);

osTimerStart (Timer02Handle, 5000);

添加完成如下图所示:

 

随后我们对回调函数Callback01 进行内容的添加,添加内容如下:

uint32_t tick_num1;

static uint32_t Count1;

Count1++;

tick_num1 = osKernelGetTickCount();

printf("Callback01 number is %lu \r\n", Count1);

printf("system counting =%lu \r\n", tick_num1);

添加完成如下图所示:

然后我们对回调函数Callback02 进行内容的添加,添加内容如下: 

	static uint32_t Count2;
	uint32_t tick_num2;
	Count2++;
	tick_num2 = osKernelGetTickCount();
	printf("Callback01 number is %lu \r\n", Count2);
	printf("system counting =%lu \r\n", tick_num2);

添加完成如下图所示:

至此,我们的内容就添加完成了。之后进行编译烧写,可以看到串口打印时间的输出如下图所示:


http://www.kler.cn/a/321067.html

相关文章:

  • 丹摩征文活动 |【前端开发】HTML+CSS+JavaScript前端三剑客的基础知识体系了解
  • docker部署bitnami/etcd:latest
  • GitHub新手入门 - 从创建仓库到协作管理
  • (附项目源码)nodejs开发语言,212 个性化音乐推荐系统的设计与实现,计算机毕设程序开发+文案(LW+PPT)
  • 【大数据】MySQL与Elasticsearch的对比分析:如何选择适合的查询解决方案
  • 视频流媒体播放器EasyPlayer.js RTSP播放器视频颜色变灰色/渲染发绿的原因分析
  • 基于SpringBoot的图书进销存管理系统【附源码】
  • 利用Spring Boot开发学生宿舍管理系统
  • 十一、SOA(SOA的具体设计模式)
  • 【中级通信工程师】终端与业务(三):电信业务
  • leetcode-10. 正则表达式匹配
  • element ui中当el-dialog需要做全屏时,.fullscreen样式修改问题
  • windows电脑git提交告警:LF will be replaced by CRLF the next time Git touches it
  • 包/环境管理工具pip和conda介绍
  • Avalonia的第三方UI库SukiUI详细教程
  • 如何将 Apifox 的自动化测试与 Jenkins 集成?
  • linux-----进程控制
  • 华为HarmonyOS灵活高效的消息推送服务(Push Kit) -- 8 发送通知扩展消息
  • Linux离线安装rmp包
  • 【FastAPI】使用FastAPI和Redis实现实时通知(SSE)
  • flutter基础 --dart语法学习
  • Maven-六、私服仓库
  • Hadoop 常用生态组件
  • 【Kubernetes】常见面试题汇总(三十四)
  • Selenium入门
  • 基于SpringBoot的旅游管理系统