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

【北京迅为】《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接口等


第四十一章 计数信号量实验

41.1计数信号量的基本概念

二进制信号量可以被认为是长度为 1 的队列,而计数信号量则可以被认为长度大于 1 的队列,信号量使用者依然不必关心存储在队列中的消息,只需关心队列是否有消息即可。

顾名思义,计数信号量肯定是用于计数的,在实际的使用中,我们常将计数信号量用于事件计数与资源管理。每当某个事件发生时,任务或者中断将释放一个信号量(信号量计数值加 1),当处理被事件时(一般在任务中处理),处理任务会取走该信号量(信号量计数值减 1),信号量的计数值则表示还有多少个事件没被处理。此外,系统还有很多资源,我们也可以使用计数信号量进行资源管理,信号量的计数值表示系统中可用的资源数目,任务必须先获取到信号量才能获取资源访问权,当信号量的计数值为零时表示系统没有可用的资源,但是要注意,在使用完资源的时候必须归还信号量,否则当计数值为 0的时候任务就无法访问该资源了。

41.2实验目的

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

2)学习计数信号量的相关知识与初步使用

我们的实验任务为通过两个按键和串口,来观察计数信号量的特性。

首先对实验进行分析,总共需要有两个任务,分别为TAKE 释放任务和GIVE获取任务,并通过串口打印对应的信息。所实现的功能如下:

TAKE 任务:通过按下VOL_UP按键来实现计数信号量的释放,释放成功和失败会通过串口进行打印。

GIVE任务:通过按下VOL_DN按键来实现计数信号量的获取。获取成功和失败会通过串口进行打印。

本章节完成的实验存放位置为“iTOP-STM32MP157开发板\iTOP-STM32MP157开发板网盘资料汇总\08_freertos实验例程\05_计数信号量实验.zip

41.3 计数信号量实验

41.3.1建立freertos_Count工程

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

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

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

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

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

41.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 。

41.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。 

41.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默认创建的任务,添加任务名字为TAKE的工程,修改优先级为最低osPriorityLow如下图所示: 

我们只需要修改任务名称和设置线程函数名即可,修改完成之后点击OK按钮,随后我们以同样的方式,创建任务名字为GIVE的任务,创建完成如下图所示:

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

弹出队列的添加窗口之后,对默认的Semaphore Name进行修改,修改为CountingSem,然后对于计数量Count我们修改为4,然后我们点击确定按钮,如下图所示: 

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

 

41.4.5工程的生成与完善

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

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

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

41.3.5.1 对应文件与文件夹的添加

由于我们在裸机章节已经完善了对应的LED,BEEP和KEY文件,所以我们将iTOP-STM32MP157开发板网盘资料汇总\06_Cortex-M4实验例程\03_KEY\KEY\CM4\Core\BSP文件拷贝到当前工程对应的位置,拷贝完成如下下图所示:

41.3.5.2 uart.h文件的完善

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

 

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

uint8_t RxBuffer;

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

41.3.5.3 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);

}

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

 

41.3.5.4 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。

41.3.5.5 app_freertos.c文件的完善

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

打开app_freertos.c文件,我们首先在/* USER CODE BEGIN Includes */和/* USER CODE END Includes */中间添加以下内容,将led、beep和key的头文件进行添加。

#include "../BSP/Include/led.h"

#include "../BSP/Include/key.h"

添加完成如下图所示:

 

然后我们来到文件的底部可以看到我们创建的TAKE_Task 和GIVE_Task任务

修改TAKE_Task 任务的for循环中的内容,修改内容如下:

	uint8_t key;osStatus_t xReturn = osOK ;for(;;){key = key_scan();if (key){switch (key){case VOL_UP_PRES:xReturn = osSemaphoreAcquire(CountingSemHandle,0);LED2_TOGGLE();if(osOK == xReturn){printf("Conuting_Handle Task Success!\n");}else{printf("Conuting_Handle Take Error!\n");}break;}}}osDelay(20);

修改完成如下图所示:

随后我们修改GIVE_Task 任务的内容,修改内容如下: 

	uint8_t key;osStatus_t xReturn = osOK ;for(;;){key = key_scan();if (key){switch (key){case VOL_DN_PRES:xReturn =osSemaphoreRelease(CountingSemHandle);LED3_TOGGLE();if(osOK == xReturn){printf("Conuting_Handle Release Success!\n");}else{printf("Conuting_Handle Release Error!\n");}break;}}}osDelay(20);

至此,我们的内容就添加完成了。之后进行编译烧写,当我们对VOL_UP和VOL_DN进行按下时,可以看到串口的打印信息如下图所示:


http://www.mrgr.cn/news/31152.html

相关文章:

  • 开源 - Ideal库 - 常用枚举扩展方法(二)
  • HTTP 客户端怎么向 Spring Cloud Sleuth 传输跟踪 ID
  • 【神经科学学习笔记】基于分层嵌套谱分割(Nested Spectral Partition)模型分析大脑网络整合与分离的局部指标(二)
  • PICO+Unity MR空间网格
  • 基于SpringBoot+Vue实现剧本杀服务平台【源码+LW+PPT+部署】
  • 【大数据学习 | kafka高级部分】kafka的kraft集群
  • 二级C语言2024-3易错题
  • 【ppt2svg svg2png/jpg】ppt转图片解决方案
  • Pandas中df常用方法介绍
  • C++日期类详解 第二级支线任务
  • FB FC里调用全局变量注意事项
  • 用 JS 实现一个发布订阅模式
  • Unity的Text组件中实现输入内容的渐变色效果
  • FedOV
  • solana项目counter,测试过程中执行报错记录分享
  • 【leetcode】堆习题
  • 铲屎官进!宠物空气净化器真的有用吗?哪款去浮毛效果好
  • SQLAlchemy思维导图
  • [产品管理-28]:NPDP新产品开发 - 26 - 产品生命周期管理 - 产品上市的八大步骤
  • 软考高级第四版备考---第四十八天(项目基本要素-项目内外部运行环境、组织系统、项目管理和产品管理)
  • java踩坑
  • Highcharts甘特图基本用法(highcharts-gantt.js)
  • 什么是机房IP?有什么缺点
  • 骨传导耳机哪个牌子比较好?2024耳机排行榜首发!一文读懂谁更值得入手!
  • 虚拟机(VMware)安装,保姆级教程(附所有安装包及所有安装步骤)
  • 稳了,搭建Docker国内源图文教程