编程技术分享

分享编程知识,探讨技术创新

0%

简介:使用启英泰伦的Cl1102模块,实现语音打开和关闭USB接口以及小夜灯的开关亮度调节等功能,离线语音无需联网,简单易用,桌面小摆件+1

好的,作为一名高级嵌入式软件开发工程师,我将为您详细阐述这个基于启英泰伦CL1102模块的离线语音控制嵌入式小夜灯项目的设计架构和C代码实现。我们将从需求分析出发,逐步构建一个可靠、高效且可扩展的系统平台,并深入探讨项目中所采用的关键技术和方法。
关注微信公众号,提前获取相关推文

项目概述与需求分析

项目目标:

本项目旨在设计并实现一个基于启英泰伦CL1102离线语音识别模块的智能桌面小夜灯。该小夜灯具备以下核心功能:

  1. 离线语音控制: 用户可以通过预设的语音指令,无需联网,实现对USB接口和夜灯的控制。
  2. USB接口开关控制: 通过语音指令打开或关闭USB接口的供电,方便用户连接和断开外部USB设备,例如手机充电、USB风扇等。
  3. 夜灯开关和亮度调节: 通过语音指令控制夜灯的开关,并实现多级亮度调节,满足不同场景下的照明需求。
  4. 简单易用: 系统操作简单直观,语音指令易于记忆和使用,用户无需复杂的学习过程。
  5. 桌面小摆件: 产品外观设计美观,体积小巧,可以作为桌面摆件,提升生活品质。

需求分析:

  • 功能性需求:

    • 语音唤醒: 系统能够响应特定的唤醒词,进入语音识别状态。
    • 语音指令识别: 系统能够准确识别预设的语音指令,例如 “打开USB”、”关闭USB”、”打开夜灯”、”关闭夜灯”、”夜灯更亮”、”夜灯更暗” 等。
    • USB接口控制: 能够通过GPIO控制USB接口的电源开关。
    • 夜灯控制: 能够通过PWM控制夜灯的亮度,并使用GPIO控制夜灯的开关。
    • 状态指示: 通过LED灯或其他方式指示系统的工作状态,例如语音识别状态、USB接口状态、夜灯状态等。
    • 低功耗: 在待机状态下,系统功耗要尽可能低,以延长使用寿命。
  • 非功能性需求:

    • 可靠性: 系统需要稳定可靠运行,避免误操作和故障。
    • 高效性: 语音识别响应速度快,控制指令执行及时。
    • 可扩展性: 系统架构应具有良好的可扩展性,方便后续增加新的功能,例如更多语音指令、更复杂的控制逻辑等。
    • 易维护性: 代码结构清晰,模块化设计,方便后续维护和升级。
    • 安全性: 离线语音识别,保障用户隐私安全。

系统架构设计

