找回密码
 立即注册
查看: 49|回复: 8

奇怪现象 串口发送简单的HEX单个数据程序卡死了

[复制链接]
  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-09-03 05:42:28

34

主题

98

回帖

944

积分

高级会员

积分
944
发表于 5 天前 | 显示全部楼层 |阅读模式
   昨天用圈圈的开发板测试
  8个按键分别发送8个不同的HEX数据
只能按一次发送正确
第二次就发不出去了
今天很早就起床
用开天斧板 改了一下例程字符串收发程序
用P3.2 P3.3 P3.4 P3.5
分别发送4个不同的HEX数据
也是卡死在发送函数(猜的,等一下点亮一个LED试试)
并且发送函数按照昨天版主的建议修改
B_TX1_Busy = 1;    SBUF = SSF;    while(B_TX1_Busy);
             void Send(u8 puts) //发送一个字符串
              {
              B_TX1_Busy = 1;
              SBUF = puts;
              while(B_TX1_Busy);
              }
并且不用接收数据,把接收子程序也删除了
感觉挺奇怪
发送数据还有其他什么寄存器和位控制设置么

SEND.png USB LINK 1D.png

/*************  功能说明    ************************/
              #include     "stc8h.h"       //包含此头文件后,不需要再包含"reg51.h"头文件
              #define      MAIN_Fosc       11059200L   //定义主时钟(精确计算9600波特率)
              typedef      unsigned char   u8;
              typedef      unsigned int    u16;
              typedef      unsigned long   u32;
              #define      Baudrate1           9600L
              #define      UART1_BUF_LENGTH    64
              sbit         InttPut0=P3^2;
              sbit         InttPut1=P3^3;
              sbit         InttPut2=P3^4;
              sbit         InttPut3=P3^5;
              u8           TX1_Cnt;    //发送计数
              u8           RX1_Cnt;    //接收计数
              bit          B_TX1_Busy; //发送忙标志
              u8           kcounter,kstatus;     //按键计数标志 按键状态标志
/****************按键计数器状态寄存器归零*************/
              void RstKey()
              {
              kcounter=0;                        //按键计数器归零
              kstatus=0;                         //状态寄存器归零
              }
/*****************按键低电平检测函数*****************/
              void   LowVoltKey(void)            //按键计数器状态标志加一
              {
              kcounter++;                       
              kstatus++;     
              _nop_();                           //延时                  
              }
/*****************按键高电平检测函数*****************/
              void    HighVoltKey(void)          //按键计数器加一 状态标志归零
              {
              kcounter++;                        //按键计数器加一
              kstatus=0;                         //按键状态标志归零
              _nop_();                           //延时
              }
//========================================================================
// 函数: void PrintHex(u8 puts)
// 描述: 串口1发送字符串函数。
// 参数: puts:  Hex.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
              void Send(u8 puts) //发送一个字符串
              {
              B_TX1_Busy = 1;
              SBUF = puts;
              while(B_TX1_Busy);
              }
//========================================================================
// 函数: SetTimer2Baudraye(u16 dat)
// 描述: 设置Timer2做波特率发生器。
// 参数: dat: Timer2的重装值.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
              void SetTimer2Baudraye(u16 dat)  // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
              {
              AUXR &= ~(1<<4);    //Timer stop
              AUXR &= ~(1<<3);    //Timer2 set As Timer
              AUXR |=  (1<<2);    //Timer2 set as 1T mode
              T2H = dat / 256;
              T2L = dat % 256;
              IE2  &= ~(1<<2);    //禁止中断
              AUXR |=  (1<<4);    //Timer run enable
              }
//========================================================================
// 函数: void UART1_config(u8 brt)
// 描述: UART1初始化函数。
// 参数: brt: 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
              void UART1_config(u8 brt)    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
              {
    /*********** 波特率使用定时器2 *****************/
              if(brt == 2)
               {
               AUXR |= 0x01;       //S1 BRT Use Timer2;
               SetTimer2Baudraye(65536UL - (MAIN_Fosc / 4) / Baudrate1);
               }
/*********** 波特率使用定时器1 *****************/
               else
               {
               TR1 = 0;
               AUXR &= ~0x01;      //S1 BRT Use Timer1;
               AUXR |=  (1<<6);    //Timer1 set as 1T mode
               TMOD &= ~(1<<6);    //Timer1 set As Timer
               TMOD &= ~0x30;      //Timer1_16bitAutoReload;
               TH1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) / 256);
               TL1 = (u8)((65536UL - (MAIN_Fosc / 4) / Baudrate1) % 256);
               ET1 = 0;    //禁止中断
               INTCLKO &= ~0x02;   //不输出时钟
               TR1  = 1;
               }
    /*************************************************/

              SCON=(SCON&0x3f)|0x40;//UART1模式,0x00:同步移位输出,0x40:8位数据,可变波特率,0x80:9位数据,固定波特率,0xc0: 9位数据,可变波特率
