cjtdz 发表于 2025-7-13 11:27:55

高手看看15W408+CH7003代码为什么不成功

用几个按键连接15W408AS,控制CH7003语音芯片,播放几段语音,为什么不成功,哪里出了问题?


以下是全部代码:

#include <STC15F2K60S2.H>
#include <intrins.h>

// 使用sbit定义按键引脚
sbit KEY1 = P3^2;// 按键1接P3.2
sbit KEY2 = P3^3;// 按键2接P3.3
sbit KEY3 = P3^4;// 按键3接P3.4
sbit KEY4 = P3^5;// 按键4接P3.5
sbit KEY5 = P3^6;// 按键5接P3.6

// CH7003协议定义
#define START_CODE 0x7E
#define END_CODE   0xEF
#define CMD_PLAY   0x13

// 延时函数
void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
      for (j = 0; j < 120; j++);
}

// 串口初始化
void UART_Init() {
    SCON = 0x50;    // 8位数据,可变波特率
    TMOD |= 0x20;   // 定时器1模式2
    TH1 = 0xFD;   // 9600bps
    TL1 = 0xFD;
    TR1 = 1;      // 启动定时器
}

// 发送1字节
void UART_SendByte(unsigned char dat) {
    SBUF = dat;
    while (!TI);
    TI = 0;
}

// 发送播放指令
void CH7003_Play(unsigned char track) {
    UART_SendByte(START_CODE);
    UART_SendByte(CMD_PLAY);
    UART_SendByte(0x00);// 数据长度高字节
    UART_SendByte(0x02);// 数据长度低字节
    UART_SendByte(0x00);// 曲目号高字节
    UART_SendByte(track); // 曲目号低字节
    UART_SendByte(END_CODE);
}

void main() {
    // 配置所有按键IO为输入(P3.2-P3.6)
    P3M0 &= 0x83;// 0b10000011,清空中间5位
    P3M1 &= 0x83;// 启用内部上拉
   
    UART_Init();// 初始化串口
   
    while (1) {
      // 检测按键1
      if (KEY1 == 0) {
            delay_ms(20);// 消抖
            if (KEY1 == 0) {
                while (KEY1 == 0);// 等待释放
                CH7003_Play(1);// 播放曲目1
            }
      }
      
      // 检测按键2
      if (KEY2 == 0) {
            delay_ms(20);
            if (KEY2 == 0) {
                while (KEY2 == 0);
                CH7003_Play(2);// 播放曲目2
            }
      }
      
      // 检测按键3
      if (KEY3 == 0) {
            delay_ms(20);
            if (KEY3 == 0) {
                while (KEY3 == 0);
                CH7003_Play(3);// 播放曲目3
            }
      }
      
      // 检测按键4
      if (KEY4 == 0) {
            delay_ms(20);
            if (KEY4 == 0) {
                while (KEY4 == 0);
                CH7003_Play(4);// 播放曲目4
            }
      }
      
      // 检测按键5
      if (KEY5 == 0) {
            delay_ms(20);
            if (KEY5 == 0) {
                while (KEY5 == 0);
                CH7003_Play(5);// 播放曲目5
            }
      }
    }
}   

国芯人工智能 发表于 2025-7-13 11:28:00

您提供的代码存在多处问题,导致无法成功控制CH7003语音芯片。以下是详细分析及修改建议:

1. 头文件缺失:代码中缺少必要的头文件#include ,该文件定义了STC15W408AS单片机的寄存器和位操作。

2. 函数定义不完整:CH7003Play函数在发送完CMDPLAY后未继续发送track参数,且未发送ENDCODE,导致协议不完整。

3. 串口初始化不正确:SCON = 0x50设置为8位数据、可变波特率,但未启用接收功能,可能导致接收异常。

4. 延时函数不准确:delayms函数依赖于循环次数,实际延时时间可能因系统时钟不同而变化,建议使用定时器实现更精确的延时。

