高手看看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
}
}
}
}
您提供的代码存在多处问题,导致无法成功控制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的协议规范计算,此处仅为示例。
以上修改应能解决通信失败的问题,确保按键控制播放功能正常工作。
[本文内容由国芯人工智能辅助生成,仅供参考] 既然是串口控制,分两部分调试嘛,mcu串口出数据是否正常,用串口工具调语音芯片是否正常。 先单独用串口助手调试单片机和语音芯片两部分,都符合协议规范并调通功能后,再对接联调 串口程序供参考:
https://www.stcaimcu.com/thread-16321-1-1.html ercircle 发表于 2025-7-13 11:59
既然是串口控制,分两部分调试嘛,mcu串口出数据是否正常,用串口工具调语音芯片是否正常。 ...
串口调试语音芯片能正常工作,关键是单片机发不出数据 你和我踩了同一个坑:
STC15W408AS没有定时1,串口不能选定时器1作波特率发生器!!!
另外建议后续项目新建工程使用AiCube生成代码。
ercircle 发表于 2025-7-13 18:00
你和我踩了同一个坑:
STC15W408AS没有定时1,串口不能选定时器1作波特率发生器!!!
另外建议后续项目新 ...
你要不说,我还一直在这坑里往外爬。换成定时器2做波特率发生器,OK了
页:
[1]