找回密码
 立即注册
查看: 169|回复: 3

串口助手发送数据正常 程序发送不行

[复制链接]
  • 打卡等级:以坛为家I
  • 打卡总天数:283
  • 最近打卡:2026-04-02 13:58:02
已绑定手机

20

主题

45

回帖

1260

积分

金牌会员

积分
1260
发表于 2025-12-27 12:05:43 | 显示全部楼层 |阅读模式
#include <stc8h.h>
#include <intrins.h>

typedef         unsigned char        u8;
typedef         unsigned int        u16;
typedef         unsigned long        u32;

// 系统时钟和波特率配置
#define MAIN_Fosc  24000000L          // 系统钟频率

sbit P3_2 = P3^2;
sbit P3_3 = P3^3;
sbit P3_4 = P3^4;
sbit P3_5 = P3^5;

// 音量控制命令模板 - 除了第13个字节(音量)和第16个字节(校验和)外的固定部分
const u8 CMD_TEMPLATE[14] = {0x01,0x0F,0x1E,0xB0,0x6E,0x02,0x1E,0xA9,0x01,0x01,0x02,0x23,0x00,0x59};
const u8 CMD_SUFFIX[2] = {0xD2, 0x00};  // 固定的倒数第二字节和校验和的偏移量

// 音量值和对应的校验和映射表
const u8 VOLUME_VALUES[21] = {0x01, 0x0E, 0x19, 0x26, 0x32, 0x40, 0x4D, 0x5A, 0x66, 0x73, 0x7F,
                              0x8C, 0x99, 0xA6, 0xB2, 0xC0, 0xCE, 0xD9, 0xE6, 0xF2, 0x00};
const u8 CHECKSUM_VALUES[21] = {0xD0, 0xDF, 0xC8, 0xF7, 0xE3, 0x91, 0x9C, 0x8B, 0xB7, 0xA2, 0xAE,
                                0x5D, 0x48, 0x77, 0x63, 0x11, 0x1F, 0x08, 0x37, 0x23, 0xD1};
                       
char  sm_1  []  = {0x01,0x0F,0x1E,0xB0,0x6E,0x02,0x1E,0xA9,0x01,0x01,0x02,0x23,0x01,0x59,0xD2,0xD0,};
/**
* 延时函数(毫秒级)
*/
void delay_ms(unsigned int ms)
{
    unsigned int i;
    do{
        i = MAIN_Fosc / 10000;
        while(--i);
    }while(--ms);
}

// 定时器2相关变量
u16 timer_count = 0;
u8 send_enable = 1;  // 发送使能标志
u8 receive_counter = 0;  // 接收计数器

/**
* 定时器2初始化函数 (用于100ms定时)
*/
void Timer2_Init(u16 time)
{
        AUXR |= 0x04;                        //定时器时钟1T模式
    T2H = (65536 - (MAIN_Fosc / time)) >> 8;  // 设置定时器初值,1ms中断
    T2L = (65536 - (MAIN_Fosc / time)) & 0xFF;
        AUXR |= 0x10;                        //定时器2开始计时
    IE2 = ET2;    //使能定时器中断  
    EA = 1;       // 开启总中断
}

/**
* 串口1初始化函数 (用于与电脑通信,P3.0/P3.1)
* 配置: 波特率9600, 无校验, 1位停止位
*/
void UART1_Init(u32 brt)
{   
    SCON = 0x50;                //8位数据,可变波特率
    AUXR |= 0x40;                //定时器时钟1T模式
    AUXR &= 0xFE;                //串口1选择定时器1为波特率发生器
    TMOD &= 0x0F;                //设置定时器模式
    TH1 = (u8)((65536UL - (MAIN_Fosc / 4) / brt) >> 8);
    TL1 = (u8)  65536UL - (MAIN_Fosc / 4) / brt;
    ET1 = 0;                        // 禁止Timer1中断
    TR1  = 1;                        // 运行Timer1

    SCON = (SCON & 0x3f) | (7<<6);        // 8位数据, 1位校验位, 1位起始位, 1位停止位
       
//        SCON = 0xD0;        // 9位数据, 可变波特率, 1位奇校验, 1位停止位 (模式3)
       
    ES  = 1;        //允许中断
    EA = 1;                     // 开总中断

    P_SW1 &= ~0xc0;                                                //UART1/USART1: RxD(P3.0), TxD(P3.1)
}



/**
* 串口1发送一个字节 (用于发送到电脑)
*/
void UART1_SendByte(unsigned char dat)
{
    SBUF = dat;                 // 写入发送数据
    while(!TI);                 // 等待发送完成(TI=1)
    TI = 0;                     // 清除TI标志位
}

/**
* 发送字符串
*/
void SendString(char *s, int num)
{
    while (num--)                  //检测字符串结束标志
    {
        UART1_SendByte(*s++);         //发送当前字符
    }
}