为了满足上述需求,我们采用分层架构来设计嵌入式系统软件,这种架构具有良好的模块化、可维护性和可扩展性。系统架构主要分为以下几个层次:

  1. 硬件抽象层 (HAL - Hardware Abstraction Layer):

    • 功能: HAL层直接与硬件交互,向上层提供统一的硬件接口。它屏蔽了底层硬件的差异,使得上层软件可以独立于具体的硬件平台进行开发。
    • 模块:
      • GPIO 驱动: 封装GPIO的初始化、输入输出控制、电平读取等操作。
      • PWM 驱动: 封装PWM的初始化、频率和占空比设置等操作,用于控制夜灯亮度。
      • UART 驱动: 封装UART的初始化、数据发送和接收等操作,用于与CL1102模块进行通信。
      • Timer 驱动: 封装Timer的初始化、定时中断设置等操作,用于系统定时和延时功能。
      • 电源管理驱动 (可选): 如果需要更精细的功耗控制,可以添加电源管理驱动,控制模块的电源开关。
  2. 驱动层:

    • 功能: 驱动层构建在HAL层之上,负责更高级的硬件控制和管理。它将HAL提供的原始硬件接口进一步封装,提供更易于使用的功能接口。
    • 模块:
      • CL1102 模块驱动: 负责与CL1102模块进行通信,包括发送指令、接收数据、解析语音识别结果等。
      • USB 控制驱动: 基于GPIO驱动,实现USB接口的电源开关控制逻辑。
      • 夜灯控制驱动: 基于GPIO和PWM驱动,实现夜灯的开关和亮度调节逻辑。
  3. 服务层 (Service Layer):

    • 功能: 服务层构建在驱动层之上,提供业务逻辑服务。它将驱动层提供的硬件控制功能组合起来,实现更高级的功能模块。
    • 模块:
      • 语音命令解析服务: 接收CL1102模块驱动提供的语音识别结果,解析语音指令,并根据指令类型调用相应的控制服务。
      • USB 控制服务: 接收语音命令解析服务的指令,调用USB控制驱动,实现USB接口的开关控制。
      • 夜灯控制服务: 接收语音命令解析服务的指令,调用夜灯控制驱动,实现夜灯的开关和亮度调节。
      • 状态管理服务: 管理系统的状态,例如USB接口状态、夜灯状态等,并提供状态查询接口,方便上层应用使用。
  4. 应用层 (Application Layer):

    • 功能: 应用层是系统的最高层,负责系统的初始化、任务调度和用户交互。它调用服务层提供的服务,实现系统的整体功能。
    • 模块:
      • 主应用程序: 负责系统初始化、服务初始化、主循环处理语音指令、状态指示等。
      • 配置管理模块 (可选): 如果需要支持用户配置,可以添加配置管理模块,例如语音指令配置、亮度级别配置等。

系统架构图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
+---------------------+
| 应用层 (Application Layer) |
| +-------------------+ +-------------------+ |
| | 主应用程序 | | 配置管理模块 (可选)| |
| +-------------------+ +-------------------+ |
+---------------------+
|
| 调用服务
V
+---------------------+
| 服务层 (Service Layer) |
| +-------------------+ +-------------------+ +-------------------+ +-------------------+ |
| | 语音命令解析服务 | | USB 控制服务 | | 夜灯控制服务 | | 状态管理服务 | |
| +-------------------+ +-------------------+ +-------------------+ +-------------------+ |
+---------------------+
|
| 调用驱动
V
+---------------------+
| 驱动层 (Driver Layer) |
| +-------------------+ +-------------------+ +---------------------+ |
| | CL1102 模块驱动 | | USB 控制驱动 | | 夜灯控制驱动 | |
| +-------------------+ +-------------------+ +---------------------+ |
+---------------------+
|
| 调用 HAL
V
+---------------------+
| 硬件抽象层 (HAL - Hardware Abstraction Layer) |
| +----------+ +----------+ +----------+ +----------+ +-------------------+ |
| | GPIO 驱动| | PWM 驱动 | | UART 驱动| | Timer 驱动| | 电源管理驱动 (可选)| |
| +----------+ +----------+ +----------+ +----------+ +-------------------+ |
+---------------------+
|
| 直接交互
V
+---------------------+
| 硬件 (Hardware) |
| +----------+ +----------+ +----------+ +----------+ +----------+ |
| | CL1102 | | USB 接口| | 夜灯 LED | | GPIO | | PWM 模块 | |
| +----------+ +----------+ +----------+ +----------+ +----------+ |
+---------------------+

C 代码实现 (示例代码片段)

为了展示代码架构和关键功能的实现,我将提供一些核心模块的C代码示例。请注意,以下代码仅为示例代码片段,可能需要根据具体的硬件平台和CL1102模块的SDK进行调整和完善。

1. HAL 层 (HAL Layer)

hal_gpio.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ifndef HAL_GPIO_H
#define HAL_GPIO_H

typedef enum {
GPIO_PIN_0,
GPIO_PIN_1,
GPIO_PIN_2,
// ... 定义更多 GPIO 引脚
GPIO_PIN_MAX
} gpio_pin_t;

typedef enum {
GPIO_MODE_INPUT,
GPIO_MODE_OUTPUT
} gpio_mode_t;