//  PS  = 1;    //高优先级中断
              ES  = 1;    //允许中断
              REN = 1;    //允许接收
              P_SW1 &= 0x3f;
              P_SW1 |= 0x00;      //UART1 switch to, 0x00: P3.0 P3.1, 0x40: P3.6 P3.7, 0x80: P1.6 P1.7, 0xC0: P4.3 P4.4
//  PCON2 |=  (1<<4);   //内部短路RXD与TXD, 做中继, ENABLE,DISABLE

              B_TX1_Busy = 0;
              TX1_Cnt = 0;
              RX1_Cnt = 0;
              }
//========================================================================
// 函数: void main(void)
// 描述: 主函数。
// 参数: none.
// 返回: none.
// 版本: VER1.0
// 日期: 2014-11-28
// 备注:
//========================================================================
              void main(void)
              {
               P_SW2|=0x80;  //扩展寄存器(XFR)访问使能
               P0M1 = 0x30;   P0M0 = 0x30;   //设置P0.4、P0.5为漏极开路(实验箱加了上拉电阻到3.3V)
               P1M1 = 0x30;   P1M0 = 0x30;   //设置P1.4、P1.5为漏极开路(实验箱加了上拉电阻到3.3V)
               P2M1 = 0x3c;   P2M0 = 0x3c;   //设置P2.2~P2.5为漏极开路(实验箱加了上拉电阻到3.3V)
               P3M1 = 0x50;   P3M0 = 0x50;   //设置P3.4、P3.6为漏极开路(实验箱加了上拉电阻到3.3V)
               P4M1 = 0x3c;   P4M0 = 0x3c;   //设置P4.2~P4.5为漏极开路(实验箱加了上拉电阻到3.3V)
               P5M1 = 0x0c;   P5M0 = 0x0c;   //设置P5.2、P5.3为漏极开路(实验箱加了上拉电阻到3.3V)
               P6M1 = 0xff;   P6M0 = 0xff;   //设置为漏极开路(实验箱加了上拉电阻到3.3V)
               P7M1 = 0x00;   P7M0 = 0x00;   //设置为准双向口
               UART1_config(1);    // 选择波特率, 2: 使用Timer2做波特率, 其它值: 使用Timer1做波特率.
               EA = 1; //允许总中断
               while (1)
               {
                RstKey();
                for(;kcounter<5;)                 //按键循环5次
                {
                 if(!InttPut0)                      //按键低电平
                 {
                 LowVoltKey();
                 }
                 else if(~!InttPut0)               //按键高电平
                 {
                 HighVoltKey();
                 }
                }
                if(kstatus>=4)                    /*按键状态标志大于等于3为有效值*/
                {                                /*循环检测 */
                Send(0X01);
                P2=0X01;
                }
//1
                RstKey();
                for(;kcounter<5;)                 //按键循环5次
                {
                 if(!InttPut1)                      //按键低电平
                 {
                 LowVoltKey();
                 }
                 else if(~!InttPut1)               //按键高电平
                 {
                 HighVoltKey();
                 }
                }
                if(kstatus>=4)                    /*按键状态标志大于等于3为有效值*/
                {                                /*循环检测 */
                Send(0X02);
                P2=0X02;
                }
//2
                RstKey();
                for(;kcounter<5;)                 //按键循环5次
                {
                 if(!InttPut2)                      //按键低电平
                 {
                 LowVoltKey();
                 }
                 else if(~!InttPut2)               //按键高电平
                 {
                 HighVoltKey();
                 }
                }
                if(kstatus>=4)                    /*按键状态标志大于等于3为有效值*/
                {                                /*循环检测 */
                Send(0X04);
                P2=0X04;
                }
//3
                RstKey();
                for(;kcounter<5;)                 //按键循环5次
                {
                 if(!InttPut3)                      //按键低电平
                 {
                 LowVoltKey();
                 }
                 else if(~!InttPut3)               //按键高电平
                 {
                 HighVoltKey();
                 }
                }
                if(kstatus>=4)                    /*按键状态标志大于等于3为有效值*/
                {                                /*循环检测 */
                Send(0X08);
                P2=0X08;
               }
//4                     
    }
}