/**
* 发送12个0x55字节
*/
void SendBytes1()
{
    u8 i;
    for(i = 0; i < 11; i++)
    {
        UART1_SendByte(0x55);
    }
}
void SendBytes2()
{
    u8 i;
    for(i = 0; i < 11; i++)
    {
        UART1_SendByte(0x00);
    }
}
/**
* 发送指定音量等级的音频控制命令
*/
void SendVolumeCommand(u8 volume_index)
{
        u8 command[16]; u8 i;
       
    if(volume_index >= 21) return;

    // 构建命令:复制模板 + 音量值 + 固定后缀 + 校验和
    for(i = 0; i < 12; i++) {
        command[i] = CMD_TEMPLATE[i];
    }
    command[12] = VOLUME_VALUES[volume_index];      // 音量值
    command[13] = CMD_TEMPLATE[13];                 // 0x59
    command[14] = CMD_SUFFIX[0];                    // 0xD2
    command[15] = CHECKSUM_VALUES[volume_index];    // 校验和

    SendString((char*)command, 16);
}

/**
* 串口1中断服务函数 (接收来自设备的数据)
*/
void Uart1_Isr(void) interrupt 4
{
         u8 received_data;
    if(RI)
    {
        RI = 0;
                received_data = SBUF;  // 读取接收到的数据
               
                        // 检查是否接收到0x55
        if(received_data == 0x55)
        {
            receive_counter++;
            // 如果连续接收到10个0x55,停止发送
            if(receive_counter >= 10)
            {
                send_enable = 0;  // 停止发送
                receive_counter = 0;  // 重置计数器
            }
        }
        else
        {
            // 如果不是0x55,重置计数器
            receive_counter = 0;
        }

        // 将接收到的数据回传到电脑
        UART1_SendByte(received_data);
               
    }

    if(TI)
    {
        TI = 0;
    }
}

/**
* 定时器2中断服务函数
*/
void Timer2_ISR() interrupt 12
{
    static u16 ms_count = 0;

    timer_count++;
    ms_count++;

    if(ms_count >= 500 && send_enable)  // 100ms且发送使能
    {
        ms_count = 0;
        SendBytes1();  // 发送12个0x55字节
    }

}

void main(void)
{
    P_SW2 |= 0x80;  //扩展寄存器(XFR)访问使能

    P0M1 = 0x00;   P0M0 = 0x00;   //设置为准双向口
    P1M1 = 0x00;   P1M0 = 0x00;
    P2M1 = 0x00;   P2M0 = 0x00;
    P3M1 = 0x00;   P3M0 = 0x00;
    P4M1 = 0x00;   P4M0 = 0x00;
    P5M1 = 0x00;   P5M0 = 0x00;
    P6M1 = 0x00;   P6M0 = 0x00;
    P7M1 = 0x00;   P7M0 = 0x00;

    UART1_Init(9600);               // 初始化串口1 (与电脑通信)
    Timer2_Init(1000);                  // 初始化定时器2用于100ms定时
       
    while(1)
    {
        if(P3_2==0)
        {
            delay_ms(10);
            if(P3_2==0)
            {
                while(!P3_2);
//                SendVolumeCommand(0);  // 发送音量等级0(对应0x01)
                                SendString(sm_1,sizeof(sm_1));   
                                delay_ms(500);
                                SendBytes2();
                P20 = !P20;
            }
        }
        if(P3_3==0)
        {
            delay_ms(10);
            if(P3_3==0)
            {
                while(!P3_3);
                SendVolumeCommand(10); // 发送音量等级10(对应0x7F)
                                delay_ms(500);
                                SendBytes2();
                P21 = !P21;
            }
        }
    }
}
为什么串口助手发送数据正常 我这个程序发送数据不行

截图202512271204462952.jpg
回复

使用道具 举报 送花

  • 打卡等级:以坛为家I
  • 打卡总天数:368
  • 最近打卡:2026-04-02 08:50:05

844

主题

1万

回帖

2万

积分

管理员

积分
22799
发表于 2025-12-27 14:53:52 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家III
  • 打卡总天数:725
  • 最近打卡:2026-03-30 12:09:34
已绑定手机

97

主题

7246

回帖

1万

积分

超级版主

积分
13798
发表于 2025-12-27 14:54:28 | 显示全部楼层
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:493
  • 最近打卡:2026-04-02 08:56:15
已绑定手机

104

主题

4229

回帖

9395

积分

荣誉版主

无情的代码机器

积分
9395
发表于 2025-12-27 16:11:36 | 显示全部楼层
串口助手发送内容?

程序发送内容?
检查波特率、校验位、停止位等设置。
勾选工具的hex模式,逐字节对比是否有不可见字符。
如果逐字节一致,接收端行为不一致就见鬼了~~

截图202512271610459091.jpg
三天不学习,赶不上刘少奇~
回复

使用道具 举报 送花

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2026-4-3 02:15 , Processed in 0.117824 second(s), 63 queries .

Powered by Discuz! X3.5

© 2001-2026 Discuz! Team.

快速回复 返回顶部 返回列表