参考《FreeRTOS入门与工程实践(基于DshanMCU-103).pdf》
目录
- 1 基本概念
- 2 任务创建与删除
- 2.1 什么是任务
- 2.2 创建分配内存
- 2.2.1 动态任务
- 2.2.1 静态分配内存
- 2.3 示例1: 创建任务
- 2.3.1 声
- 2.3.1.1 music.c
- 2.3.1.2 music.h
- 2.3.1.4 硬件接线
- 2.3.2 光
- 2.3.3 色
- 2.3.4 影
在本章中,会涉及如下内容:
- FreeRTOS如何给每个任务分配CPU时间
- 如何选择某个任务来运行
- 任务优先级如何起作用
- 任务有哪些状态
- 如何实现任务
- 如何使用任务参数
- 怎么修改任务优先级
- 怎么删除任务
- 怎么实现周期性的任务
- 如何使用空闲任务
1 基本概念
对于整个单片机程序,我们称之为application,应用程序。
使用FreeRTOS时,我们可以在application中创建多个任务(task),有些文档把任务也称为线程(thread)。
以日常生活为例,比如这个母亲要同时做两件事:
- 喂饭:这是一个任务
- 回信息:这是另一个任务 这可以引入很多概念:
- 任务状态(State):
- 当前正在喂饭,它是running状态;另一个"回信息"的任务就是**"not running"状态**
- "not running"状态还可以细分:
- ready:就绪,随时可以运行
- blocked:阻塞,卡住了,母亲在等待同事回信息
- suspended:挂起,同事废话太多,不管他了
- 优先级(Priority)
- 我工作生活兼顾:喂饭、回信息优先级一样,轮流做
- 我忙里偷闲:还有空闲任务,休息一下
- 厨房着火了,什么都别说了,先灭火:优先级更高
- 栈(Stack)
- 喂小孩时,我要记得上一口喂了米饭,这口要喂青菜了
- 回信息时,我要记得刚才聊的是啥
- 做不同的任务,这些细节不一样
- 对于人来说,当然是记在脑子里
- 对于程序,是记在栈里
- 每个任务有自己的栈
- 事件驱动
- 孩子吃饭太慢:先休息一会,等他咽下去了、等他提醒我了,再喂下一口
- 协助式调度(Co-operative Scheduling)
- 你在给同事回信息
- 同事说:好了,你先去给小孩喂一口饭吧,你才能离开
- 同事不放你走,即使孩子哭了你也不能走
- 你好不容易可以给孩子喂饭了
- 孩子说:好了,妈妈你去处理一下工作吧,你才能离开
- 孩子不放你走,即使同事连发信息你也不能走 这涉及很多概念,后续章节详细分析。
- 你在给同事回信息
2 任务创建与删除
2.1 什么是任务
在FreeRTOS中,任务就是一个函数,原型如下:
void ATaskFunction( void *pvParameters );
任务就是一个函数,任务就是工作
要注意的是:
- 这个函数不能返回
- 同一个函数,可以用来创建多个任务;换句话说,多个任务可以运行同一个函数
- 函数内部,尽量使用局部变量:
- 每个任务都有自己的栈
- 每个任务运行这个函数时
- 任务A的局部变量放在任务A的栈里、任务B的局部变量放在任务B的栈里
- 不同任务的局部变量,有自己的副本
- 函数使用全局变量、静态变量的话
- 只有一个副本:多个任务使用的是同一个副本
- 要防止冲突(后续会讲) 下面是一个示例:
void ATaskFunction( void *pvParameters )
{
/* 对于不同的任务,局部变量放在任务的栈里,有各自的副本 */
int32_t lVariableExample = 0;
/* 任务函数通常实现为一个无限循环 */
for( ;; )
{
/* 任务的代码 */
}
/* 如果程序从循环中退出,一定要使用vTaskDelete删除自己
* NULL表示删除的是自己
*/
vTaskDelete( NULL );
/* 程序不会执行到这里, 如果执行到这里就出错了 */
}
2.2 创建分配内存
创建任务时可以使用 2 个函数:动态分配内存、静态分配内存。
2.2.1 动态任务
使用动态分配内存的函数如下:
BaseType_t xTaskCreate(
BaseType_t xTaskCreate( TaskFunction_t pxTaskCode, // 函数指针, 任务函数
const char * const pcName, // 任务的名字
const configSTACK_DEPTH_TYPE usStackDepth, // 栈大小,单位为word,10表示40字节
void * const pvParameters, // 调用任务函数时传入的参数
UBaseType_t uxPriority, // 优先级
TaskHandle_t * const pxCreatedTask ); // 任务句柄, 以后使用它来操作这个任务
参数说明:
参数 | 描述 |
---|---|
pvTaskCode | 函数指针,任务对应的C函数。任务应该永远不退出,或者在退出时调用 “vTaskDelete(NULL)”。 |
pcName | 任务的名称,仅用于调试目的,FreeRTOS 内部不使用。pcName 的长度为 configMAX_TASK_NAME_LEN。 |
usStackDepth | 每个任务都有自己的栈,usStackDepth 指定了栈的大小,单位为 word。例如,如果传入 100,表示栈的大小为 100 word,即 400 字节。最大值为 uint16_t 的最大值。确定栈的大小并不容易,通常是根据估计来设定。精确的办法是查看反汇编代码。 |
pvParameters | 调用 pvTaskCode 函数指针时使用的参数:pvTaskCode(pvParameters)。 |
uxPriority | 任务的优先级范围为 0~(configMAX_PRIORITIES – 1)。数值越小,优先级越低。如果传入的值过大,xTaskCreate 会将其调整为 (configMAX_PRIORITIES – 1)。 |
pxCreatedTask | 用于保存 xTaskCreate 的输出结果,即任务的句柄(task handle)。如果以后需要对该任务进行操作,如修改优先级,则需要使用此句柄。如果不需要使用该句柄,可以传入 NULL。 |
返回值 | 成功时返回 pdPASS,失败时返回 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY(失败原因是内存不足)。请注意,文档中提到的失败返回值是 pdFAIL 是不正确的。pdFAIL 的值为 0,而 errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY 的值为 -1。 |
2.2.1 静态分配内存
使用静态分配内存的函数如下:
TaskHandle_t xTaskCreateStatic (
TaskFunction_t pxTaskCode, // 函数指针, 任务函数
const char * const pcName, // 任务的名字
const uint32_t ulStackDepth, // 栈大小,单位为word,10表示40字节
void * const pvParameters, // 调用任务函数时传入的参数
UBaseType_t uxPriority, // 优先级
StackType_t * const puxStackBuffer, // 静态分配的栈,就是一个buffer
StaticTask_t * const pxTaskBuffer // 静态分配的任务结构体的指针,用它来操作这个任务
);
相比于使用动态分配内存创建任务的函数,最后2个参数不一样:
参数 | 描述 |
---|---|
pvTaskCode | 函数指针,可以简单地认为任务就是一个C函数。 它稍微特殊一点:永远不退出,或者退出时要调用"vTaskDelete(NULL)" |
pcName | 任务的名字,FreeRTOS内部不使用它,仅仅起调试作用。 长度为:configMAX_TASK_NAME_LEN |
usStackDepth | 每个任务都有自己的栈,这里指定栈大小。 单位是word,比如传入100,表示栈大小为100 word,也就是400字节。 最大值为uint16_t的最大值。 怎么确定栈的大小,并不容易,很多时候是估计。 精确的办法是看反汇编码。 |
pvParameters | 调用pvTaskCode函数指针时用到:pvTaskCode(pvParameters) |
uxPriority | 优先级范围:0~(configMAX_PRIORITIES – 1) 数值越小优先级越低, 如果传入过大的值,xTaskCreate会把它调整为(configMAX_PRIORITIES – 1) |
puxStackBuffer | 静态分配的栈内存,比如可以传入一个数组, 它的大小是usStackDepth*4。 |
pxTaskBuffer | 静态分配的StaticTask_t结构体的指针 |
返回值 | 成功:返回任务句柄; 失败:NULL |
2.3 示例1: 创建任务
配套源码:05_create_task
使用动态、静态分配内存的方式,分别创建多个任务:
-
声:使用无源蜂鸣器播放音乐
参考: 【用单片机吟唱孤勇者(STM32+无源蜂鸣器)】 https://github.com/Lesterbor/Embcode 实测这个链接已经失效了,我会把代码都粘贴出来 https://www.bilibili.com/video/BV1TF411p78W
-
光:LED闪烁 PC13 。
-
色:全彩LED渐变颜色
-
影:监测遥控器并在LCD上显示(甚至可以在LCD上播放动画,但是这个太耗费时间,不是RTOS课程的重点)
任务的几大要素
1 做何事:函数
2 栈 和 TCB(Task Control Block 任务控制块) : malloc/静态分配
3 优先级
那我们怎么创建任务呢?
- 使用动态分配内存或者静态分配内存的函数
怎么管理任务呢?
- 用链表管理任务
2.3.1 声
先使用动态分配内存创建一个关于声音的任务,用无源蜂鸣器播放音乐
/* 创建任务:声 */
// 先创建一个动态分配内存的任务
ret = xTaskCreate( //加返回值是 判断任务有没有创建成功
PlayMusic, //孤勇者的函数
"SoundTask", //声音任务
128, //栈大小
NULL, //无传入的参数
osPriorityNormal, //优先级默认
& xSoundTaskHandle //任务句柄
);
这个PlayMusic函数后面再写
定义返回值和函数句柄,BaseType_t 类型是long类型的变量
BaseType_t ret; // long
static TaskHandle_t xSoundTaskHandle; // void * 在全局变量里记录句柄
2.3.1.1 music.c
新建一个music.c文件,用来编写歌曲的底层驱动文件
这里我是移植了别人的代码,不是我自己写的,但是源代码链接失效了!~~
#include "music.h"
#include "driver_passive_buzzer.h"
#include "driver_timer.h"
/* 实现一个PlayMusic函数 */
/*
声:使用无源蜂鸣器播放音乐
参考:
【用单片机吟唱孤勇者(STM32+无源蜂鸣器)】
https://github.com/Lesterbor/Embcode 找不到了
https://www.bilibili.com/video/BV1TF411p78W
*/
/**
******************************************************************************
* @file : Music.c
* @brief : Music program body
* @author : Lesterbor
* @time : 2022-01-15
*
******************************************************************************
* @attention
*
*
*
******************************************************************************
*/
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PT */
uint16_t Tone_Index[8][3]={
{0 ,0 ,0 },
{262,523,1046},
{294,587,1175},
{330,659,1318},
{349,698,1397},
{392,784,1568},
{440,880,1760},
{494,988,1976}
};
中速代表乐曲速度术语里的Moderato,或称中板,每分钟在88到104拍。
中速 每分钟100拍 一拍600ms
//两只老虎简谱,没有细调
// uint16_t Music_Two_Tigers[][3]={
// {0,0,570},
// {1,Alto,One_Beat},
// {2,Alto,One_Beat},
// {3,Alto,One_Beat},
// {1,Alto,One_Beat},
//
// {0,Alto,24},
//
// {1,Alto,One_Beat},
// {2,Alto,One_Beat},
// {3,Alto,One_Beat},
// {1,Alto,One_Beat},
//
// //{0,Alto,3},
//
// {3,Alto,One_Beat},
// {4,Alto,One_Beat},
// {5,Alto,One_Beat},
// {0,Alto,One_Beat},
//
//
// {3,Alto,One_Beat},
// {4,Alto,One_Beat},
// {5,Alto,One_Beat},
// {0,Alto,One_Beat},
//
//
// {5,Alto,One_TWO_Beat},
// {6,Alto,One_TWO_Beat},
// {5,Alto,One_TWO_Beat},
// {4,Alto,One_TWO_Beat},
// {3,Alto,One_Beat},
// {1,Alto,One_Beat},
//
// //{0,Alto,3},
//
// {5,Alto,One_TWO_Beat},
// {6,Alto,One_TWO_Beat},
// {5,Alto,One_TWO_Beat},
// {4,Alto,One_TWO_Beat},
// {3,Alto,One_Beat},
// {1,Alto,One_Beat},
//
// {0,Alto,24},
//
// {1,Alto,One_Beat},
// {5,Bass,One_Beat},
// {1,Alto,One_Beat},
// {0,Alto,One_Beat},
//
//
// {1,Alto,One_Beat},
// {5,Bass,One_Beat},
// {1,Alto,One_Beat},
// {0,Alto,One_Beat},
//
// };
//中速 每分钟65拍 一拍920ms
uint16_t Music_Lone_Brave[][3]={
//曲信息
{0,0,920},
// #define Bass 0
// #define Alto 1
// #define Teble 2
// #define One_Beat 1
// #define One_TWO_Beat 2
// #define One_FOUR_Beat 4
//第一小节
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
//第二小节
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
//第三小节
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
//第四小节
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
//第五小节
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
{2,Alto,One_TWO_Beat} ,{7,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,
//第六小节
{3,Alto,One_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_FOUR_Beat} ,
{1,Alto,One_FOUR_Beat} ,{2,Alto,One_FOUR_Beat},{1,Alto,One_FOUR_Beat} ,
//第七小节
{3,Alto,One_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat} ,
{2,Alto,One_FOUR_Beat} ,{1,Alto,One_FOUR_Beat},{2,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat} ,
//第八小节
{6,Bass,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat},{6,Bass,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat} ,
{6,Bass,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat},{2,Alto,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,
//第九小节
{7,Bass,One_TWO_Beat} ,{7,Bass,One_FOUR_Beat},{0,Alto,One_TWO_Beat} ,{0,Alto,One_FOUR_Beat} ,
//第十小节
{3,Alto,One_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_FOUR_Beat} ,
{1,Alto,One_FOUR_Beat} ,{2,Alto,One_FOUR_Beat},{1,Alto,One_FOUR_Beat} ,
//第十一小节
{3,Alto,One_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat} ,
{2,Alto,One_FOUR_Beat} ,{1,Alto,One_FOUR_Beat},{2,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat} ,
//第十二小节
{6,Bass,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat},{6,Bass,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat} ,
{6,Bass,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat},{3,Alto,One_TWO_Beat} ,{2,Alto,One_TWO_Beat} ,
//第十三小节
{7,Bass,One_TWO_Beat} ,{7,Bass,One_FOUR_Beat},{0,Alto,One_TWO_Beat} ,{0,Alto,One_FOUR_Beat} ,
//第十四小节
{6,Bass,One_FOUR_Beat} ,{1,Alto,One_FOUR_Beat},{6,Alto,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat} ,
{0,Alto,20 /*小衔接*/} ,{6,Alto,One_FOUR_Beat},{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
{6,Alto,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat},{5,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat} ,
{5,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat},{5,Alto,One_FOUR_Beat} ,
//第十五小节
{3,Alto,One_FOUR_Beat} ,{3,Alto,One_TWO_Beat} ,{3,Alto,One_Beat} ,{0,Alto,20 /*小衔接*/} ,
{0,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,{6,Bass,One_FOUR_Beat} ,{1,Alto,One_FOUR_Beat} ,
//第十六小节
{6,Alto,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat},{0,Alto,20 /*小衔接*/} ,{6,Alto,One_FOUR_Beat} ,
{5,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat},{5,Alto,One_FOUR_Beat} ,{7,Alto,One_TWO_Beat} ,
{7,Alto,One_FOUR_Beat} ,{0,Alto,20 /*小衔接*/},{7,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat} ,
{7,Alto,One_TWO_Beat} ,
//第十七小节
{7,Alto,One_FOUR_Beat} ,{6,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat} ,{3,Alto,One_TWO_Beat} ,
{3,Alto,One_TWO_Beat} ,{0,Alto,One_FOUR_Beat},{3,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
{3,Alto,One_FOUR_Beat} ,
//第十八小节
{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat},{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat} ,
{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat},{5,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat} ,
{5,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat},
//第十九小节
{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat},{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat} ,
{2,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat} ,{2,Alto,One_FOUR_Beat} ,
//第二十小节
{3,Alto,One_TWO_Beat} ,{6,Bass,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{3,Alto,One_TWO_Beat} ,
{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat},{2,Alto,One_FOUR_Beat} ,{1,Alto,One_FOUR_Beat} ,
{1,Alto,One_TWO_Beat} ,
//第二十一小节
{6,Bass,One_Beat} ,{6,Bass,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,
{6,Alto,One_FOUR_Beat} ,{7,Alto,One_FOUR_Beat},
//第二十二小节
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,
{1,Teble,One_FOUR_Beat},{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
//第二十三小节
{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,{3,Teble,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat} ,
{7,Alto,One_FOUR_Beat} ,
//第二十四小节
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,
{1,Teble,One_FOUR_Beat},{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
//第二十五小节
{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,
//第二十六小节
{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{5,Teble,One_FOUR_Beat},{6,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{5,Teble,One_TWO_Beat} ,
//第二十七小节
{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{5,Teble,One_FOUR_Beat},{6,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{5,Teble,One_TWO_Beat} ,
//第二十八小节
//{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,
//{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},
//{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
//第二十九小节
{1,Teble,One_TWO_Beat} ,{0,Alto,One_FOUR_Beat} ,{0,Alto,One_TWO_Beat} ,{0,Alto,One_TWO_Beat} ,
{5,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{5,Teble,One_FOUR_Beat},
//第三十小节
//{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,
//{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},
//{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
//第三十一小节
{1,Teble,One_TWO_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,
//
// //第三十二小节
// {0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,
//
// //第三十三小节
// {0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,
//第三十四小节
{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,
{6,Teble,One_FOUR_Beat},{5,Alto,One_FOUR_Beat} ,
//第三十五小节
{6,Alto,One_TWO_Beat} ,{5,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,{6,Alto,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
//第三十六小节
// {3,Alto,One_FOUR_Beat} ,{3,Alto,One_TWO_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_Beat} ,
// {0,Alto,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
{3,Alto,One_TWO_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_Beat} ,
{0,Alto,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
//第三十七小节
{6,Alto,One_TWO_Beat} ,{5,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,
{6,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,{7,Alto,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/} ,
{7,Alto,One_FOUR_Beat} ,{0,Alto,184 /*小衔接*/} ,{7,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat} ,
{7,Alto,One_FOUR_Beat} ,{6,Alto,One_FOUR_Beat} ,
//第三十八小节
// {3,Alto,One_FOUR_Beat} ,{3,Alto,One_TWO_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_Beat} ,
// {0,Alto,One_FOUR_Beat},{3,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat} ,
{3,Alto,One_TWO_Beat} ,{3,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_FOUR_Beat},
{3,Alto,One_FOUR_Beat} ,{5,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat} ,
//第三十九小节
{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat},{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat} ,
{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat},{5,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat} ,
{5,Alto,One_FOUR_Beat} ,{3,Alto,One_FOUR_Beat},
//第四十小节
{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat},{2,Alto,One_TWO_Beat} ,{3,Alto,One_FOUR_Beat} ,
{2,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,{1,Alto,One_FOUR_Beat} ,{2,Alto,One_FOUR_Beat} ,
//第四十一小节
{3,Alto,One_TWO_Beat} ,{6,Alto,One_TWO_Beat} ,{1,Teble,One_TWO_Beat} ,{3,Teble,One_TWO_Beat} ,
{2,Teble,One_TWO_Beat} ,{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat} ,
{1,Teble,One_TWO_Beat} ,
//第四十二小节
{6,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_TWO_Beat} ,
{6,Alto,One_FOUR_Beat} ,{7,Alto,One_FOUR_Beat},
//开始第一遍循环
//第二十二小节
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,
{1,Teble,One_FOUR_Beat},{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
//第二十三小节
{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,{3,Teble,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat} ,
{7,Alto,One_FOUR_Beat} ,
//第二十四小节
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,
{1,Teble,One_FOUR_Beat},{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
//第二十五小节
{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,
//第二十六小节
{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{5,Teble,One_FOUR_Beat},{6,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{5,Teble,One_TWO_Beat} ,
//第二十七小节
{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{5,Teble,One_FOUR_Beat},{6,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{5,Teble,One_TWO_Beat} ,
//第二十八小节
//{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,
//{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},
//{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
//第二十九小节
{1,Teble,One_TWO_Beat} ,{0,Alto,One_FOUR_Beat} ,{0,Alto,One_TWO_Beat} ,{0,Alto,One_TWO_Beat} ,
{5,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{5,Teble,One_FOUR_Beat},
//第三十小节
//{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,
//{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},
//{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
//第一遍循环结束
//第四十三小节
{6,Alto,One_TWO_Beat} ,{6,Alto,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{3,Alto,One_TWO_Beat} ,
{7,Alto,One_Beat},{0,Alto,184 /*小衔接*/},{7,Alto,One_TWO_Beat},{0,Alto,184 /*小衔接*/},
{7,Alto,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{7,Alto,One_FOUR_Beat},
//第四十四小节
//{6,Alto,One_FOUR_Beat} ,{6,Alto,One_TWO_Beat} ,{6,Alto,One_Beat} ,{0,Alto,One_Beat} ,
//{0,Alto,One_Beat},{0,Alto,One_Beat},
{6,Alto,One_TWO_Beat} ,{6,Alto,One_TWO_Beat} ,{6,Alto,One_TWO_Beat} ,{0,Alto,One_Beat} ,
{0,Alto,One_Beat},{0,Alto,One_Beat},
//第四十五小节
{6,Alto,One_TWO_Beat} ,{6,Alto,One_TWO_Beat} ,{1,Alto,One_TWO_Beat} ,{3,Alto,One_TWO_Beat} ,
{7,Alto,One_Beat},{0,Alto,184 /*小衔接*/},{7,Alto,One_TWO_Beat},{0,Alto,184 /*小衔接*/},
{7,Alto,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{7,Alto,One_FOUR_Beat},
//第四十六小节
{7,Alto,One_FOUR_Beat},{6,Alto,One_TWO_Beat},{6,Alto,One_Beat} ,{0,Alto,One_Beat},
{0,Alto,One_TWO_Beat},{6,Alto,One_FOUR_Beat} ,{7,Alto,One_FOUR_Beat},
//第二次循环
//第二十二小节
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,
{1,Teble,One_FOUR_Beat},{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
//第二十三小节
{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,{3,Teble,One_TWO_Beat} ,{6,Alto,One_FOUR_Beat} ,
{7,Alto,One_FOUR_Beat} ,
//第二十四小节
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{7,Alto,One_FOUR_Beat} ,{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{7,Alto,One_FOUR_Beat} ,
{1,Teble,One_FOUR_Beat},{0,Alto,306 /*小衔接*/},{1,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},
{1,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
//第二十五小节
{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{0,Alto,306 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},
{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,{3,Teble,One_TWO_Beat} ,{5,Teble,One_TWO_Beat} ,
//第二十六小节
{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{5,Teble,One_FOUR_Beat},{6,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{5,Teble,One_TWO_Beat} ,
//第二十七小节
{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},{3,Teble,One_TWO_Beat} ,{5,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{5,Teble,One_FOUR_Beat},{6,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{5,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{5,Teble,One_TWO_Beat} ,
//第二十八小节
//{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,
//{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},
//{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
//第二十九小节
{1,Teble,One_TWO_Beat} ,{0,Alto,One_FOUR_Beat} ,{0,Alto,One_TWO_Beat} ,{0,Alto,One_TWO_Beat} ,
{5,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{5,Teble,One_FOUR_Beat},
//第三十小节
//{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,
//{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{3,Teble,One_FOUR_Beat},{2,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},
//{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},
{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},{3,Teble,One_FOUR_Beat},
{2,Teble,One_TWO_Beat} ,{0,Alto,184 /*小衔接*/},{2,Teble,One_TWO_Beat} ,{1,Teble,One_FOUR_Beat},
{0,Alto,184 /*小衔接*/},{1,Teble,One_FOUR_Beat},
//第二次循环结束
//第四十七小节
{1,Teble,One_TWO_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,{0,Alto,One_Beat} ,
{0,Alto,One_Beat} ,
};
/* USER CODE END PT */
/* Function definition -------------------------------------------------------*/
/* USER CODE BEGIN FD */
/**
* @Function name MUSIC_Begin
* @Introduce 开始播放音乐
* @Return NULL
*/
void MUSIC_Analysis(void)
{
uint16_t MusicBeatNum = ((((sizeof(Music_Lone_Brave))/2)/3)-1);
uint16_t MusicSpeed = Music_Lone_Brave[0][2];
for(uint16_t i = 1;i<=MusicBeatNum;i++){
//BSP_Buzzer_SetFrequency(Tone_Index[Music_Lone_Brave[i][0]][Music_Lone_Brave[i][1]]);
PassiveBuzzer_Set_Freq_Duty(Tone_Index[Music_Lone_Brave[i][0]][Music_Lone_Brave[i][1]], 50); // 设置蜂鸣器频率,占空比50
//HAL_Delay(MusicSpeed/Music_Lone_Brave[i][2]);
mdelay(MusicSpeed/Music_Lone_Brave[i][2]); //Delay ms
}
}
/* USER CODE END FD */
/************************ (C) COPYRIGHT Lesterbor *****END OF FILE****/
void PlayMusic(void *params)
{
PassiveBuzzer_Init(); //无源蜂鸣器 初始化
while (1)
{
MUSIC_Analysis();
}
}
这个MUSIC_Analysis函数是播放音乐的逻辑函数,我们只需要用到这个函数即可,但是我们没有他编写的函数,就调用自己的驱动函数PassiveBuzzer_Set_Freq_Duty,用来设置频率和占空比!频率就保持源码计算出来的频率,占空比就默认50%
2.3.1.2 music.h
写对应的music.h文件
把头文件加到freertos.c最前面,我添加的最后一个头文件就是music.h
/* USER CODE BEGIN Header */
#include "driver_led.h"
#include "driver_lcd.h"
#include "driver_mpu6050.h"
#include "driver_timer.h"
#include "driver_ds18b20.h"
#include "driver_dht11.h"
#include "driver_active_buzzer.h"
#include "driver_passive_buzzer.h"
#include "driver_color_led.h"
#include "driver_ir_receiver.h"
#include "driver_ir_sender.h"
#include "driver_light_sensor.h"
#include "driver_ir_obstacle.h"
#include "driver_ultrasonic_sr04.h"
#include "driver_spiflash_w25q64.h"
#include "driver_rotary_encoder.h"
#include "driver_motor.h"
#include "driver_key.h"
#include "driver_uart.h"
#include "music.h"
#ifndef __MUSIC_H
#define __MUSIC_H
/**
******************************************************************************
* @file : Music.h
* @brief : Header for Music.c file.
* This file provides code for the configuration
* of the Music instances
* @author : Lesterbor
* @time : 2021-10-12
******************************************************************************
* @attention
*
*
******************************************************************************
*/
#define Bass 0
#define Alto 1
#define Teble 2
#define One_Beat 1
#define One_TWO_Beat 2
#define One_FOUR_Beat 4
void PlayMusic(void *params);
#endif
2.3.1.4 硬件接线
- 图中贴了白纸的蜂鸣器是有源蜂鸣器,没有贴白纸的才是无源蜂鸣器,我们要使用的就是无源蜂鸣器~
2.3.2 光
定义三个变量
static StackType_t g_pucStackOfLightTask[128]; // 变量前缀的意思是 全局变量g 指针p uint8_t类型uc的StackOfLightTask 光任务的栈
StaticTask_t g_TCBofLightTask; // 光任务的TCB
static TaskHandle_t xLightTaskHandle; // void * 在全局变量里记录句柄
这次使用静态分配内存的任务 ~ PC13闪烁
/* 创建任务:光 */
// 创建一个静态分配内存的任务
xLightTaskHandle = xTaskCreateStatic(
Led_Test, //LED测试函数,PC13以500ms间隔亮灭一次
"LightTask", //光任务
128, //栈大小,这里提供了栈的大小(长度)
NULL, //无传入的参数
osPriorityNormal, //优先级默认
g_pucStackOfLightTask, // 静态分配的栈,一个buffer,这里只提供了首地址,长度就是栈的大小,最开始栈的类型不对,栈的类型uint32_t
&g_TCBofLightTask // 取址TCB
);
底层函数
/**********************************************************************
* 函数名称: Led_Test
* 功能描述: Led测试程序
* 输入参数: 无
* 输出参数: 无
* 无
* 返 回 值: 0 - 成功, 其他值 - 失败
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/03 V1.0 韦东山 创建
***********************************************************************/
void Led_Test(void)
{
Led_Init();
while (1)
{
Led_Control(LED_GREEN, 1);
mdelay(500);
Led_Control(LED_GREEN, 0);
mdelay(500);
}
}
2.3.3 色
定义三个变量
static StackType_t g_pucStackOfColorTask[128]; // 变量前缀的意思是 全局变量g 指针p uint8_t类型uc的StackOfLightTask 色任务的栈
StaticTask_t g_TCBofColorTask; // 色任务的TCB
static TaskHandle_t xColorTaskHandle; // void * 在全局变量里记录句柄
这次仍然使用静态分配内存的任务 ~ 全彩LED渐变颜色
/* 创建任务:色 */
xColorTaskHandle = xTaskCreateStatic(
ColorLED_Test, //LED测试函数,PC13以500ms间隔亮灭一次
"ColorTask", //光任务
128, //栈大小,这里提供了栈的大小(长度)
NULL, //无传入的参数
osPriorityNormal, //优先级默认
g_pucStackOfColorTask, // 静态分配的栈,一个buffer,这里只提供了首地址,长度就是栈的大小
&g_TCBofColorTask // 取址TCB
);
底层函数,注意这里把LCD相关的代码注释掉了,防止和默认任务的LCD冲突,后面会学到如何互斥操作……
/**********************************************************************
* 函数名称: ColorLED_Test
* 功能描述: 全彩LED测试程序
* 输入参数: 无
* 输出参数: 无
* 无
* 返 回 值: 无
* 修改日期 版本号 修改人 修改内容
* -----------------------------------------------
* 2023/08/04 V1.0 韦东山 创建
***********************************************************************/
void ColorLED_Test(void)
{
uint32_t color = 0;
ColorLED_Init();
while (1)
{
// LCD_PrintString(0, 0, "Show Color: ");
// LCD_PrintHex(0, 2, color, 1);
ColorLED_Set(color);
color += 200000;
color &= 0x00ffffff;
mdelay(500);
}
}
2.3.4 影
使用默认的任务
遥控接收的程序
defaultTaskHandle = osThreadNew(StartDefaultTask, NULL, &defaultTask_attributes);
函数
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
LCD_Init();
LCD_Clear();
for(;;)
{
//Led_Test();
//LCD_Test();
//MPU6050_Test();
//DS18B20_Test();
//DHT11_Test();
//ActiveBuzzer_Test();
//PassiveBuzzer_Test();
//ColorLED_Test();
IRReceiver_Test(); //影 这里的函数用到了LCD显示
//IRSender_Test();
//LightSensor_Test();
//IRObstacle_Test();
//SR04_Test();
//W25Q64_Test();
//RotaryEncoder_Test();
//Motor_Test();
//Key_Test();
//UART_Test();
}
/* USER CODE END StartDefaultTask */
}
如果这些任务同时都打开,那么歌曲就比较卡顿,各个任务之间好像还是有冲突的,音乐不流畅,目前我解决不了,只能保留一个播放音乐的任务,保证音乐的流畅度~
提问:如何确定栈的大小?
根据栈的类型………………………………
学习视频:【FreeRTOS入门与工程实践 --由浅入深带你学习FreeRTOS(FreeRTOS教程 基于STM32,以实际项目为导向)】 https://www.bilibili.com/video/BV1Jw411i7Fz/?p=16&share_source=copy_web&vd_source=8af85e60c2df9af1f0fd23935753a933