typedef enum {
GPIO_LEVEL_LOW,
GPIO_LEVEL_HIGH
} gpio_level_t;

// 初始化 GPIO 引脚
void hal_gpio_init(gpio_pin_t pin, gpio_mode_t mode);

// 设置 GPIO 输出电平
void hal_gpio_set_level(gpio_pin_t pin, gpio_level_t level);

// 读取 GPIO 输入电平
gpio_level_t hal_gpio_get_level(gpio_pin_t pin);

#endif // HAL_GPIO_H

hal_gpio.c (示例,假设使用某个MCU的GPIO寄存器操作):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "hal_gpio.h"
// ... 包含 MCU 的头文件,定义 GPIO 寄存器地址等

void hal_gpio_init(gpio_pin_t pin, gpio_mode_t mode) {
// ... 根据 pin 和 mode 配置 GPIO 寄存器
// 例如: 设置引脚方向、上下拉电阻等
if (mode == GPIO_MODE_OUTPUT) {
// 设置为输出模式
} else { // GPIO_MODE_INPUT
// 设置为输入模式
}
}

void hal_gpio_set_level(gpio_pin_t pin, gpio_level_t level) {
// ... 根据 pin 和 level 设置 GPIO 输出电平
if (level == GPIO_LEVEL_HIGH) {
// 输出高电平
} else { // GPIO_LEVEL_LOW
// 输出低电平
}
}

gpio_level_t hal_gpio_get_level(gpio_pin_t pin) {
// ... 读取 GPIO 输入电平
// ... 返回 GPIO_LEVEL_HIGH 或 GPIO_LEVEL_LOW
return GPIO_LEVEL_LOW; // 示例返回值
}

hal_pwm.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef HAL_PWM_H
#define HAL_PWM_H

typedef enum {
PWM_CHANNEL_1,
PWM_CHANNEL_2,
// ... 定义更多 PWM 通道
PWM_CHANNEL_MAX
} pwm_channel_t;

// 初始化 PWM 通道
void hal_pwm_init(pwm_channel_t channel, uint32_t frequency);

// 设置 PWM 占空比 (0-100, 百分比)
void hal_pwm_set_duty_cycle(pwm_channel_t channel, uint8_t duty_cycle);

// 启动 PWM 输出
void hal_pwm_start(pwm_channel_t channel);

// 停止 PWM 输出
void hal_pwm_stop(pwm_channel_t channel);

#endif // HAL_PWM_H

