标题: 高手看看15W408单片机+CH7003代码为什么不成功 [打印本页]

作者: cjtdz    时间: 2025-7-13 11:44
标题: 高手看看15W408单片机+CH7003代码为什么不成功
用几个按键连接STC15W408AS,控制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
            }
        }
    }
}   


作者: a399288395    时间: 2025-7-13 14:11
你的程序,EA=1 好像没有看到, 总中断没有打开,串口是不工作的;  一般调试,第一步就是借助串口工具,;  1; 用串口工具验证你的单片机串口传的数据是否正确, 2; 用串口工具给语音芯片发数据看看是否受控, 可以验证语音电路是否工作; 都验证完了后再联调;   以后你就会发现, 不管调试什么 串口打印 检查验证数据 是个非常方便和必须的方式; 能节省很多很多时间 少走很多弯路。
作者: 单片机重购    时间: 2025-7-13 15:03
你好哦可以回我嘛我是可以给你解答的哦。我可以给你解答的哦。首先你如果是进行串口收发程序的时候时,你是可以使得语音芯片接受到信息的哦,可以使得你接受到的芯片的东西的语音传达到你的单片机上面的哦。这样一来你其实就是可以接收到你传达的芯片的。可以使得你获得的东西更加的多。
作者: cjtdz    时间: 2025-7-13 17:47
a399288395 发表于 2025-7-13 14:11
你的程序,EA=1 好像没有看到, 总中断没有打开,串口是不工作的;  一般调试,第一步就是借助串口工具,; ...

添加了EA=1;也不行
作者: cjtdz    时间: 2025-7-13 17:48
单片机重购 发表于 2025-7-13 15:03
你好哦可以回我嘛我是可以给你解答的哦。我可以给你解答的哦。首先你如果是进行串口收发程序的时候时,你是 ...

语音芯片用串口调试正常,关键是单片机发不出数据
作者: cjtdz    时间: 2025-7-13 19:10
掉进STC15W408AS没有定时器1这个大坑里了!欧克了
作者: zhuls    时间: 2025-7-13 20:18
串口初始化不行:

先设串口工作模式
再设定时器工作模式,
再设定时器分频
开串口中断
开总中断
开定时器计数

我也不知道你的步骤是不是少了什么?
作者: cjtdz    时间: 2025-7-13 20:41
本帖最后由 cjtdz 于 2025-7-14 09:48 编辑

掉进STC15W408AS没有定时器1坑里了,把波特率定时器1换成定时器2,OK了。
作者: jintaiyang    时间: 2025-7-13 20:48
串口中断没有开,总中断没有开。
  1. void Uart1_Isr(void) interrupt 4
  2. {
  3.         if (TI)                                //检测串口1发送中断
  4.         {
  5.                 TI = 0;                        //清除串口1发送中断请求位
  6.         }
  7.         if (RI)                                //检测串口1接收中断
  8.         {
  9.                 RI = 0;                        //清除串口1接收中断请求位
  10.         }
  11. }

  12. void Uart1_Init(void)        //9600bps@11.0592MHz
  13. {
  14.         SCON = 0x50;                //8位数据,可变波特率
  15.         AUXR &= 0xBF;                //定时器时钟12T模式
  16.         AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
  17.         TMOD &= 0x0F;                //设置定时器模式
  18.         TL1 = 0xE8;                        //设置定时初始值
  19.         TH1 = 0xFF;                        //设置定时初始值
  20.         ET1 = 0;                        //禁止定时器中断
  21.         TR1 = 1;                        //定时器1开始计时
  22.         ES = 1;                                //使能串口1中断
  23. }
复制代码

作者: cjtdz    时间: 2025-7-13 21:29
jintaiyang 发表于 2025-7-13 20:48
串口中断没有开,总中断没有开。

不需要的,只要把定时器1换成定时器2就可以了。因为STC15W408AS没有定时器1.
作者: vscos    时间: 2025-7-13 21:47
你好像没将ES置1,ES是串口中断,你只将EA置1不行的,EA是总中断,ES是串口中断,你得将EA同ES同时置1
作者: vscos    时间: 2025-7-13 21:49
a399288395 发表于 2025-7-13 14:11
你的程序,EA=1 好像没有看到, 总中断没有打开,串口是不工作的;  一般调试,第一步就是借助串口工具,; ...

他好像没打开串口中断,就是那个ES没有置1




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1