一、声明
在05和06的程序里面可以达到的一个效果就是很完美的播放音乐,并且不会影响到其它任务的运行,但是这个代码有一个弊端就是要么创建任务从头开始播放要么就直接删除任务。
我们现在的程序就增加了音乐的暂停和恢复的功能,那么能够达到的一个效果就是:按下中间的play按键的时候就能够创建音乐播放任务,再次按下play(三角符号)的时候音乐就会暂停,再次按下就会从上一次暂停的地方继续播放音乐
如果在软件的配置找不出任何问题,硬件上也没有连接错误的话,那么外设还是没有反应有可能是连线接触不良
示例代码:temp09,自己程序:07
二、基本CubeMx的配置
三、外设的配置
OLED
硬件连接
PB7——SDA
PB6——SCL
软件配置
CubeMx
直接点击I2C配置就好,其它的参数都是默认的
keil5
包含的头文件:这个里面不需要写#include "driver_oled.h"因为在#include "driver_lcd.h"里面已经包含了。好像在OLED的使用里面也用到了timer的文件,所以在添加文件的时候也把"driver_timer"这个文件也要添加进去
添加文件的时候要注意"ascii_font.c"这个文件只需要在BSP的文件包里面要包含这个文件,并不需要把这个添加到keil5里面的BSP文件下面去,也不需要在头文件包含里面写这个头文件
RGB的Led灯
硬件连接
VCC——5V
R——PA2
B——PB3
G——PA15
软件配置
CubeMx
记得要开一个内部时钟(虽然也不知道内部时钟有什么用),记得下面的PSC和ARR要配置一下,不然RGB灯的亮度会有点问题
keil5
蜂鸣器
硬件连接
IO——PA8
VCC——5V
软件配置
CubeMx
要开一个PWM输出,还有下面的PSC以及ARR要配置一下
keil5
CBT6的Led
软件配置
CubeMx
keil5
包含的头文件:
因为#include "driver_led.h"里面使用到了mdelay的延时函数,而这个延时函数是包含在#include "driver_timer.h"这个文件里面,所以我们除了要包含led的库函数文件还要包含timer的库函数文件
红外遥控接收模块
硬件连接
VCC——3.3V
IO——PB10(外部中断)
软件配置
CubeMx
下降沿模式、上拉 输入、别忘了还要开一个中断
keil5
最开始我写了一个程序烧入进去没有反应就是因为我没有添加中断的文件( "driver_irq"),还有旋转编码器的文件
四、代码讲解
/* C8T6板子上的LED灯 */
#include "driver_timer.h"
#include "driver_led.h"
/* OLED显示 */
#include "driver_lcd.h"
/* RGB的LED显示 */
#include "driver_color_led.h"
/* 蜂鸣器 */
#include "driver_passive_buzzer.h"
/* 红外遥控模块 */
#include "driver_ir_receiver.h"
#include "driver_rotary_encoder.h"
/* USER CODE BEGIN Variables */
static StackType_t g_pucStackOfLightTask[128];
static StaticTask_t g_TCBofLightTask;
static TaskHandle_t xLightTaskHandle;
static StackType_t g_pucStackOfColorTask[128];
static StaticTask_t g_TCBofColorTask;
static TaskHandle_t xColorTaskHandle;
/* USER CODE END Variables */
/* USER CODE BEGIN RTOS_THREADS */
/* add threads, ... */
/* 创建任务: 声 */
// extern void PlayMusic(void *params);
// ret = xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal, &xSoundTaskHandle);
/* 创建任务: 光 */
xLightTaskHandle = xTaskCreateStatic(Led_Test, "LightTask", 128, NULL, osPriorityNormal, g_pucStackOfLightTask, &g_TCBofLightTask);
/* 创建任务: 色 */
xColorTaskHandle = xTaskCreateStatic(ColorLED_Test, "ColorTask", 128, NULL, osPriorityNormal, g_pucStackOfColorTask, &g_TCBofColorTask);
/* USER CODE END RTOS_THREADS */
/* USER CODE END Header_StartDefaultTask */
void StartDefaultTask(void *argument)
{
/* USER CODE BEGIN StartDefaultTask */
/* Infinite loop */
uint8_t dev, data;
int len;
int bRunning;
TaskHandle_t xSoundTaskHandle = NULL;
BaseType_t ret;
LCD_Init();
LCD_Clear();
IRReceiver_Init();
LCD_PrintString(0, 0, "Waiting control");
while (1)
{
/* 读取红外遥控器 */
if (0 == IRReceiver_Read(&dev, &data))
{
if (data == 0xa8) /* play */
{
/* 创建播放音乐的任务 */
extern void PlayMusic(void *params);
if (xSoundTaskHandle == NULL)
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Create Task");
ret = xTaskCreate(PlayMusic, "SoundTask", 128, NULL, osPriorityNormal+1, &xSoundTaskHandle);
bRunning = 1;
}
else
{
/* 要么suspend要么resume */
if (bRunning==1)
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Suspend Task");
vTaskSuspend(xSoundTaskHandle);
PassiveBuzzer_Control(0);
/*如果不加这一步停止蜂鸣器的话,
那么蜂鸣器播放音乐会被暂停但是保持在同一音调 */
bRunning = 0;
}
else
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Resume Task");
vTaskResume(xSoundTaskHandle);
bRunning = 1;
}
}
}
else if (data == 0xa2) /* power */
{
/* 删除播放音乐的任务 */
if (xSoundTaskHandle != NULL)
{
LCD_ClearLine(0, 0);
LCD_PrintString(0, 0, "Delete Task");
vTaskDelete(xSoundTaskHandle);
PassiveBuzzer_Control(0); /* 停止蜂鸣器 */
xSoundTaskHandle = NULL;
}
}
}
}
/* USER CODE END StartDefaultTask */
}
注意:
在 C 和 C++ 中,bRunning 通常被定义为 bool 类型。对于 bool 类型而言:
当 bRunning 为 true 时,在条件判断里其本质等价于整数 1。
当 bRunning 为 false 时,在条件判断里其本质等价于整数 0。
在上述代码中,当 bRunning 为 true 时,if 条件判断通过;为 false 时,!bRunning 条件判断通过。
不过在 C 和 C++ 里,非 bool 类型的值也能用于条件判断。例如整数,非零值会被视为 true,零值会被视为 false。
所以一般的if(bRunning)里面就相当于if(bRunning==1);