回复

使用道具 举报 送花

3

主题

2001

回帖

850

积分

等待验证会员

积分
850
发表于 5 天前 | 显示全部楼层
您提到的串口发送HEX数据时出现“卡死”现象,可能是由于以下原因导致:

1. 发送函数未正确处理发送状态:  
   您在代码中使用了 BTX1Busy = 1; SBUF = SSF; while(BTX1Busy); 的方式来发送数据。这种方式依赖于 BTX1Busy 标志位是否被正确清零。如果该标志位没有在发送完成后自动清零,程序就会陷入死循环。

2. 波特率配置不正确:  
   如果波特率设置错误,可能导致串口通信不稳定,尤其是在高速发送或频繁发送时,容易造成数据丢失或发送失败。

3. 中断未正确配置或未启用:  
   若使用的是中断方式发送数据,但未正确配置中断使能位(如 TI 或 ES),则可能无法触发发送完成中断,从而导致程序卡死。

4. SBUF寄存器未及时清空:  
   在发送过程中,若 SBUF 寄存器未及时清空,可能会导致下一次发送失败,特别是在连续发送多字节数据时更为明显。

5. 硬件连接问题:  
   串口通信需要正确的硬件连接(如 TXD、RXD 引脚接线),若接线错误或电平不匹配,也可能导致通信异常。

建议您检查以下几点:
确保 BTX1Busy 在发送完成后被正确清零;
检查波特率计算是否准确,确保与目标设备一致;
确认中断相关寄存器(如 SCON、IE)是否配置正确;
确保 SBUF 在每次发送前被正确赋值;
使用示波器或逻辑分析仪观察TXD引脚波形,确认数据是否正常发送。

如需进一步调试,可尝试添加调试信息(如LED指示灯)以判断程序执行流程。

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

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-09-03 05:42:28

34

主题

98

回帖

944

积分

高级会员

积分
944
发表于 5 天前 | 显示全部楼层
截图202508290731202481.jpg
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-09-03 05:42:28

34

主题

98

回帖

944

积分

高级会员

积分
944
发表于 5 天前 | 显示全部楼层
           
应该这样子
            void Send(u8 puts) //发送一个字符串
              {
            SBUF = puts;
              while(!TI);
             TI=0;
              }
回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:171
  • 最近打卡:2025-09-03 08:32:47

777

主题

1万

回帖

1万

积分

管理员

积分
18935
发表于 5 天前 | 显示全部楼层

从这个程序开始:
截图202508290903404057.jpg



#include "stc8h.h"                                //包含STC8H的头文件

#include "intrins.h"                        //使用_nop_()函数所必须要包含的头文件,
                                                                //否则延时函数中调用的_nop_()函数没有被头文件引用过来,
                                                                //会导致编译器找不到这个而函数而报错。


unsigned char int0_flag = 0;        //定义1个位变量,INT0事件位变量标志,记录INT0已产生中断
// 供主循环查询INT0是否已产生中断,在主循环中处理INT0的中断事件任务,不堵塞其他中断
unsigned char int1_flag = 0;        //定义1个位变量,INT1事件位变量标志,记录INT1已产生中断
// 供主循环查询INT1是否已产生中断,在主循环中处理INT1的中断事件任务,不堵塞其他中断
unsigned char int2_flag = 0;        //定义1个位变量,INT2事件位变量标志,记录INT2已产生中断
// 供主循环查询INT2是否已产生中断,在主循环中处理INT2的中断事件任务,不堵塞其他中断
unsigned char int3_flag = 0;        //定义1个位变量,INT3事件位变量标志,记录INT3已产生中断
// 供主循环查询INT3是否已产生中断,在主循环中处理INT3的中断事件任务,不堵塞其他中断

unsigned char t0_flag = 0;                //定义1个位变量,T0事件位变量标志,记录定时器0已产生中断
// 供主循环查询定时器0是否已产生中断,在主循环中处理定时器0的中断事件任务,不堵塞其他中断
unsigned char t1_flag = 0;                //定义1个位变量,T1事件位变量标志,记录定时器1已产生中断
// 供主循环查询定时器1是否已产生中断,在主循环中处理定时器1的中断事件任务,不堵塞其他中断
unsigned char t3_flag = 0;                //定义1个位变量,T3事件位变量标志,记录定时器3已产生中断
// 供主循环查询定时器3是否已产生中断,在主循环中处理定时器3的中断事件任务,不堵塞其他中断
unsigned char t4_flag = 0;                //定义1个位变量,T4事件位变量标志,记录定时器4已产生中断
// 供主循环查询定时器4是否已产生中断,在主循环中处理定时器4的中断事件任务,不堵塞其他中断

