第一章 FreeRTOS与HAL库

第一节、对比学习,温故而知新:

我总是认为:当去学习一门新东西时,他总会让你对老东西有更深刻的理解。学习完Linux之后,再学习单片机的实时系统RTOS也有这种感觉,它会加深你对进程管理的更加深入的理解。

如果你学习过Linux之后,再来学习FreeRTOS总会有一种可以从更高的维度来理解单片机的HAL库开发,及FreeRTOS这个轻量级的单片机的OS它到底做了哪些事件?

如果说Linux内核是的巨大的操作系统,那么FreeRTOS只从中摘取了进程管理的部分内部,并优化了在单片机上的运行,而形成的一个轻量机的管理单片机中的任务执行的实时系统。

如图所示:

第二节、创建第一个FreeRTOS工程的步骤:

(关于CubeMX,及Keil的开发环境的下载及搭建请自行百度)

1. 选择系统使用的时RCC时钟源(是哪个晶振与使用什么的频率):

因为RTOS进行执行管理与调度的基本操作都是tick中断中进行的,所以RCC时钟频率的基准是第一要素要选择的。

1. 选择晶振:

2.设置频率:

2.选择SYS时钟基准源与调试Debug的方式:一般会选择一个频率高的定时器,因为这新的精度会更高一些。调试则使用串口调试。

第三节、认识GPIO的八种工作模式:

掌握了GPIO就相当掌握了硬件操作的根本:

1.输入模式有四种:

1. 输入上拉:适用场景:以上两种用于没有外部电路上拉时使用。

2.输入下拉:适用场景:以上两种用于没有外部电路下拉时使用。

3.输入浮空:适用场景:由外部电路电平高低决定的输入场景,或外部自带上,下拉电阻的情况。

4.模拟输入:适用场景:读取外部模拟信号的场景。比如直接传入到ADC控制器时。

2.输出模式有四种:

1. 推挽输出:适用于需要高电流驱动和快速切换的场景,如产生PWM波。

此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。I/O口的电平一定是输出的电平。

2.开漏输出:适用于需要多个设备共享信号线、接口电平转换和驱动高压负载等场景,如模拟I2C通信时

此时施密特触发器是打开的,即输入可用,通过输入数据寄存器GPIOx_IDR可读取I/O的实际状态。,但:I/O口的电平不一定是输出的电平,也可能是外部电路的电平。

3.开漏复用输出:适用于需要多个设备共享信号线或接口电平转换的场景,同时利用微控制器的复用功能将引脚配置为多种用途:如硬件I2C控制器

输出的高低电平的来源于其它外设,施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态  

4.推挽复用输出:适用于需要高电流驱动、快速切换和多功能复用的场景,可以加强驱动能力。

施密特触发器打开,输入可用,通过输入数据寄存器可获取I/O实际状态。

第四节、使用HAL库操作GPIO引脚的方式:

1.CubeMx直接进行GUI方式的快速设置引脚模式:

HAL操作引脚常用的库函数API:

2. 读取电平:HAL_GPIO_ReadPin

GPIO_PinState HAL_GPIO_ReadPin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin)
读取GPIOx端口的第GPIO_PIN_X引脚的引脚状态:
GPIO_PinState enum values:
– GPIO_PIN_RESET: to clear the port pin//低电平
– GPIO_PIN_SET: to set the port pin//高电平

3.设置电平高or低:HAL_GPIO_WritePin

void HAL_GPIO_WritePin (GPIO_TypeDef * GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
设置GPIOx中的第GPIO_PIN_x引脚的高低电平,没有返回值

第五节:HAL库开发第一个点灯代码实验:

1. 应用与驱动分离:分文件编程

优秀的作法:即把驱动的逻辑与任务中的应用分离开的方式。

2.驱动的创建:

led_driver.h:

#ifndef __LED_DRIVER_H__
#define __LED_DRIVER_H__
void led_on(void);
void led_off(void);
#endif

led_driver.c:

#include "led_driver.h"
#include "main.h"
//开灯
void led_on()
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);
}
//关灯:
void led_off()
{
    HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_SET);
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,下面给出一个结合FreeRTOSHAL库的中级功能实现示例: 1. 创建任务:使用FreeRTOS提供的API函数xTaskCreate()创建任务,例如: ``` xTaskCreate(Task1, "Task1", configMINIMAL_STACK_SIZE, NULL, 1, NULL); xTaskCreate(Task2, "Task2", configMINIMAL_STACK_SIZE, NULL, 2, NULL); ``` 2. 任务实现:在任务函数中,可以通过HAL库提供的驱动函数和API接口对硬件进行操作,例如: ``` void Task1(void *pvParameters) { while(1) { HAL_GPIO_TogglePin(LED_GPIO_Port, LED_Pin); vTaskDelay(500); } } void Task2(void *pvParameters) { while(1) { HAL_UART_Transmit(&huart1, (uint8_t*)"Hello World", 11, 100); vTaskDelay(1000); } } ``` 3. 任务同步:可以使用FreeRTOS提供的信号量、互斥量等机制来实现任务同步,例如: ``` SemaphoreHandle_t xSemaphore; xSemaphore = xSemaphoreCreateMutex(); void Task1(void *pvParameters) { while(1) { xSemaphoreTake(xSemaphore, portMAX_DELAY); // 临界区代码 xSemaphoreGive(xSemaphore); } } void Task2(void *pvParameters) { while(1) { xSemaphoreTake(xSemaphore, portMAX_DELAY); // 临界区代码 xSemaphoreGive(xSemaphore); } } ``` 4. 定时器:可以使用FreeRTOS提供的定时器来实现定时任务,例如: ``` TimerHandle_t xTimer; xTimer = xTimerCreate("MyTimer", pdMS_TO_TICKS(500), pdTRUE, NULL, TimerCallback); void TimerCallback(TimerHandle_t xTimer) { // 定时器回调函数 } xTimerStart(xTimer, 0); ``` 以上是一个简单的中级功能实现示例,具体实现根据不同需求可能会有所不同。需要注意的是,FreeRTOSHAL库的API函数都是阻塞的,因此在使用时需要注意任务调度和同步机制的设计,避免死锁等问题的发生。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值