赞
踩
本实验首先大家自身要有stm32cubemx基础配置,比如GPIO、中断、串口、SPI等,FreeRTOS有相关的调用函数基础及调度任务的概念都需要提前理解。单独stm32cubemx或FreeRTOS网上很多,这里就不细说了。
第一步首先打开stm32cubemx软件,创建工程之后,除了把sys、Rcc配置完成还得勾选一下FreeROTS选项enabled如下图
这样configuration就生成了FREERTOS的配置参数,如下图
点击进入FREERTOS配置
对于配置参数的理解,大家自行网上搜索,因为要写,将会写很长的文本,不易于阅读该帖子,本人只介绍如何生成任务函数或队列或信号量。
由上图可以添加函数和队列,可以看见添加了3个任务和1个队列。
上图是配置互斥量、二值量。可以看到配置了1个互斥量。
上图体现的是创建任务、队列定时器及信号量所需要的内存空间。
之后就可以直接生成工程,本人生成的是keil工程。下图是工程的用户文件和FreeROTS文件。
修改freertos.c文件来修改自己的任务及队列,当然hal也封装了FreeRTOS一些函数,但是不影响我们调用原来拥有的FreeRTOS的API函数。不过我们也可以使用它们封装函数来创建,发送,接收等函数,如果为了通用性,个人还是觉得调用以前原来拥有的API也没什么大问题,因为原来的API也不需要什么复杂的参数,很容易实现我们的需求。下图是freertos.c文件下定义的变量
由我们cube生成前,本人确实添加了3个任务和一个队列和一个互斥量。
该文件有个FreeRTOS初始化函数void MX_FREERTOS_Init(void),如下图:
上图是该初始化函数实现创建任务的过程。默认这个任务函数的参数值为NULL,因此如果自身想添加带函数参数的任务函数,建议是自己在keil工程下实现,cube生成只适合没参数的函数任务。由上图的实现过程可以看得出其已经被封装过了的API,当然我们可以不使用其API而用原有的API函数。
本实验,自己在keil工程下创建一个队列queue_1,因此在freeRTOS初始化函数下面添加如下:
我们将这个队列通过函数参数传入两个任务里,因此将原来没参数的修改成如下图:
注意,因为这个queue_1句柄的使用不需要指针,所以我们定义queue_1时不需要指针变量,如果是指针变量,千万别使用,因为这个是局部变量,初始化函数结束之后,这个变量将会被释放,后面如果使用这个变量的地址将会出现内存错误。因此由于刚好参数要的不是指针变量,因此直接传局部变量,而不是传局部变量的地址,这样的做法还是可取的。
下面有我们生成的任务函数:默认函数内部是一个for(;;)的空循环,因此我们修改它实现如下:
printf警告的原因是编译器的误识别,要消除警告可以在该文件添加头文件"stm32f1xx_hal.h"。警告就消除了:
从这个函数我们可以看到xQueeuSendToBack是原本的API函数。
另外一个任务函数做接收并打印实现如下:
编译烧录,有以下的结果:
当然我们是目的是实现串口中断,首先我们知道中断服务程序里面只能调用一些特殊的FreeRTOS的API,而不能直接使用xQueueSendToFront()和xQueueSend()等普通的API,能使用的函数如下:
因此,在我们在cube环境配置好uart之后,在keil工程中,先添加好printf的重定义fputc函数。这个添加方式网上也有很多教程如何使用printf,同时,在main函数下实现uart串口接收回调函数void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)。实现如下:
上图的第204行至于为什么重新添加HAL_UART_Receive_IT,可以阅读以下链接的解释:(如果理解可以不需要参考该链接)
https://bbs.afuiot.com/forum.php?mod=viewthread&tid=130&extra=
同时在main函数之后还得添加HAL_UART_Receive_IT(&huart1,UART_BUF,UART_BUF_SIZE);,如下图:
UART_BUF 和UART_BUF_SIZE的定义在main的全局区中,如下图:
71行这个外部变量声明的这个队列,该队列是要在main.c文件的串口中断回调函数使用得到该变量,又因为这个队列是cube生成之后放置在freertos.c文件上的,因此要在main文件下写上一个外部声明的队列,这样调用这个队列就不会报错。
由于这个UART_BUF_SIZE才4个字节大小,因此当串口调试助手测试时,向mcu发送4个字节,就能触发一次中断,
我们已经实现了串口接收中断发送捕获的数据到队列UartQueueHandle中,UartQueueHandle这个队列在上图可以看到它的外部声明,实际定义已经在freertos.c文件定义了(由cube配置的队列)。我们看看第三个任务函数实现如下:
因此就是实现了回射功能,测试功能如下:
因为此时另外两个任务在不断的打印i和j,因此在发送端发送时,就马上使用暂停查看确实是有1234的值被回射。
如需要源码工程可以到我个人的资源页获取,谢谢支持,如有问题,请在评论区评论。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。