unsigned char uart1_txflag = 0;        //定义1个位变量,UART1事件位变量标志,记录UART1已产生发送中断
// 供主循环查询UART1是否已产生发送中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart1_rxflag = 0;        //定义1个位变量,UART1事件位变量标志,记录UART1已产生接收中断
// 供主循环查询UART1是否已产生接收中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart2_txflag = 0;        //定义1个位变量,UART2事件位变量标志,记录UART2已产生发送中断
// 供主循环查询UART2是否已产生发送中断,在主循环中处理UART2的中断事件任务,不堵塞其他中断
unsigned char uart2_rxflag = 0;        //定义1个位变量,UART2事件位变量标志,记录UART2已产生接收中断
// 供主循环查询UART2是否已产生接收中断,在主循环中处理UART2的中断事件任务,不堵塞其他中断
unsigned char uart3_txflag = 0;        //定义1个位变量,UART3事件位变量标志,记录UART3已产生发送中断
// 供主循环查询UART3是否已产生发送中断,在主循环中处理UART3的中断事件任务,不堵塞其他中断
unsigned char uart3_rxflag = 0;        //定义1个位变量,UART3事件位变量标志,记录UART3已产生接收中断
// 供主循环查询UART3是否已产生接收中断,在主循环中处理UART3的中断事件任务,不堵塞其他中断
unsigned char uart4_txflag = 0;        //定义1个位变量,UART4事件位变量标志,记录UART4已产生发送中断
// 供主循环查询UART4是否已产生发送中断,在主循环中处理UART1的中断事件任务,不堵塞其他中断
unsigned char uart4_rxflag = 0;        //定义1个位变量,UART4事件位变量标志,记录UART4已产生接收中断
// 供主循环查询UART4是否已产生接收中断,在主循环中处理UART4的中断事件任务,不堵塞其他中断

void Timer0_Init(void)                        //定时器0初始化,2秒@40.000MHz
{
        TM0PS = 0x65;                                //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0x7F;                                //定时器时钟12T模式
        TMOD &= 0xF0;                                //设置定时器模式
        TL0 = 0xB1;                                        //设置定时初始值
        TH0 = 0x00;                                        //设置定时初始值
        TF0 = 0;                                        //清除TF0标志
        TR0 = 1;                                        //定时器0开始计时
        ET0 = 1;                                        //使能定时器0中断
}

void Timer1_Init(void)                        //定时器1初始化,500毫秒@40.000MHz
{
        TM1PS = 0x19;                                //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        AUXR &= 0xBF;                                //定时器时钟12T模式
        TMOD &= 0x0F;                                //设置定时器模式
        TL1 = 0x99;                                        //设置定时初始值
        TH1 = 0x05;                                        //设置定时初始值
        TF1 = 0;                                        //清除TF1标志
        TR1 = 1;                                        //定时器1开始计时
        ET1 = 1;                                        //使能定时器1中断
}

void Timer3_Init(void)                    //100毫秒@40.000MHz
{
        TM3PS = 0x3D;                            //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        T4T3M |= 0x02;                            //定时器时钟1T模式
        T3L = 0xFC;                                    //设置定时初始值
        T3H = 0x03;                                    //设置定时初始值
        T4T3M |= 0x08;                            //定时器3开始计时
        IE2 |= 0x20;                            //使能定时器3中断
}

void Timer4_Init(void)                    //200毫秒@40.000MHz
{
        TM4PS = 0x7A;                            //设置定时器时钟预分频 ( 注意:并非所有系列都有此寄存器,详情请查看数据手册 )
        T4T3M |= 0x20;                            //定时器时钟1T模式
        T4L = 0xEF;                                    //设置定时初始值
        T4H = 0x01;                                    //设置定时初始值
        T4T3M |= 0x80;                            //定时器4开始计时
        IE2 |= 0x40;                            //使能定时器4中断
}

void Uart1_Init(void)                        //115200bps@40.000MHz
{
        SCON = 0x50;                                //8位数据,可变波特率
        AUXR |= 0x01;                                //串口1选择定时器2为波特率发生器
        AUXR |= 0x04;                                //定时器时钟1T模式
        T2L = 0xA9;                                        //设置定时初始值
        T2H = 0xFF;                                        //设置定时初始值
        AUXR |= 0x10;                                //定时器2开始计时
        ES = 1;                                                //使能串口1中断
}

