wanli 发表于 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_Fosc24000000L          // 系统钟频率

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 = {0x01,0x0F,0x1E,0xB0,0x6E,0x02,0x1E,0xA9,0x01,0x01,0x02,0x23,0x00,0x59};
const u8 CMD_SUFFIX = {0xD2, 0x00};// 固定的倒数第二字节和校验和的偏移量

// 音量值和对应的校验和映射表
const u8 VOLUME_VALUES = {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 = {0xD0, 0xDF, 0xC8, 0xF7, 0xE3, 0x91, 0x9C, 0x8B, 0xB7, 0xA2, 0xAE,
                              0x5D, 0x48, 0x77, 0x63, 0x11, 0x1F, 0x08, 0x37, 0x23, 0xD1};
                       
charsm_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; u8 i;
       
    if(volume_index >= 21) return;

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

    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;
            }
      }
    }
}
为什么串口助手发送数据正常 我这个程序发送数据不行

神农鼎 发表于 2025-12-27 14:53:52



8H/8G/8C/8A系列4组串口同时通信的程序,Modbus 演示程序;可共享T2做波特率发生器 - 串行口,DMA支持的4组串口,RS232,RS485,Modbus, CRC16 国芯人工智能技术交流网站 - AI32位8051交流社区

DebugLab 发表于 2025-12-27 14:54:28

全局变量不要声明时赋值
新手必读:
https://www.stcaimcu.com/thread-16535-1-1.html

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

ercircle 发表于 2025-12-27 16:11:36

串口助手发送内容?

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


页: [1]
查看完整版本: 串口助手发送数据正常 程序发送不行