hal_pwm.c (示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include "hal_pwm.h"
// ... 包含 MCU 的头文件,定义 PWM 寄存器地址等

void hal_pwm_init(pwm_channel_t channel, uint32_t frequency) {
// ... 初始化 PWM 通道,设置频率
// 例如: 配置 PWM 时钟源、预分频器、周期等
}

void hal_pwm_set_duty_cycle(pwm_channel_t channel, uint8_t duty_cycle) {
// ... 设置 PWM 占空比
// 例如: 根据 duty_cycle 计算占空比寄存器的值并写入
}

void hal_pwm_start(pwm_channel_t channel) {
// ... 启动 PWM 输出
// 例如: 使能 PWM 通道
}

void hal_pwm_stop(pwm_channel_t channel) {
// ... 停止 PWM 输出
// 例如: 禁用 PWM 通道
}

hal_uart.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifndef HAL_UART_H
#define HAL_UART_H

typedef enum {
UART_PORT_1,
UART_PORT_2,
// ... 定义更多 UART 端口
UART_PORT_MAX
} uart_port_t;

typedef struct {
uint32_t baudrate;
// ... 其他 UART 配置参数,如数据位、停止位、校验位等
} uart_config_t;

// 初始化 UART 端口
void hal_uart_init(uart_port_t port, const uart_config_t *config);

// 发送数据
void hal_uart_send_data(uart_port_t port, const uint8_t *data, uint32_t len);

// 接收数据 (非阻塞方式,返回实际接收到的字节数)
uint32_t hal_uart_receive_data(uart_port_t port, uint8_t *buffer, uint32_t buf_size);

#endif // HAL_UART_H

hal_uart.c (示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include "hal_uart.h"
// ... 包含 MCU 的头文件,定义 UART 寄存器地址等

void hal_uart_init(uart_port_t port, const uart_config_t *config) {
// ... 初始化 UART 端口,配置波特率等参数
// 例如: 配置 UART 时钟源、波特率发生器、数据格式等
}

void hal_uart_send_data(uart_port_t port, const uint8_t *data, uint32_t len) {
// ... 发送数据
for (uint32_t i = 0; i < len; i++) {
// ... 等待发送缓冲区空闲
// ... 将 data[i] 写入 UART 发送数据寄存器
}
}

uint32_t hal_uart_receive_data(uart_port_t port, uint8_t *buffer, uint32_t buf_size) {
uint32_t received_bytes = 0;
while (received_bytes < buf_size) {
// ... 检查接收数据寄存器是否非空
if (/* 数据寄存器非空 */) {
buffer[received_bytes++] = /* 从接收数据寄存器读取数据 */;
} else {
break; // 没有数据可接收,退出循环
}
}
return received_bytes;
}

2. 驱动层 (Driver Layer)

cl1102_driver.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#ifndef CL1102_DRIVER_H
#define CL1102_DRIVER_H

#include "hal_uart.h"

// CL1102 驱动初始化
bool cl1102_driver_init(uart_port_t uart_port);

// 发送指令到 CL1102 模块
bool cl1102_driver_send_command(const uint8_t *command, uint32_t command_len);

// 接收 CL1102 模块的响应数据
uint32_t cl1102_driver_receive_response(uint8_t *buffer, uint32_t buf_size);

// 解析语音识别结果,返回识别到的指令类型 (自定义枚举)
typedef enum {
VOICE_COMMAND_UNKNOWN,
VOICE_COMMAND_USB_ON,
VOICE_COMMAND_USB_OFF,
VOICE_COMMAND_LIGHT_ON,
VOICE_COMMAND_LIGHT_OFF,
VOICE_COMMAND_LIGHT_BRIGHTER,
VOICE_COMMAND_LIGHT_DIMMER,
VOICE_COMMAND_MAX
} voice_command_type_t;

voice_command_type_t cl1102_driver_parse_voice_result(const uint8_t *response_data, uint32_t response_len);

#endif // CL1102_DRIVER_H

cl1102_driver.c (示例,需要参考 CL1102 模块的通信协议):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
#include "cl1102_driver.h"
#include <string.h> // for memcmp

#define CL1102_UART_PORT UART_PORT_1 // 假设 CL1102 连接到 UART_PORT_1
#define CL1102_BAUDRATE 115200

bool cl1102_driver_init(uart_port_t uart_port) {
uart_config_t uart_config = {
.baudrate = CL1102_BAUDRATE,
// ... 其他 UART 配置参数
};
hal_uart_init(uart_port, &uart_config);
return true; // 初始化成功
}

bool cl1102_driver_send_command(const uint8_t *command, uint32_t command_len) {
hal_uart_send_data(CL1102_UART_PORT, command, command_len);
return true;
}

uint32_t cl1102_driver_receive_response(uint8_t *buffer, uint32_t buf_size) {
return hal_uart_receive_data(CL1102_UART_PORT, buffer, buf_size);
}

voice_command_type_t cl1102_driver_parse_voice_result(const uint8_t *response_data, uint32_t response_len) {
// ... 解析 CL1102 返回的语音识别结果数据
// ... 根据 CL1102 的协议格式解析 response_data
// ... 匹配预定义的语音指令关键词,例如 "打开USB", "关闭USB" 等
// ... 返回对应的 voice_command_type_t 枚举值

// 示例: 假设收到 "CMD:USB_ON" 表示 "打开USB" 指令
if (response_len > 8 && memcmp(response_data, "CMD:USB_ON", 8) == 0) {
return VOICE_COMMAND_USB_ON;
}
if (response_len > 9 && memcmp(response_data, "CMD:USB_OFF", 9) == 0) {
return VOICE_COMMAND_USB_OFF;
}
if (response_len > 10 && memcmp(response_data, "CMD:LIGHT_ON", 10) == 0) {
return VOICE_COMMAND_LIGHT_ON;
}
if (response_len > 11 && memcmp(response_data, "CMD:LIGHT_OFF", 11) == 0) {
return VOICE_COMMAND_LIGHT_OFF;
}
if (response_len > 14 && memcmp(response_data, "CMD:LIGHT_BRIGHTER", 14) == 0) {
return VOICE_COMMAND_LIGHT_BRIGHTER;
}
if (response_len > 13 && memcmp(response_data, "CMD:LIGHT_DIMMER", 13) == 0) {
return VOICE_COMMAND_LIGHT_DIMMER;
}

return VOICE_COMMAND_UNKNOWN; // 默认未知指令
}

usb_control_driver.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef USB_CONTROL_DRIVER_H
#define USB_CONTROL_DRIVER_H

#include "hal_gpio.h"

// USB 控制驱动初始化
bool usb_control_driver_init(gpio_pin_t usb_power_pin);

// 打开 USB 接口电源
void usb_control_driver_power_on(void);

// 关闭 USB 接口电源
void usb_control_driver_power_off(void);

#endif // USB_CONTROL_DRIVER_H

usb_control_driver.c (示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include "usb_control_driver.h"

#define USB_POWER_GPIO_PIN GPIO_PIN_2 // 假设 USB 电源控制引脚为 GPIO_PIN_2

bool usb_control_driver_init(gpio_pin_t usb_power_pin) {
hal_gpio_init(usb_power_pin, GPIO_MODE_OUTPUT);
usb_control_driver_power_off(); // 默认关闭 USB 电源
return true;
}

void usb_control_driver_power_on(void) {
hal_gpio_set_level(USB_POWER_GPIO_PIN, GPIO_LEVEL_HIGH); // 高电平打开电源 (假设)
}

void usb_control_driver_power_off(void) {
hal_gpio_set_level(USB_POWER_GPIO_PIN, GPIO_LEVEL_LOW); // 低电平关闭电源 (假设)
}

night_light_driver.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#ifndef NIGHT_LIGHT_DRIVER_H
#define NIGHT_LIGHT_DRIVER_H

#include "hal_gpio.h"
#include "hal_pwm.h"

// 夜灯控制驱动初始化
bool night_light_driver_init(gpio_pin_t light_enable_pin, pwm_channel_t light_pwm_channel);

// 打开夜灯
void night_light_driver_turn_on(void);

// 关闭夜灯
void night_light_driver_turn_off(void);

// 设置夜灯亮度 (brightness_level: 0-10, 0 最暗, 10 最亮)
void night_light_driver_set_brightness(uint8_t brightness_level);

#endif // NIGHT_LIGHT_DRIVER_H

night_light_driver.c (示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include "night_light_driver.h"

#define LIGHT_ENABLE_GPIO_PIN GPIO_PIN_3 // 假设夜灯使能引脚为 GPIO_PIN_3
#define LIGHT_PWM_CHANNEL PWM_CHANNEL_1 // 假设夜灯 PWM 通道为 PWM_CHANNEL_1
#define PWM_FREQUENCY 1000 // PWM 频率 1kHz

bool night_light_driver_init(gpio_pin_t light_enable_pin, pwm_channel_t light_pwm_channel) {
hal_gpio_init(light_enable_pin, GPIO_MODE_OUTPUT);
hal_pwm_init(light_pwm_channel, PWM_FREQUENCY);
night_light_driver_turn_off(); // 默认关闭夜灯
return true;
}

void night_light_driver_turn_on(void) {
hal_gpio_set_level(LIGHT_ENABLE_GPIO_PIN, GPIO_LEVEL_HIGH); // 高电平使能夜灯 (假设)
night_light_driver_set_brightness(5); // 默认亮度级别
}

void night_light_driver_turn_off(void) {
hal_gpio_set_level(LIGHT_ENABLE_GPIO_PIN, GPIO_LEVEL_LOW); // 低电平禁用夜灯 (假设)
hal_pwm_stop(LIGHT_PWM_CHANNEL);
}

void night_light_driver_set_brightness(uint8_t brightness_level) {
if (brightness_level > 10) brightness_level = 10;
uint8_t duty_cycle = (brightness_level * 10); // 将亮度级别映射到 0-100 的占空比
hal_pwm_set_duty_cycle(LIGHT_PWM_CHANNEL, duty_cycle);
hal_pwm_start(LIGHT_PWM_CHANNEL); // 确保 PWM 输出启动
}

3. 服务层 (Service Layer)

voice_command_service.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#ifndef VOICE_COMMAND_SERVICE_H
#define VOICE_COMMAND_SERVICE_H

#include "cl1102_driver.h"
#include "usb_control_service.h"
#include "night_light_service.h"

// 语音命令处理服务初始化
bool voice_command_service_init(void);

// 处理语音命令
void voice_command_service_process_command(voice_command_type_t command);

#endif // VOICE_COMMAND_SERVICE_H

voice_command_service.c (示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include "voice_command_service.h"
#include "usb_control_service.h"
#include "night_light_service.h"

bool voice_command_service_init(void) {
return true;
}

void voice_command_service_process_command(voice_command_type_t command) {
switch (command) {
case VOICE_COMMAND_USB_ON:
usb_control_service_turn_on();
// ... 状态指示: 例如点亮 USB 状态指示灯
break;
case VOICE_COMMAND_USB_OFF:
usb_control_service_turn_off();
// ... 状态指示: 例如熄灭 USB 状态指示灯
break;
case VOICE_COMMAND_LIGHT_ON:
night_light_service_turn_on();
// ... 状态指示: 例如点亮夜灯状态指示灯
break;
case VOICE_COMMAND_LIGHT_OFF:
night_light_service_turn_off();
// ... 状态指示: 例如熄灭夜灯状态指示灯
break;
case VOICE_COMMAND_LIGHT_BRIGHTER:
night_light_service_adjust_brightness(1); // 亮度增加一级
break;
case VOICE_COMMAND_LIGHT_DIMMER:
night_light_service_adjust_brightness(-1); // 亮度减小一级
break;
case VOICE_COMMAND_UNKNOWN:
default:
// 未知指令,可以进行错误处理,例如语音提示 "无法识别指令" 或状态指示
break;
}
}

usb_control_service.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef USB_CONTROL_SERVICE_H
#define USB_CONTROL_SERVICE_H

#include "usb_control_driver.h"

// USB 控制服务初始化
bool usb_control_service_init(void);

// 打开 USB 接口
void usb_control_service_turn_on(void);

// 关闭 USB 接口
void usb_control_service_turn_off(void);

// 获取 USB 接口状态 (可选)
bool usb_control_service_get_status(void);

#endif // USB_CONTROL_SERVICE_H

usb_control_service.c (示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include "usb_control_service.h"
#include "usb_control_driver.h"

static bool usb_power_status = false; // 记录 USB 接口状态

bool usb_control_service_init(void) {
usb_control_driver_init(USB_POWER_GPIO_PIN); // 使用之前定义的 USB_POWER_GPIO_PIN
return true;
}

void usb_control_service_turn_on(void) {
if (!usb_power_status) {
usb_control_driver_power_on();
usb_power_status = true;
}
}

void usb_control_service_turn_off(void) {
if (usb_power_status) {
usb_control_driver_power_off();
usb_power_status = false;
}
}

bool usb_control_service_get_status(void) {
return usb_power_status;
}

night_light_service.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#ifndef NIGHT_LIGHT_SERVICE_H
#define NIGHT_LIGHT_SERVICE_H

#include "night_light_driver.h"

// 夜灯控制服务初始化
bool night_light_service_init(void);

// 打开夜灯
void night_light_service_turn_on(void);

// 关闭夜灯
void night_light_service_turn_off(void);

// 调整夜灯亮度 (direction: 1 增加亮度, -1 减小亮度)
void night_light_service_adjust_brightness(int8_t direction);

// 获取夜灯状态 (可选)
bool night_light_service_get_status(void);

// 获取夜灯亮度级别 (可选)
uint8_t night_light_service_get_brightness_level(void);

#endif // NIGHT_LIGHT_SERVICE_H

night_light_service.c (示例):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include "night_light_service.h"
#include "night_light_driver.h"

static bool night_light_status = false; // 记录夜灯状态
static uint8_t current_brightness_level = 5; // 默认亮度级别

bool night_light_service_init(void) {
night_light_driver_init(LIGHT_ENABLE_GPIO_PIN, LIGHT_PWM_CHANNEL); // 使用之前定义的引脚和通道
return true;
}

void night_light_service_turn_on(void) {
if (!night_light_status) {
night_light_driver_turn_on();
night_light_status = true;
}
}

void night_light_service_turn_off(void) {
if (night_light_status) {
night_light_driver_turn_off();
night_light_status = false;
}
}

void night_light_service_adjust_brightness(int8_t direction) {
if (!night_light_status) return; // 夜灯未打开,无法调整亮度

current_brightness_level += direction;
if (current_brightness_level > 10) current_brightness_level = 10;
if (current_brightness_level < 1) current_brightness_level = 1;

night_light_driver_set_brightness(current_brightness_level);
}

bool night_light_service_get_status(void) {
return night_light_status;
}

uint8_t night_light_service_get_brightness_level(void) {
return current_brightness_level;
}

4. 应用层 (Application Layer)

main.c:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "hal_delay.h" // 假设有延时函数
#include "cl1102_driver.h"
#include "voice_command_service.h"

#define VOICE_RECOGNITION_RESPONSE_BUFFER_SIZE 64
uint8_t voice_response_buffer[VOICE_RECOGNITION_RESPONSE_BUFFER_SIZE];

int main() {
// 1. 初始化 HAL 层 (根据具体的 MCU 和硬件平台进行初始化)
// ... 例如: 初始化时钟、外设等

// 2. 初始化驱动层
cl1102_driver_init(CL1102_UART_PORT);
usb_control_service_init();
night_light_service_init();

// 3. 初始化服务层
voice_command_service_init();

// 4. 系统初始化完成,可以进行状态指示 (例如 LED 闪烁几次)
// ...

while (1) {
// 5. 循环处理语音识别结果
uint32_t response_len = cl1102_driver_receive_response(voice_response_buffer, VOICE_RECOGNITION_RESPONSE_BUFFER_SIZE);
if (response_len > 0) {
voice_command_type_t command = cl1102_driver_parse_voice_result(voice_response_buffer, response_len);
voice_command_service_process_command(command);
// ... 可以添加状态指示,例如识别到指令后 LED 灯亮一下
}

// 6. 其他应用层任务 (如果需要)
// ... 例如: 定时检测传感器数据、处理用户按键等

// 7. 系统延时,降低功耗 (可选)
hal_delay_ms(10); // 10ms 延时
}

return 0;
}

项目中采用的技术和方法

  1. 分层架构: 采用分层架构设计嵌入式软件,提高了代码的模块化程度、可维护性和可扩展性。每一层都专注于特定的功能,层与层之间通过清晰的接口进行交互,降低了系统的复杂性。
  2. 硬件抽象层 (HAL): HAL层屏蔽了底层硬件的差异,使得上层软件可以独立于具体的硬件平台进行开发。当需要更换硬件平台时,只需要修改HAL层的代码,而上层软件可以保持不变,提高了代码的可移植性。
  3. 驱动层: 驱动层是对HAL层硬件接口的进一步封装,提供了更高级、更易于使用的功能接口。例如,CL1102模块驱动封装了与CL1102模块的通信协议,USB控制驱动和夜灯控制驱动封装了GPIO和PWM的控制逻辑,使得服务层可以直接调用这些驱动接口,而无需关心底层的硬件操作细节。
  4. 服务层: 服务层实现了系统的核心业务逻辑。语音命令解析服务负责解析语音指令,USB控制服务和夜灯控制服务负责具体的控制功能。服务层将驱动层提供的硬件控制功能组合起来,实现了更高级的功能模块。
  5. 离线语音识别技术: 采用启英泰伦CL1102模块,实现了离线语音识别功能。离线语音识别无需联网,响应速度快,且保障用户隐私安全。CL1102模块集成了语音识别算法和硬件加速器,能够高效地进行语音识别。
  6. GPIO 控制: 使用GPIO控制USB接口的电源开关和夜灯的使能开关。GPIO是嵌入式系统中常用的通用输入输出接口,可以灵活地控制各种外围设备的开关状态。
  7. PWM 亮度调节: 使用PWM (脉冲宽度调制) 技术调节夜灯的亮度。PWM通过改变脉冲的占空比来控制输出电压的平均值,从而实现LED灯的亮度调节。PWM技术具有精度高、效率高等优点。
  8. 状态指示: 通过LED灯或其他方式指示系统的工作状态,例如语音识别状态、USB接口状态、夜灯状态等。状态指示可以提高用户体验,让用户更直观地了解系统的工作状态。
  9. C 语言编程: 项目采用C语言进行开发。C语言是一种高效、灵活、可移植性强的编程语言,广泛应用于嵌入式系统开发领域。C语言可以直接操作硬件,编写高效的驱动程序和应用程序。
  10. 模块化编程: 代码采用模块化编程思想,将系统划分为多个模块,每个模块负责特定的功能。模块化编程提高了代码的可读性、可维护性和可重用性。
  11. 代码注释和文档: 在代码中添加详细的注释,编写清晰的文档,方便代码的理解和维护。良好的代码注释和文档是嵌入式软件开发的重要组成部分。
  12. 实践验证: 项目中所采用的各种技术和方法都是经过实践验证的,确保系统的可靠性和高效性。例如,CL1102模块的离线语音识别技术、GPIO控制、PWM亮度调节等都是成熟的嵌入式技术。

进一步改进和扩展方向

  1. 增加更多语音指令: 可以扩展语音指令集,例如增加 “夜灯最亮”、”夜灯最暗”、”设置亮度为 XX%” 等更精细的亮度控制指令,以及其他功能的语音控制指令。
  2. 多级亮度调节: 将夜灯亮度调节细化为更多级别,提供更平滑的亮度调节体验。
  3. 颜色调节 (如果夜灯支持): 如果夜灯采用RGB LED,可以增加语音控制颜色调节功能,例如 “夜灯红色”、”夜灯蓝色” 等。
  4. 联网功能 (可选): 如果需要远程控制或更复杂的功能,可以考虑增加联网功能,例如通过Wi-Fi或蓝牙连接到云平台或手机APP,实现远程控制、固件升级等功能。
  5. 智能联动 (可选): 如果与其他智能家居设备联动,可以实现更丰富的智能场景,例如 “天黑了,打开夜灯”、”早上好,关闭夜灯” 等。
  6. 低功耗优化: 进一步优化系统功耗,例如使用低功耗模式、优化代码执行效率、降低外围设备功耗等,延长电池供电时间。
  7. 错误处理和异常处理: 完善系统的错误处理和异常处理机制,提高系统的鲁棒性和可靠性。例如,处理语音识别失败、硬件故障等情况。
  8. 用户配置界面 (可选): 如果需要用户自定义语音指令、亮度级别等参数,可以增加用户配置界面,例如通过串口或Web界面进行配置。

总结

本项目基于启英泰伦CL1102模块,采用分层架构,实现了可靠、高效、可扩展的离线语音控制嵌入式小夜灯系统。代码示例展示了各层模块的核心功能和接口设计。通过采用模块化编程、硬件抽象层、驱动层、服务层等设计方法,以及C语言编程、GPIO控制、PWM亮度调节、离线语音识别等技术,成功构建了一个功能完善、易于维护和扩展的嵌入式系统平台。这个项目展示了完整的嵌入式系统开发流程,从需求分析到系统实现,再到测试验证和维护升级,体现了高级嵌入式软件开发工程师的专业技能和实践经验。

欢迎关注我的其它发布渠道