void Uart2_Init(void)                        //115200bps@40.000MHz
{
        S2CON = 0x50;                                //8位数据,可变波特率
        AUXR |= 0x04;                                //定时器时钟1T模式
        T2L = 0xA9;                                        //设置定时初始值
        T2H = 0xFF;                                        //设置定时初始值
        AUXR |= 0x10;                                //定时器2开始计时
        IE2 |= 0x01;                                //使能串口2中断
}

void Uart3_Init(void)                        //115200bps@40.000MHz
{
        S3CON = 0x10;                                //8位数据,可变波特率
        S3CON &= 0xBF;                                //串口3选择定时器2为波特率发生器
        AUXR |= 0x04;                                //定时器时钟1T模式
        T2L = 0xA9;                                        //设置定时初始值
        T2H = 0xFF;                                        //设置定时初始值
        AUXR |= 0x10;                                //定时器2开始计时
        IE2 |= 0x08;                                //使能串口3中断
}

void Uart4_Init(void)                        //115200bps@40.000MHz
{
        S4CON = 0x10;                                //8位数据,可变波特率
        S4CON &= 0xBF;                                //串口4选择定时器2为波特率发生器
        AUXR |= 0x04;                                //定时器时钟1T模式
        T2L = 0xA9;                                        //设置定时初始值
        T2H = 0xFF;                                        //设置定时初始值
        AUXR |= 0x10;                                //定时器2开始计时
        IE2 |= 0x10;                                //使能串口4中断
}