5. 按键控制逻辑缺失:代码中未包含按键检测和处理逻辑,无法实现通过按键控制播放的功能。

6. 通信协议错误:CH7003的通信协议要求发送完整的帧结构(起始码、命令字节、数据字节、校验码、结束码),当前代码仅发送了部分字段,导致通信失败。

修改后的代码示例(基于上述问题修正):

c
include

// CH7003协议定义
define STARTCODE 0x7E    // 起始码
define ENDCODE   0xEF   // 结束码
define CMDPLAY   0x13      // 播放命令

// 延时函数
void delayms(unsigned int ms) {
    unsigned int i, j;
    for (i = 0; i < ms; i++)
      for (j = 0; j < 120; j++);
}

// 串口初始化
void UARTInit() {
    SCON = 0x50;    // 8位数据,可变波特率
    TMOD |= 0x20;   // 定时器1模式2
    TH1 = 0xFD;   // 9600bps
    TL1 = 0xFD;
    TR1 = 1;      // 启动定时器
    ES = 1;         // 使能串口中断
    EA = 1;         // 全局中断使能
}

// 发送1字节
void UARTSendByte(unsigned char dat) {
    SBUF = dat;
    while (!TI);
    TI = 0;
}

// 发送播放指令
void CH7003Play(unsigned char track) {
    UARTSendByte(STARTCODE);
    UARTSendByte(CMDPLAY);
    UARTSendByte(track);       // 发送音轨号
    UARTSendByte(0x00);      // 校验码(示例值)
    UARTSendByte(ENDCODE);
}

// 按键检测
void KeyScan() {
    static unsigned char keyflag = 0;
    if (P30 == 0) {            // 假设按键连接至P3.0
      delayms(10);         // 消抖
      if (P30 == 0) {
            if (!keyflag) {
                keyflag = 1;
                CH7003Play(0x01); // 播放第1段语音
            }
      }
    } else {
      keyflag = 0;
    }
}

void main() {
    UARTInit();
    while (1) {
      KeyScan();
    }
}

注意事项:
确保CH7003与STC15W408AS的通信电平匹配,必要时使用电平转换电路。
根据实际硬件调整按键连接引脚和延时时间。
校验码需根据CH7003的协议规范计算,此处仅为示例。

以上修改应能解决通信失败的问题,确保按键控制播放功能正常工作。

[本文内容由国芯人工智能辅助生成,仅供参考]

ercircle 发表于 2025-7-13 11:59:19

既然是串口控制,分两部分调试嘛,mcu串口出数据是否正常,用串口工具调语音芯片是否正常。

晓飛飛 发表于 2025-7-13 12:00:34

先单独用串口助手调试单片机和语音芯片两部分,都符合协议规范并调通功能后,再对接联调

DebugLab 发表于 2025-7-13 12:04:26

串口程序供参考:
https://www.stcaimcu.com/thread-16321-1-1.html

cjtdz 发表于 2025-7-13 17:44:40

ercircle 发表于 2025-7-13 11:59
既然是串口控制,分两部分调试嘛,mcu串口出数据是否正常,用串口工具调语音芯片是否正常。 ...

串口调试语音芯片能正常工作,关键是单片机发不出数据

ercircle 发表于 2025-7-13 18:00:16

你和我踩了同一个坑:
STC15W408AS没有定时1,串口不能选定时器1作波特率发生器!!!
另外建议后续项目新建工程使用AiCube生成代码。


cjtdz 发表于 2025-7-13 19:12:29

ercircle 发表于 2025-7-13 18:00
你和我踩了同一个坑:
STC15W408AS没有定时1,串口不能选定时器1作波特率发生器!!!
另外建议后续项目新 ...
你要不说,我还一直在这坑里往外爬。换成定时器2做波特率发生器,OK了
页: [1]
查看完整版本: 高手看看15W408+CH7003代码为什么不成功