第一节、对比学习,温故而知新:
我总是认为:当去学习一门新东西时,他总会让你对老东西有更深刻的理解。学习完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);
}