void main (void)
{
        P_SW2 |= 0x80;                                //允许访问扩展的特殊寄存器,XFR

                                                                //32位8051需要使用下面3句进行初始化
//        EAXFR = 1;                                        //允许访问扩展的特殊寄存器,XFR
//        WTST = 0;                                        //设置取程序代码等待时间,赋值为0表示不等待,程序以最快速度运行
//        CKCON = 0;                                        //设置访问片内的xdata速度,赋值为0表示用最快速度访问,不增加额外的等待时间

        P0M0 = 0x00; P0M1 = 0x00;         //设置 P0 口为准双向口模式
        P1M0 = 0x00; P1M1 = 0x00;         //设置 P1 口为准双向口模式
        P2M0 = 0x00; P2M1 = 0x00;         //设置 P2 口为准双向口模式
        P3M0 = 0x00; P3M1 = 0x00;        //设置 P3 口为准双向口模式
        P3M0 = 0x00; P3M1 = 0x0c;         //P32、P33设置为高阻输入(需要同步开启上拉电阻)
        P4M0 = 0x00; P4M1 = 0x00;         //设置 P4 口为准双向口模式
        P5M0 = 0x00; P5M1 = 0x00;         //设置 P5 口为准双向口模式
        P6M0 = 0x00; P6M1 = 0x00;         //设置 P6 口为准双向口模式
        P7M0 = 0x00; P7M1 = 0x00;         //设置 P7 口为准双向口模式
       
        P3PU = 0x0c;                                 //P32、P33打开上拉电阻

        int0_flag = 0;                            //初始化用户标志位
        int1_flag = 0;                            //初始化用户标志位
        int2_flag = 0;                            //初始化用户标志位
        int3_flag = 0;                            //初始化用户标志位
   
        t0_flag = 0;                            //初始化用户标志位
        t1_flag = 0;                            //初始化用户标志位
        t3_flag = 0;                            //初始化用户标志位
        t4_flag = 0;                            //初始化用户标志位
   
        uart1_txflag = 0;                        //初始化用户标志位
        uart1_rxflag = 0;                        //初始化用户标志位
        uart2_txflag = 0;                        //初始化用户标志位
        uart2_rxflag = 0;                        //初始化用户标志位
        uart3_txflag = 0;                        //初始化用户标志位
        uart3_rxflag = 0;                        //初始化用户标志位
        uart4_txflag = 0;                        //初始化用户标志位
        uart4_rxflag = 0;                        //初始化用户标志位

        IT0 = 0;                                         //使能 INT0 上升沿和下降沿中断
        //        IT0 = 1;                                 //使能 INT0 下降沿中断
        EX0 = 1;                                         //使能 INT0 中断
        IE0 = 0;                                        //清INT0中断标志

        //        IT1 = 0;                                 //使能 INT1 上升沿和下降沿中断
        IT1 = 1;                                         //使能 INT1 下降沿中断
        EX1 = 1;                                         //使能 INT1 中断
        IE1 = 0;                                        //清INT1中断标志

        INTCLKO |= 0x10;                        //使能INT2中断

        INTCLKO |= 0x20;                        //使能INT3中断
       
        Timer0_Init();                                //调用定时器0初始化函数
        Timer1_Init();                                //调用定时器1初始化函数
        Timer3_Init();                                //调用定时器0初始化函数
        Timer4_Init();                                //调用定时器1初始化函数

        Uart1_Init();                                //调用UART1初始化函数
        Uart2_Init();                                //调用UART2初始化函数
        Uart3_Init();                                //调用UART3初始化函数
        Uart4_Init();                                //调用UART4初始化函数

        EA = 1;                                                //总中断允许位打开
        P40 = 0;                                         //打开LED灯供电
        while(1)                                         //主循环中查询需要处理的各种事件
        {
                /*  本演示程序中,主循环查询各中断有无需要继续处理的事件的次序,
                依次是 INTx/TIMERx/UARTx, 用户可以自己根据实际情况,
                调整查询各中断有无需要继续处理的事件的优先次序  */

                //查询外部中断0事件
                if(int0_flag)                        //主循环中查询,INT0是否已产生中断,是否有需要处理的INT 0事件
                {
                        int0_flag = 0;                //清0,INT0事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询外部中断1事件
                if(int1_flag)                        //主循环中查询,INT1是否已产生中断,是否有需要处理的INT1事件
                {
                        int1_flag = 0;                //清0,INT1事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询外部中断2事件
                if(int2_flag)                        //主循环中查询,INT2是否已产生中断,是否有需要处理的INT2事件
                {
                        int2_flag = 0;                //清0,INT2事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询外部中断3事件
                if(int3_flag)                        //主循环中查询,INT3是否已产生中断,是否有需要处理的INT3事件
                {
                        int3_flag = 0;                //清0,INT3事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器0中断事件
                if(t0_flag)                                //主循环中查询,定时器0是否已产生中断,是否有需要处理的定时器0事件
                {
                        t0_flag = 0;                //清0,T0事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器1中断事件
                if(t1_flag)                                //主循环中查询,定时器1是否已产生中断,是否有需要处理的定时器1事件
                {
                        t1_flag = 0;                //清0,T1事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器3中断事件
                if(t3_flag)                                //主循环中查询,定时器3是否已产生中断,是否有需要处理的定时器3事件
                {
                        t3_flag = 0;                //清0,T3事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询定时器4中断事件
                if(t4_flag)                                //主循环中查询,定时器4是否已产生中断,是否有需要处理的定时器4事件
                {
                        t4_flag = 0;                //清0,T4事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口1中断事件
                if(uart1_txflag)                //主循环中查询,UART1是否已产生发送中断,是否有需要处理的UART1发送事件
                {
                        uart1_txflag = 0;        //清0,UART1发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart1_rxflag)                //主循环中查询,UART1是否已产生接收中断,是否有需要处理的UART1接收事件
                {
                        uart1_rxflag = 0;        //清0,UART1接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口2中断事件
                if(uart2_txflag)                //主循环中查询,UART2是否已产生发送中断,是否有需要处理的UART2发送事件
                {
                        uart2_txflag = 0;        //清0,UART2发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart2_rxflag)                //主循环中查询,UART2是否已产生接收中断,是否有需要处理的UART2接收事件
                {
                        uart2_rxflag = 0;        //清0,UART2接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口3中断事件
                if(uart3_txflag)                //主循环中查询,UART3是否已产生发送中断,是否有需要处理的UART3发送事件
                {
                        uart3_txflag = 0;        //清0,UART3发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart3_rxflag)                //主循环中查询,UART3是否已产生接收中断,是否有需要处理的UART3接收事件
                {
                        uart3_rxflag = 0;        //清0,UART3接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                //查询串口4中断事件
                if(uart4_txflag)                //主循环中查询,UART4是否已产生发送中断,是否有需要处理的UART4发送事件
                {
                        uart4_txflag = 0;        //清0,UART4发送事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }

                if(uart4_rxflag)                //主循环中查询,UART4是否已产生接收中断,是否有需要处理的UART4接收事件
                {
                        uart4_rxflag = 0;        //清0,UART4接收事件位变量标志
                        _nop_();                        //用户在此添加需要处理的事件
                        _nop_();
                }
        }
}


void int0_isr(void) interrupt INT0_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int0_flag = 1;                                // int0_flag置1是通知主循环处理部分INT0中断事件不需要特急处理的任务
                                                                //置1,记录INT0已产生中断,供主循环查询判断有无需处理的INT0任务

        if(INT0)                                         //边沿中断,进入后再次判断电平从而判断是什么样的电平
        {
                _nop_();                                //判断为高电平,则当前为上升沿
                _nop_();                                //可以在这里插入断点进行观察现象
        }
        else
        {
                _nop_();                                //判断为低电平,则当前为下降沿
                _nop_();                                //可以在这里插入断点进行观察现象
        }
}
//INT0中断服务程序,INT0_VECTOR在stc8h头文件中已宏定义为0

void int1_isr(void) interrupt INT1_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int1_flag = 1;                                // int1_flag置1是通知主循环处理部分INT1中断事件不需要特急处理的任务
}
//INT1中断服务程序,INT1_VECTOR在stc8h头文件中已宏定义为2

void int2_isr(void) interrupt INT2_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int2_flag = 1;                                // int2_flag置1是通知主循环处理部分INT2中断事件不需要特急处理的任务
}
//INT2中断服务程序,INT2_VECTOR在stc8h头文件中已宏定义为10

void int3_isr(void) interrupt INT3_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        int3_flag = 1;                                // int3_flag置1是通知主循环处理部分INT3中断事件不需要特急处理的任务
}
//INT3中断服务程序,INT3_VECTOR在stc8h头文件中已宏定义为11

void Timer0_Isr(void) interrupt TMR0_VECTOR                //定时器0中断服务程序
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t0_flag = 1;                                // t0_flag置1是通知主循环处理部分T0中断事件不需要特急处理的任务
                                                                //置1,记录定时器0已产生中断,供主循环查询判断有无需处理的定时器0任务
}
//定时器0中断服务程序,TMR0_VECTOR在stc8h头文件中已宏定义为1

void Timer1_Isr(void) interrupt TMR1_VECTOR  
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t1_flag = 1;                                // t1_flag置1是通知主循环处理部分T1中断事件不需要特急处理的任务
                                                                //置1,记录定时器1已产生中断,供主循环查询判断有无需处理的定时器1任务
}
//定时器1中断服务程序,TMR1_VECTOR在stc8h头文件中已宏定义为3


void Timer3_Isr(void) interrupt TMR3_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t3_flag = 1;                                // t3_flag置1是通知主循环处理部分T3中断事件不需要特急处理的任务
                                                                //置1,记录定时器3已产生中断,供主循环查询判断有无需处理的定时器1任务
}
//定时器3中断服务程序,TMR3_VECTOR在stc8h头文件中已宏定义为19

void Timer4_Isr(void) interrupt TMR4_VECTOR
{
        _nop_();                                        //特急处理,中断服务程序中尽量少执行长的任务,防止堵塞其他中断
        //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
        //但时间不要太长,否则会影响其他中断事件的实时响应速度
        t4_flag = 1;                                // t1_flag置4是通知主循环处理部分T4中断事件不需要特急处理的任务
                                                                //置1,记录定时器4已产生中断,供主循环查询判断有无需处理的定时器1任务
}
//定时器4中断服务程序,TMR4_VECTOR在stc8h头文件中已宏定义为20

void Uart1_Isr(void) interrupt UART1_VECTOR
{
        if (TI)                                                //检测串口1发送中断
        {
                TI = 0;                                        //清除串口1发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart1_txflag = 1;                // uart1_txflag置1是通知主循环处理部分串口1发送中断事件不需要特急处理的任务
                                                                //置1,记录UART1已产生发送中断,供主循环查询判断有无需处理的UART1发送任务
        }
        if (RI)                                                //检测串口1接收中断
        {
                RI = 0;                                        //清除串口1接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart1_rxflag = 1;                // uart1_rxflag置1是通知主循环处理部分串口1接收中断事件不需要特急处理的任务
                                                                //置1,记录UART1已产生接收中断,供主循环查询判断有无需处理的UART1接收任务
        }
}
//UART1中断服务程序,UART1_VECTOR在stc8h头文件中已宏定义为4

void Uart2_Isr(void) interrupt UART2_VECTOR
{
        if (S2CON & 0x02)                        //检测串口2发送中断
        {
                S2CON &= ~0x02;                        //清除串口2发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart2_txflag = 1;                // uart2_txflag置1是通知主循环处理部分串口2发送中断事件不需要特急处理的任务
                                                                //置1,记录UART2已产生发送中断,供主循环查询判断有无需处理的UART2发送任务
        }
        if (S2CON & 0x01)                        //检测串口2接收中断
        {
                S2CON &= ~0x01;                        //清除串口2接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart2_rxflag = 1;                // uart2_rxflag置1是通知主循环处理部分串口2接收中断事件不需要特急处理的任务
                                                                //置1,记录UART2已产生接收中断,供主循环查询判断有无需处理的UART2接收任务
        }
}
//UART2中断服务程序,UART2_VECTOR在stc8h头文件中已宏定义为8

void Uart3_Isr(void) interrupt UART3_VECTOR
{
        if (S3CON & 0x02)                        //检测串口3发送中断
        {
                S3CON &= ~0x02;                        //清除串口3发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart3_txflag = 1;                // uart3_txflag置1是通知主循环处理部分串口3发送中断事件不需要特急处理的任务
                                                                //置1,记录UART3已产生发送中断,供主循环查询判断有无需处理的UART3发送任务
        }
        if (S3CON & 0x01)                        //检测串口3接收中断
        {
                S3CON &= ~0x01;                        //清除串口3接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart3_rxflag = 1;                // uart3_rxflag置1是通知主循环处理部分串口3接收中断事件不需要特急处理的任务
                                                                //置1,记录UART3已产生接收中断,供主循环查询判断有无需处理的UART3接收任务
        }
}
//UART3中断服务程序,UART3_VECTOR在stc8h头文件中已宏定义为17

void Uart4_Isr(void) interrupt UART4_VECTOR
{
        if (S4CON & 0x02)                        //检测串口4发送中断
        {
                S4CON &= ~0x02;                        //清除串口4发送中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart4_txflag = 1;                // uart4_txflag置1是通知主循环处理部分串口4发送中断事件不需要特急处理的任务
                                                                //置1,记录UART4已产生发送中断,供主循环查询判断有无需处理的UART4发送任务
        }
        if (S4CON & 0x01)                        //检测串口4接收中断
        {
                S4CON &= ~0x01;                        //清除串口4接收中断请求位
                _nop_();                                //特急处理
                //以上程序代表部分需特急处理的中断事件,可在中断服务程序中直接处理
                //但时间不要太长,否则会影响其他中断事件的实时响应速度
                uart4_rxflag = 1;                // uart4_rxflag置1是通知主循环处理部分串口4接收中断事件不需要特急处理的任务
                                                                //置1,记录UART4已产生接收中断,供主循环查询判断有无需处理的UART4接收任务
        }
}
//UART4中断服务程序,UART4_VECTOR在stc8h头文件中已宏定义为18


回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:505
  • 最近打卡:2025-09-02 16:59:35
已绑定手机

45

主题

2194

回帖

7662

积分

论坛元老

积分
7662
发表于 5 天前 | 显示全部楼层
附件例子供参考,按一次按键串口打印一次信息。

IO口做按键扫描.zip

9.37 KB, 下载次数: 1

回复

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-09-03 05:42:28

34

主题

98

回帖

944

积分

高级会员

积分
944
发表于 5 天前 | 显示全部楼层
           要改成这个样子才可以   



             void Send(u8 puts) //发送一个字符串
              {
              SBUF = puts;
              while(!TI);
              TI=0;
              }

范例程序 bit busy;是全局变量
不是寄存器位检测标志
void UartSend(char dat)
{
    while (busy);
    busy = 1;
    SBUF = dat;
}



回复

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:168
  • 最近打卡:2025-09-02 10:14:23

76

主题

6682

回帖

1万

积分

超级版主

积分
14003
发表于 5 天前 | 显示全部楼层
你没有串口中断服务函数,要有串口中断服务函数,并在函数中清除BTX1Busy=0;
你另外一个主贴有回复。
回复

使用道具 举报 送花

  • 打卡等级:偶尔看看II
  • 打卡总天数:28
  • 最近打卡:2025-09-03 05:42:28

34

主题

98

回帖

944

积分

高级会员

积分
944
发表于 5 天前 | 显示全部楼层
梁*** 发表于 2025-8-29 14:12
你没有串口中断服务函数,要有串口中断服务函数,并在函数中清除BTX1Busy=0;
你另外一个主贴有回复。 ...

好的 梁工 谢谢
回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-9-3 08:53 , Processed in 0.181375 second(s), 90 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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